diff options
Diffstat (limited to 'arch/armv7/thumb2_disasm/spec.cpp')
| -rw-r--r-- | arch/armv7/thumb2_disasm/spec.cpp | 54387 |
1 files changed, 54387 insertions, 0 deletions
diff --git a/arch/armv7/thumb2_disasm/spec.cpp b/arch/armv7/thumb2_disasm/spec.cpp new file mode 100644 index 00000000..89ee1807 --- /dev/null +++ b/arch/armv7/thumb2_disasm/spec.cpp @@ -0,0 +1,54387 @@ + +#include <stdint.h> + +#include <map> +#include <string> +#include <vector> + +#include "spec.h" /* FIELD_imm8, FIELD_MAX, etc. */ +#include "disassembler.h" /* decomp_request, decomp_result */ + +#if defined(__clang__) +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wunused-variable" +#pragma clang diagnostic ignored "-Wunused-parameter" +#pragma clang diagnostic ignored "-Wunused-function" +#elif defined(__GNUC__) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wunused-variable" +#pragma GCC diagnostic ignored "-Wunused-parameter" +#pragma GCC diagnostic ignored "-Wunused-function" +#endif + +/* forward declarations */ +int adc_immediate(struct decomp_request *req, struct decomp_result *res); +int adc_register(struct decomp_request *req, struct decomp_result *res); +int add_immediate(struct decomp_request *req, struct decomp_result *res); +int add_register(struct decomp_request *req, struct decomp_result *res); +int add_sp_plus_immediate(struct decomp_request *req, struct decomp_result *res); +int add_sp_plus_register(struct decomp_request *req, struct decomp_result *res); +int adr(struct decomp_request *req, struct decomp_result *res); +int advanced_simd_data_proc(struct decomp_request *req, struct decomp_result *res); +int advanced_simd_elem_struct_load_store(struct decomp_request *req, struct decomp_result *res); +int advsimd_one_reg_mod_imm(struct decomp_request *req, struct decomp_result *res); +int advsimd_three_reg_diff_len(struct decomp_request *req, struct decomp_result *res); +int advsimd_three_reg_same_len(struct decomp_request *req, struct decomp_result *res); +int advsimd_two_reg_misc(struct decomp_request *req, struct decomp_result *res); +int advsimd_two_reg_scalar(struct decomp_request *req, struct decomp_result *res); +int advsimd_two_reg_shift(struct decomp_request *req, struct decomp_result *res); +int and_immediate(struct decomp_request *req, struct decomp_result *res); +int and_register(struct decomp_request *req, struct decomp_result *res); +int asr_immediate(struct decomp_request *req, struct decomp_result *res); +int asr_register(struct decomp_request *req, struct decomp_result *res); +int b(struct decomp_request *req, struct decomp_result *res); +int bfc(struct decomp_request *req, struct decomp_result *res); +int bfi(struct decomp_request *req, struct decomp_result *res); +int bic_immediate(struct decomp_request *req, struct decomp_result *res); +int bic_register(struct decomp_request *req, struct decomp_result *res); +int bkpt(struct decomp_request *req, struct decomp_result *res); +int bl_blx_immediate(struct decomp_request *req, struct decomp_result *res); +int blx(struct decomp_request *req, struct decomp_result *res); +int branches_misc_control(struct decomp_request *req, struct decomp_result *res); +int bx(struct decomp_request *req, struct decomp_result *res); +int bxj(struct decomp_request *req, struct decomp_result *res); +int cbnz_cbz(struct decomp_request *req, struct decomp_result *res); +int cdp_cdp2(struct decomp_request *req, struct decomp_result *res); +int change_proc_state_and_hints(struct decomp_request *req, struct decomp_result *res); +int clrex(struct decomp_request *req, struct decomp_result *res); +int clz(struct decomp_request *req, struct decomp_result *res); +int cmn_immediate(struct decomp_request *req, struct decomp_result *res); +int cmn_register(struct decomp_request *req, struct decomp_result *res); +int cmp_immediate(struct decomp_request *req, struct decomp_result *res); +int cmp_register(struct decomp_request *req, struct decomp_result *res); +int cond_branch_superv_call(struct decomp_request *req, struct decomp_result *res); +int coprocessor_instructions(struct decomp_request *req, struct decomp_result *res); +int cps(struct decomp_request *req, struct decomp_result *res); +int data_proc(struct decomp_request *req, struct decomp_result *res); +int data_processing_modified_immediate(struct decomp_request *req, struct decomp_result *res); +int data_processing_plain_binary_immediate(struct decomp_request *req, struct decomp_result *res); +int data_processing_register(struct decomp_request *req, struct decomp_result *res); +int data_processing_shifted_register(struct decomp_request *req, struct decomp_result *res); +int dbg(struct decomp_request *req, struct decomp_result *res); +int dmb(struct decomp_request *req, struct decomp_result *res); +int dsb(struct decomp_request *req, struct decomp_result *res); +int enterx_leavex(struct decomp_request *req, struct decomp_result *res); +int eor_immediate(struct decomp_request *req, struct decomp_result *res); +int eor_register(struct decomp_request *req, struct decomp_result *res); +int extension_reg_load_store(struct decomp_request *req, struct decomp_result *res); +int hint_undoc(struct decomp_request *req, struct decomp_result *res); +int if_then_hints(struct decomp_request *req, struct decomp_result *res); +int isb(struct decomp_request *req, struct decomp_result *res); +int it(struct decomp_request *req, struct decomp_result *res); +int it_related_encodings(struct decomp_request *req, struct decomp_result *res); +int lda(struct decomp_request *req, struct decomp_result *res); +int ldab(struct decomp_request *req, struct decomp_result *res); +int ldaex(struct decomp_request *req, struct decomp_result *res); +int ldaexb(struct decomp_request *req, struct decomp_result *res); +int ldaexh(struct decomp_request *req, struct decomp_result *res); +int ldah(struct decomp_request *req, struct decomp_result *res); +int ldc_immediate(struct decomp_request *req, struct decomp_result *res); +int ldc_literal(struct decomp_request *req, struct decomp_result *res); +int ldm(struct decomp_request *req, struct decomp_result *res); +int ldmdb(struct decomp_request *req, struct decomp_result *res); +int ldr_immediate(struct decomp_request *req, struct decomp_result *res); +int ldr_literal(struct decomp_request *req, struct decomp_result *res); +int ldr_register(struct decomp_request *req, struct decomp_result *res); +int ldrb_immediate(struct decomp_request *req, struct decomp_result *res); +int ldrb_literal(struct decomp_request *req, struct decomp_result *res); +int ldrb_register(struct decomp_request *req, struct decomp_result *res); +int ldrbt(struct decomp_request *req, struct decomp_result *res); +int ldrd_immediate(struct decomp_request *req, struct decomp_result *res); +int ldrd_literal(struct decomp_request *req, struct decomp_result *res); +int ldrex(struct decomp_request *req, struct decomp_result *res); +int ldrexb(struct decomp_request *req, struct decomp_result *res); +int ldrexd(struct decomp_request *req, struct decomp_result *res); +int ldrexh(struct decomp_request *req, struct decomp_result *res); +int ldrh_immediate(struct decomp_request *req, struct decomp_result *res); +int ldrh_literal(struct decomp_request *req, struct decomp_result *res); +int ldrh_register(struct decomp_request *req, struct decomp_result *res); +int ldrht(struct decomp_request *req, struct decomp_result *res); +int ldrsb_immediate(struct decomp_request *req, struct decomp_result *res); +int ldrsb_literal(struct decomp_request *req, struct decomp_result *res); +int ldrsb_register(struct decomp_request *req, struct decomp_result *res); +int ldrsbt(struct decomp_request *req, struct decomp_result *res); +int ldrsh_immediate(struct decomp_request *req, struct decomp_result *res); +int ldrsh_literal(struct decomp_request *req, struct decomp_result *res); +int ldrsh_register(struct decomp_request *req, struct decomp_result *res); +int ldrsht(struct decomp_request *req, struct decomp_result *res); +int ldrt(struct decomp_request *req, struct decomp_result *res); +int load_byte_mem_hint(struct decomp_request *req, struct decomp_result *res); +int load_halfword_mem_hint(struct decomp_request *req, struct decomp_result *res); +int load_lit_pool(struct decomp_request *req, struct decomp_result *res); +int load_store_dual_exclusive_table_branch(struct decomp_request *req, struct decomp_result *res); +int load_store_multiple(struct decomp_request *req, struct decomp_result *res); +int load_store_single_data(struct decomp_request *req, struct decomp_result *res); +int load_word(struct decomp_request *req, struct decomp_result *res); +int long_mul_accumulate_divide(struct decomp_request *req, struct decomp_result *res); +int lsl_immediate(struct decomp_request *req, struct decomp_result *res); +int lsl_register(struct decomp_request *req, struct decomp_result *res); +int lsr_immediate(struct decomp_request *req, struct decomp_result *res); +int lsr_register(struct decomp_request *req, struct decomp_result *res); +int mcr_mcr2(struct decomp_request *req, struct decomp_result *res); +int mcrr_mcrr2(struct decomp_request *req, struct decomp_result *res); +int misc(struct decomp_request *req, struct decomp_result *res); +int misc_control(struct decomp_request *req, struct decomp_result *res); +int misc_operations(struct decomp_request *req, struct decomp_result *res); +int mla(struct decomp_request *req, struct decomp_result *res); +int mls(struct decomp_request *req, struct decomp_result *res); +int mov_immediate(struct decomp_request *req, struct decomp_result *res); +int mov_register(struct decomp_request *req, struct decomp_result *res); +int movt(struct decomp_request *req, struct decomp_result *res); +int mrc_mrc2(struct decomp_request *req, struct decomp_result *res); +int mrrc_mrrc2(struct decomp_request *req, struct decomp_result *res); +int mrs(struct decomp_request *req, struct decomp_result *res); +int msr_reg_app(struct decomp_request *req, struct decomp_result *res); +int msr_reg_sys(struct decomp_request *req, struct decomp_result *res); +int mul(struct decomp_request *req, struct decomp_result *res); +int mul_accumulate_absolute_difference(struct decomp_request *req, struct decomp_result *res); +int mul_register(struct decomp_request *req, struct decomp_result *res); +int mvn_immediate(struct decomp_request *req, struct decomp_result *res); +int mvn_register(struct decomp_request *req, struct decomp_result *res); +int nop(struct decomp_request *req, struct decomp_result *res); +int orn_immediate(struct decomp_request *req, struct decomp_result *res); +int orn_register(struct decomp_request *req, struct decomp_result *res); +int orr_immediate(struct decomp_request *req, struct decomp_result *res); +int orr_register(struct decomp_request *req, struct decomp_result *res); +int parallel_add_sub_signed(struct decomp_request *req, struct decomp_result *res); +int parallel_add_sub_unsigned(struct decomp_request *req, struct decomp_result *res); +int pkh(struct decomp_request *req, struct decomp_result *res); +int pld(struct decomp_request *req, struct decomp_result *res); +int pld_literal(struct decomp_request *req, struct decomp_result *res); +int pld_pldw_immediate(struct decomp_request *req, struct decomp_result *res); +int pld_pldw_register(struct decomp_request *req, struct decomp_result *res); +int pli_immediate_literal(struct decomp_request *req, struct decomp_result *res); +int pli_register(struct decomp_request *req, struct decomp_result *res); +int pop(struct decomp_request *req, struct decomp_result *res); +int push(struct decomp_request *req, struct decomp_result *res); +int qadd(struct decomp_request *req, struct decomp_result *res); +int qadd16(struct decomp_request *req, struct decomp_result *res); +int qadd8(struct decomp_request *req, struct decomp_result *res); +int qasx(struct decomp_request *req, struct decomp_result *res); +int qdadd(struct decomp_request *req, struct decomp_result *res); +int qdsub(struct decomp_request *req, struct decomp_result *res); +int qsax(struct decomp_request *req, struct decomp_result *res); +int qsub(struct decomp_request *req, struct decomp_result *res); +int qsub16(struct decomp_request *req, struct decomp_result *res); +int qsub8(struct decomp_request *req, struct decomp_result *res); +int rbit(struct decomp_request *req, struct decomp_result *res); +int rev(struct decomp_request *req, struct decomp_result *res); +int rev16(struct decomp_request *req, struct decomp_result *res); +int revsh(struct decomp_request *req, struct decomp_result *res); +int rfe(struct decomp_request *req, struct decomp_result *res); +int ror_immediate(struct decomp_request *req, struct decomp_result *res); +int ror_register(struct decomp_request *req, struct decomp_result *res); +int rrx(struct decomp_request *req, struct decomp_result *res); +int rsb_immediate(struct decomp_request *req, struct decomp_result *res); +int rsb_register(struct decomp_request *req, struct decomp_result *res); +int sadd16(struct decomp_request *req, struct decomp_result *res); +int sadd8(struct decomp_request *req, struct decomp_result *res); +int sasx(struct decomp_request *req, struct decomp_result *res); +int sbc_immediate(struct decomp_request *req, struct decomp_result *res); +int sbc_register(struct decomp_request *req, struct decomp_result *res); +int sbfx(struct decomp_request *req, struct decomp_result *res); +int sdiv(struct decomp_request *req, struct decomp_result *res); +int sel(struct decomp_request *req, struct decomp_result *res); +int setend(struct decomp_request *req, struct decomp_result *res); +int sev(struct decomp_request *req, struct decomp_result *res); +int shadd16(struct decomp_request *req, struct decomp_result *res); +int shadd8(struct decomp_request *req, struct decomp_result *res); +int shasx(struct decomp_request *req, struct decomp_result *res); +int shift_immediate_add_sub_mov_cmp(struct decomp_request *req, struct decomp_result *res); +int shsax(struct decomp_request *req, struct decomp_result *res); +int shsub16(struct decomp_request *req, struct decomp_result *res); +int shsub8(struct decomp_request *req, struct decomp_result *res); +int smc(struct decomp_request *req, struct decomp_result *res); +int smlabb_smlabt_smlatb_smlatt(struct decomp_request *req, struct decomp_result *res); +int smlad(struct decomp_request *req, struct decomp_result *res); +int smlal(struct decomp_request *req, struct decomp_result *res); +int smlalbb_smlalbt_smlaltb_smlaltt(struct decomp_request *req, struct decomp_result *res); +int smlald(struct decomp_request *req, struct decomp_result *res); +int smlawb_smlawt(struct decomp_request *req, struct decomp_result *res); +int smlsd(struct decomp_request *req, struct decomp_result *res); +int smlsld(struct decomp_request *req, struct decomp_result *res); +int smmla(struct decomp_request *req, struct decomp_result *res); +int smmls(struct decomp_request *req, struct decomp_result *res); +int smmul(struct decomp_request *req, struct decomp_result *res); +int smuad(struct decomp_request *req, struct decomp_result *res); +int smulbb_smulbt_smultb_smultt(struct decomp_request *req, struct decomp_result *res); +int smull(struct decomp_request *req, struct decomp_result *res); +int smulwb_smulwt(struct decomp_request *req, struct decomp_result *res); +int smusd(struct decomp_request *req, struct decomp_result *res); +int spcl_data_branch_exch(struct decomp_request *req, struct decomp_result *res); +int srs(struct decomp_request *req, struct decomp_result *res); +int ssat(struct decomp_request *req, struct decomp_result *res); +int ssat16(struct decomp_request *req, struct decomp_result *res); +int ssax(struct decomp_request *req, struct decomp_result *res); +int ssub16(struct decomp_request *req, struct decomp_result *res); +int ssub8(struct decomp_request *req, struct decomp_result *res); +int stc_stc2(struct decomp_request *req, struct decomp_result *res); +int stl(struct decomp_request *req, struct decomp_result *res); +int stlb(struct decomp_request *req, struct decomp_result *res); +int stlex(struct decomp_request *req, struct decomp_result *res); +int stlexb(struct decomp_request *req, struct decomp_result *res); +int stlexh(struct decomp_request *req, struct decomp_result *res); +int stlh(struct decomp_request *req, struct decomp_result *res); +int stm(struct decomp_request *req, struct decomp_result *res); +int stmdb(struct decomp_request *req, struct decomp_result *res); +int store_single_data_item(struct decomp_request *req, struct decomp_result *res); +int str_immediate(struct decomp_request *req, struct decomp_result *res); +int str_register(struct decomp_request *req, struct decomp_result *res); +int strb_immediate(struct decomp_request *req, struct decomp_result *res); +int strb_register(struct decomp_request *req, struct decomp_result *res); +int strbt(struct decomp_request *req, struct decomp_result *res); +int strd_immediate(struct decomp_request *req, struct decomp_result *res); +int strex(struct decomp_request *req, struct decomp_result *res); +int strexb(struct decomp_request *req, struct decomp_result *res); +int strexd(struct decomp_request *req, struct decomp_result *res); +int strexh(struct decomp_request *req, struct decomp_result *res); +int strh_immediate(struct decomp_request *req, struct decomp_result *res); +int strh_register(struct decomp_request *req, struct decomp_result *res); +int strht(struct decomp_request *req, struct decomp_result *res); +int strt(struct decomp_request *req, struct decomp_result *res); +int sub_immediate(struct decomp_request *req, struct decomp_result *res); +int sub_register(struct decomp_request *req, struct decomp_result *res); +int sub_sp_minus_immediate(struct decomp_request *req, struct decomp_result *res); +int sub_sp_minus_register(struct decomp_request *req, struct decomp_result *res); +int subs_pc_lr_related(struct decomp_request *req, struct decomp_result *res); +int svc(struct decomp_request *req, struct decomp_result *res); +int sxtab(struct decomp_request *req, struct decomp_result *res); +int sxtab16(struct decomp_request *req, struct decomp_result *res); +int sxtah(struct decomp_request *req, struct decomp_result *res); +int sxtb(struct decomp_request *req, struct decomp_result *res); +int sxtb16(struct decomp_request *req, struct decomp_result *res); +int sxth(struct decomp_request *req, struct decomp_result *res); +int tbb_tbh(struct decomp_request *req, struct decomp_result *res); +int teq_immediate(struct decomp_request *req, struct decomp_result *res); +int teq_register(struct decomp_request *req, struct decomp_result *res); +int thumb16(struct decomp_request *req, struct decomp_result *res); +int thumb32(struct decomp_request *req, struct decomp_result *res); +int thumb_root(struct decomp_request *req, struct decomp_result *res); +int tst_immediate(struct decomp_request *req, struct decomp_result *res); +int tst_register(struct decomp_request *req, struct decomp_result *res); +int uadd16(struct decomp_request *req, struct decomp_result *res); +int uadd8(struct decomp_request *req, struct decomp_result *res); +int uasx(struct decomp_request *req, struct decomp_result *res); +int ubfx(struct decomp_request *req, struct decomp_result *res); +int udf(struct decomp_request *req, struct decomp_result *res); +int udiv(struct decomp_request *req, struct decomp_result *res); +int uhadd16(struct decomp_request *req, struct decomp_result *res); +int uhadd8(struct decomp_request *req, struct decomp_result *res); +int uhasx(struct decomp_request *req, struct decomp_result *res); +int uhsax(struct decomp_request *req, struct decomp_result *res); +int uhsub16(struct decomp_request *req, struct decomp_result *res); +int uhsub8(struct decomp_request *req, struct decomp_result *res); +int umaal(struct decomp_request *req, struct decomp_result *res); +int umlal(struct decomp_request *req, struct decomp_result *res); +int umull(struct decomp_request *req, struct decomp_result *res); +int undefined(struct decomp_request *req, struct decomp_result *res); +int unpredictable(struct decomp_request *req, struct decomp_result *res); +int uqadd16(struct decomp_request *req, struct decomp_result *res); +int uqadd8(struct decomp_request *req, struct decomp_result *res); +int uqasx(struct decomp_request *req, struct decomp_result *res); +int uqsax(struct decomp_request *req, struct decomp_result *res); +int uqsub16(struct decomp_request *req, struct decomp_result *res); +int uqsub8(struct decomp_request *req, struct decomp_result *res); +int usad8(struct decomp_request *req, struct decomp_result *res); +int usada8(struct decomp_request *req, struct decomp_result *res); +int usat(struct decomp_request *req, struct decomp_result *res); +int usat16(struct decomp_request *req, struct decomp_result *res); +int usax(struct decomp_request *req, struct decomp_result *res); +int usub16(struct decomp_request *req, struct decomp_result *res); +int usub8(struct decomp_request *req, struct decomp_result *res); +int uxtab(struct decomp_request *req, struct decomp_result *res); +int uxtab16(struct decomp_request *req, struct decomp_result *res); +int uxtah(struct decomp_request *req, struct decomp_result *res); +int uxtb(struct decomp_request *req, struct decomp_result *res); +int uxtb16(struct decomp_request *req, struct decomp_result *res); +int uxth(struct decomp_request *req, struct decomp_result *res); +int vaba(struct decomp_request *req, struct decomp_result *res); +int vabd_float(struct decomp_request *req, struct decomp_result *res); +int vabd_integer(struct decomp_request *req, struct decomp_result *res); +int vabs(struct decomp_request *req, struct decomp_result *res); +int vacge(struct decomp_request *req, struct decomp_result *res); +int vadd_float(struct decomp_request *req, struct decomp_result *res); +int vadd_integer(struct decomp_request *req, struct decomp_result *res); +int vaddhn(struct decomp_request *req, struct decomp_result *res); +int vaddlw(struct decomp_request *req, struct decomp_result *res); +int vand(struct decomp_request *req, struct decomp_result *res); +int vbic_immediate(struct decomp_request *req, struct decomp_result *res); +int vbic_register(struct decomp_request *req, struct decomp_result *res); +int vbif(struct decomp_request *req, struct decomp_result *res); +int vbit(struct decomp_request *req, struct decomp_result *res); +int vbsl(struct decomp_request *req, struct decomp_result *res); +int vceq_immediate(struct decomp_request *req, struct decomp_result *res); +int vceq_register(struct decomp_request *req, struct decomp_result *res); +int vcge_immediate(struct decomp_request *req, struct decomp_result *res); +int vcge_register(struct decomp_request *req, struct decomp_result *res); +int vcgt_immediate(struct decomp_request *req, struct decomp_result *res); +int vcgt_register(struct decomp_request *req, struct decomp_result *res); +int vcle_immediate(struct decomp_request *req, struct decomp_result *res); +int vcls(struct decomp_request *req, struct decomp_result *res); +int vclt_immediate(struct decomp_request *req, struct decomp_result *res); +int vclz(struct decomp_request *req, struct decomp_result *res); +int vcmp(struct decomp_request *req, struct decomp_result *res); +int vcnt(struct decomp_request *req, struct decomp_result *res); +int vcvt_double_single(struct decomp_request *req, struct decomp_result *res); +int vcvt_float_fixed(struct decomp_request *req, struct decomp_result *res); +int vcvt_float_int(struct decomp_request *req, struct decomp_result *res); +int vcvt_half_single(struct decomp_request *req, struct decomp_result *res); +int vcvta(struct decomp_request *req, struct decomp_result *res); +int vcvtb(struct decomp_request *req, struct decomp_result *res); +int vcvtm(struct decomp_request *req, struct decomp_result *res); +int vcvtn(struct decomp_request *req, struct decomp_result *res); +int vcvtp(struct decomp_request *req, struct decomp_result *res); +int vdiv(struct decomp_request *req, struct decomp_result *res); +int vdup_register(struct decomp_request *req, struct decomp_result *res); +int vdup_scalar(struct decomp_request *req, struct decomp_result *res); +int veor(struct decomp_request *req, struct decomp_result *res); +int vext(struct decomp_request *req, struct decomp_result *res); +int vfma(struct decomp_request *req, struct decomp_result *res); +int vfnma(struct decomp_request *req, struct decomp_result *res); +int vfp_data_proc(struct decomp_request *req, struct decomp_result *res); +int vfp_data_proc_ext(struct decomp_request *req, struct decomp_result *res); +int vhadd(struct decomp_request *req, struct decomp_result *res); +int vhsub(struct decomp_request *req, struct decomp_result *res); +int vld1_mult_1elem(struct decomp_request *req, struct decomp_result *res); +int vld1_single_1elem_1lane(struct decomp_request *req, struct decomp_result *res); +int vld1_single_1elem_nlanes(struct decomp_request *req, struct decomp_result *res); +int vld2_mult_2elem(struct decomp_request *req, struct decomp_result *res); +int vld2_single_2elem_1lane(struct decomp_request *req, struct decomp_result *res); +int vld2_single_2elem_nlanes(struct decomp_request *req, struct decomp_result *res); +int vld3_mult_3elem(struct decomp_request *req, struct decomp_result *res); +int vld3_single_3elem_1lane(struct decomp_request *req, struct decomp_result *res); +int vld3_single_3elem_nlanes(struct decomp_request *req, struct decomp_result *res); +int vld4_mult_4elem(struct decomp_request *req, struct decomp_result *res); +int vld4_single_4elem_1lane(struct decomp_request *req, struct decomp_result *res); +int vld4_single_4elem_nlanes(struct decomp_request *req, struct decomp_result *res); +int vldm(struct decomp_request *req, struct decomp_result *res); +int vldr(struct decomp_request *req, struct decomp_result *res); +int vmax_vmin_float(struct decomp_request *req, struct decomp_result *res); +int vmax_vmin_integer(struct decomp_request *req, struct decomp_result *res); +int vmaxnm(struct decomp_request *req, struct decomp_result *res); +int vmla_float(struct decomp_request *req, struct decomp_result *res); +int vmla_integer(struct decomp_request *req, struct decomp_result *res); +int vmla_scalar(struct decomp_request *req, struct decomp_result *res); +int vmov_core_double(struct decomp_request *req, struct decomp_result *res); +int vmov_core_scalar(struct decomp_request *req, struct decomp_result *res); +int vmov_core_single(struct decomp_request *req, struct decomp_result *res); +int vmov_core_two_single(struct decomp_request *req, struct decomp_result *res); +int vmov_immediate(struct decomp_request *req, struct decomp_result *res); +int vmov_register(struct decomp_request *req, struct decomp_result *res); +int vmov_scalar_core(struct decomp_request *req, struct decomp_result *res); +int vmovl(struct decomp_request *req, struct decomp_result *res); +int vmovn(struct decomp_request *req, struct decomp_result *res); +int vmrs(struct decomp_request *req, struct decomp_result *res); +int vmsr(struct decomp_request *req, struct decomp_result *res); +int vmul_float(struct decomp_request *req, struct decomp_result *res); +int vmul_integer(struct decomp_request *req, struct decomp_result *res); +int vmul_scalar(struct decomp_request *req, struct decomp_result *res); +int vmvn(struct decomp_request *req, struct decomp_result *res); +int vmvn_immediate(struct decomp_request *req, struct decomp_result *res); +int vneg(struct decomp_request *req, struct decomp_result *res); +int vnmla(struct decomp_request *req, struct decomp_result *res); +int vorn_register(struct decomp_request *req, struct decomp_result *res); +int vorr_immediate(struct decomp_request *req, struct decomp_result *res); +int vorr_register(struct decomp_request *req, struct decomp_result *res); +int vpadal(struct decomp_request *req, struct decomp_result *res); +int vpadd_float(struct decomp_request *req, struct decomp_result *res); +int vpadd_integer(struct decomp_request *req, struct decomp_result *res); +int vpaddl(struct decomp_request *req, struct decomp_result *res); +int vpmax_float(struct decomp_request *req, struct decomp_result *res); +int vpmax_integer(struct decomp_request *req, struct decomp_result *res); +int vpop(struct decomp_request *req, struct decomp_result *res); +int vpush(struct decomp_request *req, struct decomp_result *res); +int vqabs(struct decomp_request *req, struct decomp_result *res); +int vqadd(struct decomp_request *req, struct decomp_result *res); +int vqdmlal(struct decomp_request *req, struct decomp_result *res); +int vqdmulh(struct decomp_request *req, struct decomp_result *res); +int vqdmull(struct decomp_request *req, struct decomp_result *res); +int vqmovn(struct decomp_request *req, struct decomp_result *res); +int vqneg(struct decomp_request *req, struct decomp_result *res); +int vqrdmulh(struct decomp_request *req, struct decomp_result *res); +int vqrshl(struct decomp_request *req, struct decomp_result *res); +int vqrshrn(struct decomp_request *req, struct decomp_result *res); +int vqshl_immediate(struct decomp_request *req, struct decomp_result *res); +int vqshl_register(struct decomp_request *req, struct decomp_result *res); +int vqshrn(struct decomp_request *req, struct decomp_result *res); +int vqsub(struct decomp_request *req, struct decomp_result *res); +int vraddhn(struct decomp_request *req, struct decomp_result *res); +int vrecpe(struct decomp_request *req, struct decomp_result *res); +int vrecps(struct decomp_request *req, struct decomp_result *res); +int vrev16(struct decomp_request *req, struct decomp_result *res); +int vrev32(struct decomp_request *req, struct decomp_result *res); +int vrev64(struct decomp_request *req, struct decomp_result *res); +int vrhadd(struct decomp_request *req, struct decomp_result *res); +int vrinta(struct decomp_request *req, struct decomp_result *res); +int vrintx(struct decomp_request *req, struct decomp_result *res); +int vrintz(struct decomp_request *req, struct decomp_result *res); +int vrshl(struct decomp_request *req, struct decomp_result *res); +int vrshr(struct decomp_request *req, struct decomp_result *res); +int vrshrn(struct decomp_request *req, struct decomp_result *res); +int vrsqrte(struct decomp_request *req, struct decomp_result *res); +int vrsqrts(struct decomp_request *req, struct decomp_result *res); +int vrsra(struct decomp_request *req, struct decomp_result *res); +int vrsubhn(struct decomp_request *req, struct decomp_result *res); +int vsel(struct decomp_request *req, struct decomp_result *res); +int vshl_immediate(struct decomp_request *req, struct decomp_result *res); +int vshl_register(struct decomp_request *req, struct decomp_result *res); +int vshll(struct decomp_request *req, struct decomp_result *res); +int vshr(struct decomp_request *req, struct decomp_result *res); +int vshrn(struct decomp_request *req, struct decomp_result *res); +int vsli(struct decomp_request *req, struct decomp_result *res); +int vsqrt(struct decomp_request *req, struct decomp_result *res); +int vsra(struct decomp_request *req, struct decomp_result *res); +int vsri(struct decomp_request *req, struct decomp_result *res); +int vst1_mult_1elem(struct decomp_request *req, struct decomp_result *res); +int vst1_single_1elem(struct decomp_request *req, struct decomp_result *res); +int vst2_mult_2elem(struct decomp_request *req, struct decomp_result *res); +int vst2_single_2elem(struct decomp_request *req, struct decomp_result *res); +int vst3_mult_3elem(struct decomp_request *req, struct decomp_result *res); +int vst3_single_3elem(struct decomp_request *req, struct decomp_result *res); +int vst4_mult_4elem(struct decomp_request *req, struct decomp_result *res); +int vst4_single_4elem(struct decomp_request *req, struct decomp_result *res); +int vstm(struct decomp_request *req, struct decomp_result *res); +int vstr(struct decomp_request *req, struct decomp_result *res); +int vsub_float(struct decomp_request *req, struct decomp_result *res); +int vsub_integer(struct decomp_request *req, struct decomp_result *res); +int vsubhn(struct decomp_request *req, struct decomp_result *res); +int vsubl(struct decomp_request *req, struct decomp_result *res); +int vswp(struct decomp_request *req, struct decomp_result *res); +int vtbl(struct decomp_request *req, struct decomp_result *res); +int vtrn(struct decomp_request *req, struct decomp_result *res); +int vtst(struct decomp_request *req, struct decomp_result *res); +int vuzp(struct decomp_request *req, struct decomp_result *res); +int vzip(struct decomp_request *req, struct decomp_result *res); +int wfe(struct decomp_request *req, struct decomp_result *res); +int wfi(struct decomp_request *req, struct decomp_result *res); +int xfer_64_core_ext_regs(struct decomp_request *req, struct decomp_result *res); +int xfer_8_16_32_core_extension(struct decomp_request *req, struct decomp_result *res); +int yield(struct decomp_request *req, struct decomp_result *res); + +// see A8.4.3 +int DecodeImmShift_shift_t(uint8_t enc_bits, uint8_t imm5) +{ + if(enc_bits == 0) + return SRType_LSL; + else if(enc_bits == 1) + return SRType_LSR; + else if(enc_bits == 2) + return SRType_ASR; + else if(enc_bits == 3) { + if(imm5 == 0) + return SRType_RRX; + else + return SRType_ROR; + } + return SRType_ERROR; +} + +int DecodeImmShift_shift_n(uint8_t enc_bits, uint8_t imm5) +{ + if(enc_bits == 0) + return imm5; + else if(enc_bits == 1) + return imm5 ? imm5 : 32; + else if(enc_bits == 2) + return imm5 ? imm5 : 32; + else if(enc_bits == 3) { + if(imm5 == 0) + return 1; + else + return imm5; + } + return -1; +} + +int BadReg(uint8_t reg) +{ + return (reg==13) || (reg==15); +} + +uint64_t Replicate(uint32_t rep, uint32_t before, char before_char, uint32_t after, char after_char, uint8_t times) { + uint64_t imm64 = 0; + uint32_t i, time; + for (time = 0; time < times; time++) { + if (time > 0) { + for (i = 0; i < before+8; i++) { + imm64 <<= 1; + imm64 |= before_char; + } + } + imm64 |= rep; + for (i = 0; i < after; i++) { + imm64 <<= 1; + imm64 |= after_char; + } + } + return imm64; +} + +uint32_t VFPExpandImm(uint32_t imm, uint32_t N, uint32_t lowbits) { + + uint32_t E = 0; + if (N == 32) { + E = 8; + } + else { + E = 11; + } + uint32_t F = (N - E) - 1; + uint32_t sign = (imm >> 7) & 1; + uint32_t exp = ((imm >> 6) & 1) ^ 1; + for (uint32_t i = 0; i < E-3; i++) { + exp <<= 1; + exp |= (imm >> 6) & 1; + } + exp <<= 2; + exp |= (imm >> 4) & 3; + uint32_t frac = (imm & 15); + frac <<= F-4; + uint32_t out = (sign << 31) | (exp << 23) | (frac); + + return out; +} + +uint32_t AdvSIMDExpandImm(uint32_t op, uint32_t cmode, uint32_t imm8, uint32_t lowbits) { + + uint32_t testimm8; + uint64_t imm64 = 0; + uint32_t imm32 = 0; + uint32_t i = 0; + imm8 = imm8 & 0xff; + switch(cmode >> 1) { + case 0: + testimm8 = 0; + imm64 = Replicate(imm8, 24, 0, 0, 0, 2); + if (lowbits) return imm64 & 0xffffffff; + return 0; + break; + case 1: + testimm8 = 1; + imm64 = Replicate(imm8, 16, 0, 8, 0, 2); + if (lowbits) return imm64 & 0xffffffff; + return 0; + break; + case 2: + testimm8 = 1; + imm64 = Replicate(imm8, 8, 0, 16, 0, 2); + if (lowbits) return imm64 & 0xffffffff; + return 0; + break; + case 3: + testimm8 = 1; + imm64 = Replicate(imm8, 0, 0, 24, 0, 2); + if (lowbits) return imm64 & 0xffffffff; + return 0; + break; + case 4: + testimm8 = 0; + imm64 = Replicate(imm8, 8, 0, 0, 0, 4); + if (lowbits) return imm64 & 0xff; + return 0; + break; + case 5: + testimm8 = 1; + imm64 = Replicate(imm8, 0, 0, 8, 0, 4); + if (lowbits) return imm64 & 0xffff; + return 0; + break; + case 6: + testimm8 = 1; + if ((cmode & 1) == 0) { + imm64 = Replicate(imm8, 16, 0, 8, 1, 2); + } + else { + imm64 = Replicate(imm8, 8, 0, 16, 1, 2); + } + if (lowbits) return imm64 & 0xffffffff; + return 0; + break; + case 7: + testimm8 = 0; + if ((cmode & 1) == 0 && (op & 1) == 0) { + imm64 = Replicate(imm8, 0, 0, 0, 0, 8); + if (lowbits) return imm8; + return 0; + } + + else if ((cmode & 1) == 0 && (op & 1) == 1) { + int i, j; + for (i = 0; i < 8; i++) { + for (j = 0; j < 8; j++) { + imm64 |= ((imm8 >> (7-i)) & 1); + if (i != 7 || j != 7) imm64 <<= 1; + } + } + } + else if ((cmode & 1) == 1 && (op & 1) == 0) { + imm32 = ((imm8 >> 7) & 1); + imm32 <<= 1; + imm32 |= ((imm8 >> 6) & 1) ? 0 : 1; + for (i = 0; i < 5; i++) { + imm32 <<= 1; + imm32 |= (imm8 >> 6) & 1; + } + imm32 <<= 6; + imm32 |= (imm8 & 63); + imm32 <<= 19; + imm64 = imm32; + } + else if ((cmode & 1) == 1 && (op & 1) == 1) { + //return undefined() + } + break; + } + + if (testimm8 && imm8 == 0) { + //return undefined() + } + + if (lowbits) return imm64 & 0xffffffff; + return imm64 >> 32; +} + +uint32_t ROR_C(uint32_t input, int shamt) +{ + shamt %= 32; + uint32_t left = input << (32-shamt); + uint32_t right = input >> shamt; + return left | right; +} + +uint32_t ROR_C_cout(uint32_t input, int shamt) +{ + return ROR_C(input, shamt) >> 31; +} + +int ThumbExpandImm_C_imm32(uint32_t imm12, uint32_t carry_in) +{ + (void)carry_in; + + if(0 == (imm12 & 0xC00)) { + uint32_t idx = (imm12 & 0x300)>>8; + uint32_t tmp = imm12 & 0xFF; + if(idx==0) { + return tmp; + } + else if(idx==1) { + return (tmp << 16) | tmp; + } + else if(idx==2) { + return (tmp << 24) | (tmp << 8); + } + else { + return (tmp << 24) | (tmp << 16) | (tmp << 8) | tmp; + } + } + else { + uint32_t value = 0x80 | (imm12 & 0x7F); + uint32_t rotamt = (imm12 & 0xF80) >> 7; + return ROR_C(value, rotamt); + } +} + +int ThumbExpandImm_C_cout(uint32_t imm12, uint32_t carry_in) +{ + if(0 == (imm12 & 0xC00)) { + return carry_in; + } + else { + uint32_t unrot_value = 0x80 | (imm12 & 0x7F); + return ROR_C_cout(unrot_value, (imm12 & 0xF80) >> 7); + } +} + +// TODO: replace with optimized implementation +int BitCount(int x) +{ + int answer = 0; + while(x) { + if(x&1) answer += 1; + x>>=1; + } + return answer; +} + +uint32_t SignExtend(uint32_t val, int inWidth) +{ + int doExtend = val & (1 << (inWidth-1)); + + if(doExtend) { + uint32_t mask = (uint32_t)-1 ^ ((1<<inWidth)-1); + val = mask | val; + } + + return val; +} + +void printBits(uint32_t val, int bit_width, int str_width) +{ + int left_pad = (str_width > bit_width) ? str_width - bit_width : 0; + for(int i=0; i<left_pad; ++i) printf(" "); + + if(bit_width > 32) bit_width = 32; + for(int i=bit_width-1; i>=0; --i) + printf("%c", (val & (1<<i)) ? '1' : '0'); +} + +#if defined(__APPLE__) || defined(__MACH__) +int __attribute__((optnone)) success(void) { + /* debugger script can break here to see path taken */ + return 0; +} +#else +int success(void) { + return 0; +} +#endif + +// gen_crc: 7E7F6888 +int adc_immediate(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + /* Encoding T1 */ + /* pattern="11110,i.1,0,1010,S.1,Rn.4,0,imm3.3,Rd.4,imm8.8" width=32 stringency=13 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFBE08000)==0xF1400000)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ARMv6T2) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_i] = (instr & 0x4000000)>>26; + res->fields_mask[FIELD_i >> 6] |= 1LL << (FIELD_i & 63); + char i_width = 1; + res->fields[FIELD_S] = (instr & 0x100000)>>20; + res->fields_mask[FIELD_S >> 6] |= 1LL << (FIELD_S & 63); + char S_width = 1; + res->fields[FIELD_Rn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Rn >> 6] |= 1LL << (FIELD_Rn & 63); + char Rn_width = 4; + res->fields[FIELD_imm3] = (instr & 0x7000)>>12; + res->fields_mask[FIELD_imm3 >> 6] |= 1LL << (FIELD_imm3 & 63); + char imm3_width = 3; + res->fields[FIELD_Rd] = (instr & 0xF00)>>8; + res->fields_mask[FIELD_Rd >> 6] |= 1LL << (FIELD_Rd & 63); + char Rd_width = 4; + res->fields[FIELD_imm8] = instr & 0xFF; + res->fields_mask[FIELD_imm8 >> 6] |= 1LL << (FIELD_imm8 & 63); + char imm8_width = 8; + + static const instruction_format instr_formats[] = + { + { /* ADC{S}<c> <Rd>,<Rn>,#<imm32> */ + "adc", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_OPTIONAL_STATUS, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rd,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rn,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_IMM,FIELD_imm32,FIELD_UNINIT,"#","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_ADC; + + /* pcode: d = UInt(Rd) */ + res->fields[FIELD_d] = (res->fields[FIELD_Rd]); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: n = UInt(Rn) */ + res->fields[FIELD_n] = (res->fields[FIELD_Rn]); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: setflags = (S == '1') */ + res->fields[FIELD_setflags] = ((res->fields[FIELD_S]) == (0x1)); + res->fields_mask[FIELD_setflags >> 6] |= 1LL << (FIELD_setflags & 63); + /* pcode: imm32 = ThumbExpandImm(i:imm3:imm8) */ + res->fields[FIELD_imm32] = ThumbExpandImm_C_imm32((res->fields[FIELD_i]<<(8+3))|(res->fields[FIELD_imm3]<<8)|(res->fields[FIELD_imm8]), req->carry_in); + /* TODO: handle ThumbExpandImm_C's possible setting of UNPREDICTABLE */ while(0); + res->fields_mask[FIELD_imm32 >> 6] |= 1LL << (FIELD_imm32 & 63); + /* pcode: if BadReg(d) || BadReg(n) then UNPREDICTABLE */ + if((BadReg(res->fields[FIELD_d])) || (BadReg(res->fields[FIELD_n]))) { + res->flags |= FLAG_UNPREDICTABLE; + } + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: B99071D4 +int adc_register(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + /* Encoding T1 */ + /* pattern="010000,0101,Rm.3,Rdn.3" width=16 stringency=10 */ + { + uint16_t instr = req->instr_word16; + if(((instr & 0xFFC0)==0x4140)) { + res->instrSize = 16; + if(!(req->arch & ARCH_ARMv4T) && !(req->arch & ARCH_ARMv5T) && !(req->arch & ARCH_ARMv6) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_Rm] = (instr & 0x38)>>3; + res->fields_mask[FIELD_Rm >> 6] |= 1LL << (FIELD_Rm & 63); + char Rm_width = 3; + res->fields[FIELD_Rdn] = instr & 0x7; + res->fields_mask[FIELD_Rdn >> 6] |= 1LL << (FIELD_Rdn & 63); + char Rdn_width = 3; + + static const instruction_format instr_formats[] = + { + { /* ADCS <Rdn>,<Rm> */ + "adcs", /* .operation (const char *) */ + 0, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rdn,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rm,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + { /* ADC<c> <Rdn>,<Rm> */ + "adc", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rdn,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rm,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 2; + res->mnem = armv7::ARMV7_ADCS; + + /* pcode: d = UInt(Rdn) */ + res->fields[FIELD_d] = (res->fields[FIELD_Rdn]); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: n = UInt(Rdn) */ + res->fields[FIELD_n] = (res->fields[FIELD_Rdn]); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: m = UInt(Rm) */ + res->fields[FIELD_m] = (res->fields[FIELD_Rm]); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + /* pcode: setflags = !InITBlock() */ + res->fields[FIELD_setflags] = !(req->inIfThen == IFTHEN_YES); + res->fields_mask[FIELD_setflags >> 6] |= 1LL << (FIELD_setflags & 63); + /* pcode: (shift_t, shift_n) = (SRType_LSL, 0) */ + res->fields[FIELD_shift_t] = 0; + res->fields_mask[FIELD_shift_t >> 6] |= 1LL << (FIELD_shift_t & 63); + res->fields[FIELD_shift_n] = 0; + res->fields_mask[FIELD_shift_n >> 6] |= 1LL << (FIELD_shift_n & 63); + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* Encoding T2 */ + /* pattern="11101,01,1010,S.1,Rn.4,(0),imm3.3,Rd.4,imm2.2,type.2,Rm.4" width=32 stringency=13 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFFE00000)==0xEB400000)) { + res->instrSize = 32; + if(!((instr & 0x8000)==0x0)) { + res->flags |= FLAG_UNPREDICTABLE; + } + if(!(req->arch & ARCH_ARMv6T2) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_S] = (instr & 0x100000)>>20; + res->fields_mask[FIELD_S >> 6] |= 1LL << (FIELD_S & 63); + char S_width = 1; + res->fields[FIELD_Rn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Rn >> 6] |= 1LL << (FIELD_Rn & 63); + char Rn_width = 4; + res->fields[FIELD_imm3] = (instr & 0x7000)>>12; + res->fields_mask[FIELD_imm3 >> 6] |= 1LL << (FIELD_imm3 & 63); + char imm3_width = 3; + res->fields[FIELD_Rd] = (instr & 0xF00)>>8; + res->fields_mask[FIELD_Rd >> 6] |= 1LL << (FIELD_Rd & 63); + char Rd_width = 4; + res->fields[FIELD_imm2] = (instr & 0xC0)>>6; + res->fields_mask[FIELD_imm2 >> 6] |= 1LL << (FIELD_imm2 & 63); + char imm2_width = 2; + res->fields[FIELD_type] = (instr & 0x30)>>4; + res->fields_mask[FIELD_type >> 6] |= 1LL << (FIELD_type & 63); + char type_width = 2; + res->fields[FIELD_Rm] = instr & 0xF; + res->fields_mask[FIELD_Rm >> 6] |= 1LL << (FIELD_Rm & 63); + char Rm_width = 4; + + static const instruction_format instr_formats[] = + { + { /* ADC{S}<c> <Rd>,<Rn>,<Rm>{,<shift>} */ + "adc", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_OPTIONAL_STATUS, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rd,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rn,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rm,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_SHIFT,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 4 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_ADC; + + /* pcode: d = UInt(Rd) */ + res->fields[FIELD_d] = (res->fields[FIELD_Rd]); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: n = UInt(Rn) */ + res->fields[FIELD_n] = (res->fields[FIELD_Rn]); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: m = UInt(Rm) */ + res->fields[FIELD_m] = (res->fields[FIELD_Rm]); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + /* pcode: setflags = (S == '1') */ + res->fields[FIELD_setflags] = ((res->fields[FIELD_S]) == (0x1)); + res->fields_mask[FIELD_setflags >> 6] |= 1LL << (FIELD_setflags & 63); + /* pcode: (shift_t, shift_n) = DecodeImmShift(type, imm3:imm2) */ + res->fields[FIELD_shift_t] = DecodeImmShift_shift_t(res->fields[FIELD_type], (res->fields[FIELD_imm3]<<2)|(res->fields[FIELD_imm2])); + res->fields_mask[FIELD_shift_t >> 6] |= 1LL << (FIELD_shift_t & 63); + res->fields[FIELD_shift_n] = DecodeImmShift_shift_n(res->fields[FIELD_type], (res->fields[FIELD_imm3]<<2)|(res->fields[FIELD_imm2])); + res->fields_mask[FIELD_shift_n >> 6] |= 1LL << (FIELD_shift_n & 63); + /* pcode: if BadReg(d) || BadReg(n) || BadReg(m) then UNPREDICTABLE */ + if(((BadReg(res->fields[FIELD_d])) || (BadReg(res->fields[FIELD_n]))) || (BadReg(res->fields[FIELD_m]))) { + res->flags |= FLAG_UNPREDICTABLE; + } + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: 6B57825C +int add_immediate(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + /* Encoding T1 */ + /* pattern="000,11,1,0,imm3.3,Rn.3,Rd.3" width=16 stringency=7 */ + { + uint16_t instr = req->instr_word16; + if(((instr & 0xFE00)==0x1C00)) { + res->instrSize = 16; + if(!(req->arch & ARCH_ARMv4T) && !(req->arch & ARCH_ARMv5T) && !(req->arch & ARCH_ARMv6) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_imm3] = (instr & 0x1C0)>>6; + res->fields_mask[FIELD_imm3 >> 6] |= 1LL << (FIELD_imm3 & 63); + char imm3_width = 3; + res->fields[FIELD_Rn] = (instr & 0x38)>>3; + res->fields_mask[FIELD_Rn >> 6] |= 1LL << (FIELD_Rn & 63); + char Rn_width = 3; + res->fields[FIELD_Rd] = instr & 0x7; + res->fields_mask[FIELD_Rd >> 6] |= 1LL << (FIELD_Rd & 63); + char Rd_width = 3; + + static const instruction_format instr_formats[] = + { + { /* ADDS <Rd>,<Rn>,#<imm3> */ + "adds", /* .operation (const char *) */ + 0, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rd,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rn,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_IMM,FIELD_imm3,FIELD_UNINIT,"#","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + { /* ADD<c> <Rd>,<Rn>,#<imm3> */ + "add", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rd,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rn,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_IMM,FIELD_imm3,FIELD_UNINIT,"#","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 2; + res->mnem = armv7::ARMV7_ADDS; + + /* pcode: d = UInt(Rd) */ + res->fields[FIELD_d] = (res->fields[FIELD_Rd]); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: n = UInt(Rn) */ + res->fields[FIELD_n] = (res->fields[FIELD_Rn]); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: setflags = !InITBlock() */ + res->fields[FIELD_setflags] = !(req->inIfThen == IFTHEN_YES); + res->fields_mask[FIELD_setflags >> 6] |= 1LL << (FIELD_setflags & 63); + /* pcode: imm32 = ZeroExtend(imm3, 32) */ + res->fields[FIELD_imm32] = res->fields[FIELD_imm3]; + res->fields_mask[FIELD_imm32 >> 6] |= 1LL << (FIELD_imm32 & 63); + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* Encoding T2 */ + /* pattern="001,10,Rdn.3,imm8.8" width=16 stringency=5 */ + { + uint16_t instr = req->instr_word16; + if(((instr & 0xF800)==0x3000)) { + res->instrSize = 16; + if(!(req->arch & ARCH_ARMv4T) && !(req->arch & ARCH_ARMv5T) && !(req->arch & ARCH_ARMv6) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_Rdn] = (instr & 0x700)>>8; + res->fields_mask[FIELD_Rdn >> 6] |= 1LL << (FIELD_Rdn & 63); + char Rdn_width = 3; + res->fields[FIELD_imm8] = instr & 0xFF; + res->fields_mask[FIELD_imm8 >> 6] |= 1LL << (FIELD_imm8 & 63); + char imm8_width = 8; + + static const instruction_format instr_formats[] = + { + { /* ADDS <Rdn>,#<imm8> */ + "adds", /* .operation (const char *) */ + 0, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rdn,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_IMM,FIELD_imm8,FIELD_UNINIT,"#","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + { /* ADD<c> <Rdn>,#<imm8> */ + "add", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rdn,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_IMM,FIELD_imm8,FIELD_UNINIT,"#","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 2; + res->mnem = armv7::ARMV7_ADDS; + + /* pcode: d = UInt(Rdn) */ + res->fields[FIELD_d] = (res->fields[FIELD_Rdn]); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: n = UInt(Rdn) */ + res->fields[FIELD_n] = (res->fields[FIELD_Rdn]); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: setflags = !InITBlock() */ + res->fields[FIELD_setflags] = !(req->inIfThen == IFTHEN_YES); + res->fields_mask[FIELD_setflags >> 6] |= 1LL << (FIELD_setflags & 63); + /* pcode: imm32 = ZeroExtend(imm8, 32) */ + res->fields[FIELD_imm32] = res->fields[FIELD_imm8]; + res->fields_mask[FIELD_imm32 >> 6] |= 1LL << (FIELD_imm32 & 63); + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* Encoding T3 */ + /* pattern="11110,i.1,0,1000,S.1,Rn.4,0,imm3.3,Rd.4,imm8.8" width=32 stringency=13 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFBE08000)==0xF1000000)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ARMv6T2) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_i] = (instr & 0x4000000)>>26; + res->fields_mask[FIELD_i >> 6] |= 1LL << (FIELD_i & 63); + char i_width = 1; + res->fields[FIELD_S] = (instr & 0x100000)>>20; + res->fields_mask[FIELD_S >> 6] |= 1LL << (FIELD_S & 63); + char S_width = 1; + res->fields[FIELD_Rn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Rn >> 6] |= 1LL << (FIELD_Rn & 63); + char Rn_width = 4; + res->fields[FIELD_imm3] = (instr & 0x7000)>>12; + res->fields_mask[FIELD_imm3 >> 6] |= 1LL << (FIELD_imm3 & 63); + char imm3_width = 3; + res->fields[FIELD_Rd] = (instr & 0xF00)>>8; + res->fields_mask[FIELD_Rd >> 6] |= 1LL << (FIELD_Rd & 63); + char Rd_width = 4; + res->fields[FIELD_imm8] = instr & 0xFF; + res->fields_mask[FIELD_imm8 >> 6] |= 1LL << (FIELD_imm8 & 63); + char imm8_width = 8; + + static const instruction_format instr_formats[] = + { + { /* ADD{S}<c> <Rd>,<Rn>,#<imm32> */ + "add", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_OPTIONAL_STATUS, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rd,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rn,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_IMM,FIELD_imm32,FIELD_UNINIT,"#","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_ADD; + + /* pcode: if Rd == '1111' && S == '1' then SEE CMN (immediate) */ + if(((res->fields[FIELD_Rd]) == (0xF)) && ((res->fields[FIELD_S]) == (0x1))) { + + return cmn_immediate(req, res); + } + /* pcode: if Rn == '1101' then SEE ADD (SP plus immediate) */ + if((res->fields[FIELD_Rn]) == (0xD)) { + + return add_sp_plus_immediate(req, res); + } + /* pcode: d = UInt(Rd) */ + res->fields[FIELD_d] = (res->fields[FIELD_Rd]); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: n = UInt(Rn) */ + res->fields[FIELD_n] = (res->fields[FIELD_Rn]); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: setflags = (S == '1') */ + res->fields[FIELD_setflags] = ((res->fields[FIELD_S]) == (0x1)); + res->fields_mask[FIELD_setflags >> 6] |= 1LL << (FIELD_setflags & 63); + /* pcode: imm32 = ThumbExpandImm(i:imm3:imm8) */ + res->fields[FIELD_imm32] = ThumbExpandImm_C_imm32((res->fields[FIELD_i]<<(8+3))|(res->fields[FIELD_imm3]<<8)|(res->fields[FIELD_imm8]), req->carry_in); + /* TODO: handle ThumbExpandImm_C's possible setting of UNPREDICTABLE */ while(0); + res->fields_mask[FIELD_imm32 >> 6] |= 1LL << (FIELD_imm32 & 63); + /* pcode: if BadReg(d) || n == 15 then UNPREDICTABLE */ + if((BadReg(res->fields[FIELD_d])) || ((res->fields[FIELD_n]) == (15))) { + res->flags |= FLAG_UNPREDICTABLE; + } + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* Encoding T4 */ + /* pattern="11110,i.1,1,0000,0,Rn.4,0,imm3.3,Rd.4,imm8.8" width=32 stringency=13 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFBF08000)==0xF2000000)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ARMv6T2) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_i] = (instr & 0x4000000)>>26; + res->fields_mask[FIELD_i >> 6] |= 1LL << (FIELD_i & 63); + char i_width = 1; + res->fields[FIELD_Rn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Rn >> 6] |= 1LL << (FIELD_Rn & 63); + char Rn_width = 4; + res->fields[FIELD_imm3] = (instr & 0x7000)>>12; + res->fields_mask[FIELD_imm3 >> 6] |= 1LL << (FIELD_imm3 & 63); + char imm3_width = 3; + res->fields[FIELD_Rd] = (instr & 0xF00)>>8; + res->fields_mask[FIELD_Rd >> 6] |= 1LL << (FIELD_Rd & 63); + char Rd_width = 4; + res->fields[FIELD_imm8] = instr & 0xFF; + res->fields_mask[FIELD_imm8 >> 6] |= 1LL << (FIELD_imm8 & 63); + char imm8_width = 8; + + static const instruction_format instr_formats[] = + { + { /* ADDW<c> <Rd>,<Rn>,#<imm32> */ + "addw", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rd,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rn,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_IMM,FIELD_imm32,FIELD_UNINIT,"#","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_ADDW; + + /* pcode: if Rn == '1111' then SEE ADR */ + if((res->fields[FIELD_Rn]) == (0xF)) { + + return adr(req, res); + } + /* pcode: if Rn == '1101' then SEE ADD (SP plus immediate) */ + if((res->fields[FIELD_Rn]) == (0xD)) { + + return add_sp_plus_immediate(req, res); + } + /* pcode: d = UInt(Rd) */ + res->fields[FIELD_d] = (res->fields[FIELD_Rd]); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: n = UInt(Rn) */ + res->fields[FIELD_n] = (res->fields[FIELD_Rn]); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: setflags = FALSE */ + res->fields[FIELD_setflags] = 0; + res->fields_mask[FIELD_setflags >> 6] |= 1LL << (FIELD_setflags & 63); + /* pcode: imm32 = ZeroExtend(i:imm3:imm8, 32) */ + res->fields[FIELD_imm32] = (res->fields[FIELD_i]<<(8+3))|(res->fields[FIELD_imm3]<<8)|(res->fields[FIELD_imm8]); + res->fields_mask[FIELD_imm32 >> 6] |= 1LL << (FIELD_imm32 & 63); + /* pcode: if BadReg(d) then UNPREDICTABLE */ + if(BadReg(res->fields[FIELD_d])) { + res->flags |= FLAG_UNPREDICTABLE; + } + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: 1D984FB3 +int add_register(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + /* Encoding T1 */ + /* pattern="000,11,0,0,Rm.3,Rn.3,Rd.3" width=16 stringency=7 */ + { + uint16_t instr = req->instr_word16; + if(((instr & 0xFE00)==0x1800)) { + res->instrSize = 16; + if(!(req->arch & ARCH_ARMv4T) && !(req->arch & ARCH_ARMv5T) && !(req->arch & ARCH_ARMv6) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_Rm] = (instr & 0x1C0)>>6; + res->fields_mask[FIELD_Rm >> 6] |= 1LL << (FIELD_Rm & 63); + char Rm_width = 3; + res->fields[FIELD_Rn] = (instr & 0x38)>>3; + res->fields_mask[FIELD_Rn >> 6] |= 1LL << (FIELD_Rn & 63); + char Rn_width = 3; + res->fields[FIELD_Rd] = instr & 0x7; + res->fields_mask[FIELD_Rd >> 6] |= 1LL << (FIELD_Rd & 63); + char Rd_width = 3; + + static const instruction_format instr_formats[] = + { + { /* ADDS <Rd>,<Rn>,<Rm> */ + "adds", /* .operation (const char *) */ + 0, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rd,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rn,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rm,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + { /* ADD<c> <Rd>,<Rn>,<Rm> */ + "add", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rd,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rn,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rm,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 2; + res->mnem = armv7::ARMV7_ADDS; + + /* pcode: d = UInt(Rd) */ + res->fields[FIELD_d] = (res->fields[FIELD_Rd]); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: n = UInt(Rn) */ + res->fields[FIELD_n] = (res->fields[FIELD_Rn]); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: m = UInt(Rm) */ + res->fields[FIELD_m] = (res->fields[FIELD_Rm]); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + /* pcode: setflags = !InITBlock() */ + res->fields[FIELD_setflags] = !(req->inIfThen == IFTHEN_YES); + res->fields_mask[FIELD_setflags >> 6] |= 1LL << (FIELD_setflags & 63); + /* pcode: (shift_t, shift_n) = (SRType_LSL, 0) */ + res->fields[FIELD_shift_t] = 0; + res->fields_mask[FIELD_shift_t >> 6] |= 1LL << (FIELD_shift_t & 63); + res->fields[FIELD_shift_n] = 0; + res->fields_mask[FIELD_shift_n >> 6] |= 1LL << (FIELD_shift_n & 63); + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* Encoding T2 */ + /* pattern="010001,00,DN.1,Rm.4,Rdn.3" width=16 stringency=9 */ + { + uint16_t instr = req->instr_word16; + if(((instr & 0xFF00)==0x4400)) { + res->instrSize = 16; + if(!(req->arch & ARCH_ARMv6T2) && !(req->arch & ARCH_ARMv7) && !(req->arch & ARCH_ARMv4T) && !(req->arch & ARCH_ARMv5T) && !(req->arch & ARCH_ARMv6) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_DN] = (instr & 0x80)>>7; + res->fields_mask[FIELD_DN >> 6] |= 1LL << (FIELD_DN & 63); + char DN_width = 1; + res->fields[FIELD_Rm] = (instr & 0x78)>>3; + res->fields_mask[FIELD_Rm >> 6] |= 1LL << (FIELD_Rm & 63); + char Rm_width = 4; + res->fields[FIELD_Rdn] = instr & 0x7; + res->fields_mask[FIELD_Rdn >> 6] |= 1LL << (FIELD_Rdn & 63); + char Rdn_width = 3; + + static const instruction_format instr_formats[] = + { + { /* ADD<c> <Rdn>,<Rm> */ + "add", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rdn,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rm,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_ADD; + + /* pcode: if (DN:Rdn) == '1101' || Rm == '1101' then SEE ADD (SP plus register) */ + if(((((res->fields[FIELD_DN]<<Rdn_width)|(res->fields[FIELD_Rdn]))) == (0xD)) || ((res->fields[FIELD_Rm]) == (0xD))) { + + return add_sp_plus_register(req, res); + } + /* pcode: Rdn = UInt(DN:Rdn) */ + res->fields[FIELD_Rdn] = ((res->fields[FIELD_DN]<<Rdn_width)|(res->fields[FIELD_Rdn])); + res->fields_mask[FIELD_Rdn >> 6] |= 1LL << (FIELD_Rdn & 63); + /* pcode: d = UInt(DN:Rdn) */ + res->fields[FIELD_d] = ((res->fields[FIELD_DN]<<Rdn_width)|(res->fields[FIELD_Rdn])); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: n = d */ + res->fields[FIELD_n] = res->fields[FIELD_d]; + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: m = UInt(Rm) */ + res->fields[FIELD_m] = (res->fields[FIELD_Rm]); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + /* pcode: setflags = FALSE */ + res->fields[FIELD_setflags] = 0; + res->fields_mask[FIELD_setflags >> 6] |= 1LL << (FIELD_setflags & 63); + /* pcode: (shift_t, shift_n) = (SRType_LSL, 0) */ + res->fields[FIELD_shift_t] = 0; + res->fields_mask[FIELD_shift_t >> 6] |= 1LL << (FIELD_shift_t & 63); + res->fields[FIELD_shift_n] = 0; + res->fields_mask[FIELD_shift_n >> 6] |= 1LL << (FIELD_shift_n & 63); + /* pcode: if n == 15 && m == 15 then UNPREDICTABLE */ + if(((res->fields[FIELD_n]) == (15)) && ((res->fields[FIELD_m]) == (15))) { + res->flags |= FLAG_UNPREDICTABLE; + } + /* pcode: if d == 15 && InITBlock() && !LastInITBlock() then UNPREDICTABLE */ + if((((res->fields[FIELD_d]) == (15)) && (req->inIfThen == IFTHEN_YES)) && (!(req->inIfThenLast == IFTHENLAST_YES))) { + res->flags |= FLAG_UNPREDICTABLE; + } + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* Encoding T3 */ + /* pattern="11101,01,1000,S.1,Rn.4,(0),imm3.3,Rd.4,imm2.2,type.2,Rm.4" width=32 stringency=13 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFFE00000)==0xEB000000)) { + res->instrSize = 32; + if(!((instr & 0x8000)==0x0)) { + res->flags |= FLAG_UNPREDICTABLE; + } + if(!(req->arch & ARCH_ARMv6T2) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_S] = (instr & 0x100000)>>20; + res->fields_mask[FIELD_S >> 6] |= 1LL << (FIELD_S & 63); + char S_width = 1; + res->fields[FIELD_Rn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Rn >> 6] |= 1LL << (FIELD_Rn & 63); + char Rn_width = 4; + res->fields[FIELD_imm3] = (instr & 0x7000)>>12; + res->fields_mask[FIELD_imm3 >> 6] |= 1LL << (FIELD_imm3 & 63); + char imm3_width = 3; + res->fields[FIELD_Rd] = (instr & 0xF00)>>8; + res->fields_mask[FIELD_Rd >> 6] |= 1LL << (FIELD_Rd & 63); + char Rd_width = 4; + res->fields[FIELD_imm2] = (instr & 0xC0)>>6; + res->fields_mask[FIELD_imm2 >> 6] |= 1LL << (FIELD_imm2 & 63); + char imm2_width = 2; + res->fields[FIELD_type] = (instr & 0x30)>>4; + res->fields_mask[FIELD_type >> 6] |= 1LL << (FIELD_type & 63); + char type_width = 2; + res->fields[FIELD_Rm] = instr & 0xF; + res->fields_mask[FIELD_Rm >> 6] |= 1LL << (FIELD_Rm & 63); + char Rm_width = 4; + + static const instruction_format instr_formats[] = + { + { /* ADD{S}<c> <Rd>,<Rn>,<Rm>{,<shift>} */ + "add", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_OPTIONAL_STATUS, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rd,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rn,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rm,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_SHIFT,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 4 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_ADD; + + /* pcode: if Rd == '1111' && S == '1' then SEE CMN (register) */ + if(((res->fields[FIELD_Rd]) == (0xF)) && ((res->fields[FIELD_S]) == (0x1))) { + + return cmn_register(req, res); + } + /* pcode: if Rn == '1101' then SEE ADD (SP plus register) */ + if((res->fields[FIELD_Rn]) == (0xD)) { + + return add_sp_plus_register(req, res); + } + /* pcode: d = UInt(Rd) */ + res->fields[FIELD_d] = (res->fields[FIELD_Rd]); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: n = UInt(Rn) */ + res->fields[FIELD_n] = (res->fields[FIELD_Rn]); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: m = UInt(Rm) */ + res->fields[FIELD_m] = (res->fields[FIELD_Rm]); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + /* pcode: setflags = (S == '1') */ + res->fields[FIELD_setflags] = ((res->fields[FIELD_S]) == (0x1)); + res->fields_mask[FIELD_setflags >> 6] |= 1LL << (FIELD_setflags & 63); + /* pcode: (shift_t, shift_n) = DecodeImmShift(type, imm3:imm2) */ + res->fields[FIELD_shift_t] = DecodeImmShift_shift_t(res->fields[FIELD_type], (res->fields[FIELD_imm3]<<2)|(res->fields[FIELD_imm2])); + res->fields_mask[FIELD_shift_t >> 6] |= 1LL << (FIELD_shift_t & 63); + res->fields[FIELD_shift_n] = DecodeImmShift_shift_n(res->fields[FIELD_type], (res->fields[FIELD_imm3]<<2)|(res->fields[FIELD_imm2])); + res->fields_mask[FIELD_shift_n >> 6] |= 1LL << (FIELD_shift_n & 63); + /* pcode: if BadReg(d) || n == 15 || BadReg(m) then UNPREDICTABLE */ + if(((BadReg(res->fields[FIELD_d])) || ((res->fields[FIELD_n]) == (15))) || (BadReg(res->fields[FIELD_m]))) { + res->flags |= FLAG_UNPREDICTABLE; + } + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: 8A919745 +int add_sp_plus_immediate(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + /* Encoding T1 */ + /* pattern="1010,1,Rd.3,imm8.8" width=16 stringency=5 */ + { + uint16_t instr = req->instr_word16; + if(((instr & 0xF800)==0xA800)) { + res->instrSize = 16; + if(!(req->arch & ARCH_ARMv4T) && !(req->arch & ARCH_ARMv5T) && !(req->arch & ARCH_ARMv6) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_Rd] = (instr & 0x700)>>8; + res->fields_mask[FIELD_Rd >> 6] |= 1LL << (FIELD_Rd & 63); + char Rd_width = 3; + res->fields[FIELD_imm8] = instr & 0xFF; + res->fields_mask[FIELD_imm8 >> 6] |= 1LL << (FIELD_imm8 & 63); + char imm8_width = 8; + + static const instruction_format instr_formats[] = + { + { /* ADD<c> <Rd>,SP,#<imm32> */ + "add", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rd,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_SP,FIELD_UNINIT,FIELD_UNINIT,"sp","",WRITEBACK_NO}, + {OPERAND_FORMAT_IMM,FIELD_imm32,FIELD_UNINIT,"#","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_ADD; + + /* pcode: d = UInt(Rd) */ + res->fields[FIELD_d] = (res->fields[FIELD_Rd]); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: setflags = FALSE */ + res->fields[FIELD_setflags] = 0; + res->fields_mask[FIELD_setflags >> 6] |= 1LL << (FIELD_setflags & 63); + /* pcode: imm32 = ZeroExtend(imm8:'00', 32) */ + res->fields[FIELD_imm32] = (res->fields[FIELD_imm8]<<2)|(0x0); + res->fields_mask[FIELD_imm32 >> 6] |= 1LL << (FIELD_imm32 & 63); + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* Encoding T2 */ + /* pattern="1011,0000,0,imm7.7" width=16 stringency=9 */ + { + uint16_t instr = req->instr_word16; + if(((instr & 0xFF80)==0xB000)) { + res->instrSize = 16; + if(!(req->arch & ARCH_ARMv4T) && !(req->arch & ARCH_ARMv5T) && !(req->arch & ARCH_ARMv6) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_imm7] = instr & 0x7F; + res->fields_mask[FIELD_imm7 >> 6] |= 1LL << (FIELD_imm7 & 63); + char imm7_width = 7; + + static const instruction_format instr_formats[] = + { + { /* ADD<c> SP,#<imm32> */ + "add", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_SP,FIELD_UNINIT,FIELD_UNINIT,"sp","",WRITEBACK_NO}, + {OPERAND_FORMAT_IMM,FIELD_imm32,FIELD_UNINIT,"#","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_ADD; + + /* pcode: d = 13 */ + res->fields[FIELD_d] = 13; + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: setflags = FALSE */ + res->fields[FIELD_setflags] = 0; + res->fields_mask[FIELD_setflags >> 6] |= 1LL << (FIELD_setflags & 63); + /* pcode: imm32 = ZeroExtend(imm7:'00', 32) */ + res->fields[FIELD_imm32] = (res->fields[FIELD_imm7]<<2)|(0x0); + res->fields_mask[FIELD_imm32 >> 6] |= 1LL << (FIELD_imm32 & 63); + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* Encoding T3 */ + /* pattern="11110,i.1,0,1000,S.1,1101,0,imm3.3,Rd.4,imm8.8" width=32 stringency=17 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFBEF8000)==0xF10D0000)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ARMv6T2) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_i] = (instr & 0x4000000)>>26; + res->fields_mask[FIELD_i >> 6] |= 1LL << (FIELD_i & 63); + char i_width = 1; + res->fields[FIELD_S] = (instr & 0x100000)>>20; + res->fields_mask[FIELD_S >> 6] |= 1LL << (FIELD_S & 63); + char S_width = 1; + res->fields[FIELD_imm3] = (instr & 0x7000)>>12; + res->fields_mask[FIELD_imm3 >> 6] |= 1LL << (FIELD_imm3 & 63); + char imm3_width = 3; + res->fields[FIELD_Rd] = (instr & 0xF00)>>8; + res->fields_mask[FIELD_Rd >> 6] |= 1LL << (FIELD_Rd & 63); + char Rd_width = 4; + res->fields[FIELD_imm8] = instr & 0xFF; + res->fields_mask[FIELD_imm8 >> 6] |= 1LL << (FIELD_imm8 & 63); + char imm8_width = 8; + + static const instruction_format instr_formats[] = + { + { /* ADD{S}<c> <Rd>,SP,#<imm32> */ + "add", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_OPTIONAL_STATUS, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rd,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_SP,FIELD_UNINIT,FIELD_UNINIT,"sp","",WRITEBACK_NO}, + {OPERAND_FORMAT_IMM,FIELD_imm32,FIELD_UNINIT,"#","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_ADD; + + /* pcode: if Rd == '1111' && S == '1' then SEE CMN (immediate) */ + if(((res->fields[FIELD_Rd]) == (0xF)) && ((res->fields[FIELD_S]) == (0x1))) { + + return cmn_immediate(req, res); + } + /* pcode: d = UInt(Rd) */ + res->fields[FIELD_d] = (res->fields[FIELD_Rd]); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: setflags = (S == '1') */ + res->fields[FIELD_setflags] = ((res->fields[FIELD_S]) == (0x1)); + res->fields_mask[FIELD_setflags >> 6] |= 1LL << (FIELD_setflags & 63); + /* pcode: imm32 = ThumbExpandImm(i:imm3:imm8) */ + res->fields[FIELD_imm32] = ThumbExpandImm_C_imm32((res->fields[FIELD_i]<<(8+3))|(res->fields[FIELD_imm3]<<8)|(res->fields[FIELD_imm8]), req->carry_in); + /* TODO: handle ThumbExpandImm_C's possible setting of UNPREDICTABLE */ while(0); + res->fields_mask[FIELD_imm32 >> 6] |= 1LL << (FIELD_imm32 & 63); + /* pcode: if d == 15 then UNPREDICTABLE */ + if((res->fields[FIELD_d]) == (15)) { + res->flags |= FLAG_UNPREDICTABLE; + } + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* Encoding T4 */ + /* pattern="11110,i.1,1,0000,0,1101,0,imm3.3,Rd.4,imm8.8" width=32 stringency=17 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFBFF8000)==0xF20D0000)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ARMv6T2) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_i] = (instr & 0x4000000)>>26; + res->fields_mask[FIELD_i >> 6] |= 1LL << (FIELD_i & 63); + char i_width = 1; + res->fields[FIELD_imm3] = (instr & 0x7000)>>12; + res->fields_mask[FIELD_imm3 >> 6] |= 1LL << (FIELD_imm3 & 63); + char imm3_width = 3; + res->fields[FIELD_Rd] = (instr & 0xF00)>>8; + res->fields_mask[FIELD_Rd >> 6] |= 1LL << (FIELD_Rd & 63); + char Rd_width = 4; + res->fields[FIELD_imm8] = instr & 0xFF; + res->fields_mask[FIELD_imm8 >> 6] |= 1LL << (FIELD_imm8 & 63); + char imm8_width = 8; + + static const instruction_format instr_formats[] = + { + { /* ADDW<c> <Rd>,SP,#<imm32> */ + "addw", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rd,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_SP,FIELD_UNINIT,FIELD_UNINIT,"sp","",WRITEBACK_NO}, + {OPERAND_FORMAT_IMM,FIELD_imm32,FIELD_UNINIT,"#","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_ADDW; + + /* pcode: d = UInt(Rd) */ + res->fields[FIELD_d] = (res->fields[FIELD_Rd]); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: setflags = FALSE */ + res->fields[FIELD_setflags] = 0; + res->fields_mask[FIELD_setflags >> 6] |= 1LL << (FIELD_setflags & 63); + /* pcode: imm32 = ZeroExtend(i:imm3:imm8, 32) */ + res->fields[FIELD_imm32] = (res->fields[FIELD_i]<<(8+3))|(res->fields[FIELD_imm3]<<8)|(res->fields[FIELD_imm8]); + res->fields_mask[FIELD_imm32 >> 6] |= 1LL << (FIELD_imm32 & 63); + /* pcode: if d == 15 then UNPREDICTABLE */ + if((res->fields[FIELD_d]) == (15)) { + res->flags |= FLAG_UNPREDICTABLE; + } + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: 2AFA11CA +int add_sp_plus_register(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + /* Encoding T1 */ + /* pattern="01000100,DM.1,1101,Rdm.3" width=16 stringency=13 */ + { + uint16_t instr = req->instr_word16; + if(((instr & 0xFF78)==0x4468)) { + res->instrSize = 16; + if(!(req->arch & ARCH_ARMv4T) && !(req->arch & ARCH_ARMv5T) && !(req->arch & ARCH_ARMv6) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_DM] = (instr & 0x80)>>7; + res->fields_mask[FIELD_DM >> 6] |= 1LL << (FIELD_DM & 63); + char DM_width = 1; + res->fields[FIELD_Rdm] = instr & 0x7; + res->fields_mask[FIELD_Rdm >> 6] |= 1LL << (FIELD_Rdm & 63); + char Rdm_width = 3; + + static const instruction_format instr_formats[] = + { + { /* ADD<c> <Rdm>,SP,<Rdm> */ + "add", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rdm,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_SP,FIELD_UNINIT,FIELD_UNINIT,"sp","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rdm,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_ADD; + + /* pcode: Rdm = UInt(DM:Rdm) */ + res->fields[FIELD_Rdm] = ((res->fields[FIELD_DM]<<Rdm_width)|(res->fields[FIELD_Rdm])); + res->fields_mask[FIELD_Rdm >> 6] |= 1LL << (FIELD_Rdm & 63); + /* pcode: m = UInt(DM:Rdm) */ + res->fields[FIELD_m] = ((res->fields[FIELD_DM]<<Rdm_width)|(res->fields[FIELD_Rdm])); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + /* pcode: setflags = FALSE */ + res->fields[FIELD_setflags] = 0; + res->fields_mask[FIELD_setflags >> 6] |= 1LL << (FIELD_setflags & 63); + /* pcode: (shift_t, shift_n) = (SRType_LSL, 0) */ + res->fields[FIELD_shift_t] = 0; + res->fields_mask[FIELD_shift_t >> 6] |= 1LL << (FIELD_shift_t & 63); + res->fields[FIELD_shift_n] = 0; + res->fields_mask[FIELD_shift_n >> 6] |= 1LL << (FIELD_shift_n & 63); + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* Encoding T2 */ + /* pattern="01000100,1,Rm.4,101" width=16 stringency=12 */ + { + uint16_t instr = req->instr_word16; + if(((instr & 0xFF87)==0x4485)) { + res->instrSize = 16; + if(!(req->arch & ARCH_ARMv4T) && !(req->arch & ARCH_ARMv5T) && !(req->arch & ARCH_ARMv6) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_Rm] = (instr & 0x78)>>3; + res->fields_mask[FIELD_Rm >> 6] |= 1LL << (FIELD_Rm & 63); + char Rm_width = 4; + + static const instruction_format instr_formats[] = + { + { /* ADD<c> SP,<Rm> */ + "add", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_SP,FIELD_UNINIT,FIELD_UNINIT,"sp","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rm,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_ADD; + + /* pcode: d = 13 */ + res->fields[FIELD_d] = 13; + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: m = UInt(Rm) */ + res->fields[FIELD_m] = (res->fields[FIELD_Rm]); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + /* pcode: setflags = FALSE */ + res->fields[FIELD_setflags] = 0; + res->fields_mask[FIELD_setflags >> 6] |= 1LL << (FIELD_setflags & 63); + /* pcode: (shift_t, shift_n) = (SRType_LSL, 0) */ + res->fields[FIELD_shift_t] = 0; + res->fields_mask[FIELD_shift_t >> 6] |= 1LL << (FIELD_shift_t & 63); + res->fields[FIELD_shift_n] = 0; + res->fields_mask[FIELD_shift_n >> 6] |= 1LL << (FIELD_shift_n & 63); + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* Encoding T3 */ + /* pattern="11101011000,S.1,1101,0,imm3.3,Rd.4,imm2.2,type.2,Rm.4" width=32 stringency=17 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFFEF8000)==0xEB0D0000)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ARMv6T2) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_S] = (instr & 0x100000)>>20; + res->fields_mask[FIELD_S >> 6] |= 1LL << (FIELD_S & 63); + char S_width = 1; + res->fields[FIELD_imm3] = (instr & 0x7000)>>12; + res->fields_mask[FIELD_imm3 >> 6] |= 1LL << (FIELD_imm3 & 63); + char imm3_width = 3; + res->fields[FIELD_Rd] = (instr & 0xF00)>>8; + res->fields_mask[FIELD_Rd >> 6] |= 1LL << (FIELD_Rd & 63); + char Rd_width = 4; + res->fields[FIELD_imm2] = (instr & 0xC0)>>6; + res->fields_mask[FIELD_imm2 >> 6] |= 1LL << (FIELD_imm2 & 63); + char imm2_width = 2; + res->fields[FIELD_type] = (instr & 0x30)>>4; + res->fields_mask[FIELD_type >> 6] |= 1LL << (FIELD_type & 63); + char type_width = 2; + res->fields[FIELD_Rm] = instr & 0xF; + res->fields_mask[FIELD_Rm >> 6] |= 1LL << (FIELD_Rm & 63); + char Rm_width = 4; + + static const instruction_format instr_formats[] = + { + { /* ADD{S}<c> <Rd>,SP,<Rm>{,<shift>} */ + "add", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_OPTIONAL_STATUS, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rd,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_SP,FIELD_UNINIT,FIELD_UNINIT,"sp","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rm,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_SHIFT,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 4 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_ADD; + + /* pcode: d = UInt(Rd) */ + res->fields[FIELD_d] = (res->fields[FIELD_Rd]); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: m = UInt(Rm) */ + res->fields[FIELD_m] = (res->fields[FIELD_Rm]); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + /* pcode: setflags = (S == '1') */ + res->fields[FIELD_setflags] = ((res->fields[FIELD_S]) == (0x1)); + res->fields_mask[FIELD_setflags >> 6] |= 1LL << (FIELD_setflags & 63); + /* pcode: (shift_t, shift_n) = DecodeImmShift(type, imm3:imm2) */ + res->fields[FIELD_shift_t] = DecodeImmShift_shift_t(res->fields[FIELD_type], (res->fields[FIELD_imm3]<<2)|(res->fields[FIELD_imm2])); + res->fields_mask[FIELD_shift_t >> 6] |= 1LL << (FIELD_shift_t & 63); + res->fields[FIELD_shift_n] = DecodeImmShift_shift_n(res->fields[FIELD_type], (res->fields[FIELD_imm3]<<2)|(res->fields[FIELD_imm2])); + res->fields_mask[FIELD_shift_n >> 6] |= 1LL << (FIELD_shift_n & 63); + /* pcode: if d == 13 && (shift_t != SRType_LSL || shift_n > 3) then UNPREDICTABLE */ + if(((res->fields[FIELD_d]) == (13)) && ((((res->fields[FIELD_shift_t]) != (0)) || ((res->fields[FIELD_shift_n]) > (3))))) { + res->flags |= FLAG_UNPREDICTABLE; + } + /* pcode: if d == 15 || BadReg(m) then UNPREDICTABLE */ + if(((res->fields[FIELD_d]) == (15)) || (BadReg(res->fields[FIELD_m]))) { + res->flags |= FLAG_UNPREDICTABLE; + } + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: DBCA34E0 +int adr(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + /* Encoding T1 */ + /* pattern="1010,0,Rd.3,imm8.8" width=16 stringency=5 */ + { + uint16_t instr = req->instr_word16; + if(((instr & 0xF800)==0xA000)) { + res->instrSize = 16; + if(!(req->arch & ARCH_ARMv4T) && !(req->arch & ARCH_ARMv5T) && !(req->arch & ARCH_ARMv6) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_Rd] = (instr & 0x700)>>8; + res->fields_mask[FIELD_Rd >> 6] |= 1LL << (FIELD_Rd & 63); + char Rd_width = 3; + res->fields[FIELD_imm8] = instr & 0xFF; + res->fields_mask[FIELD_imm8 >> 6] |= 1LL << (FIELD_imm8 & 63); + char imm8_width = 8; + + static const instruction_format instr_formats[] = + { + { /* ADR<c> <Rd>,#<imm32> */ + "adr", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rd,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_IMM,FIELD_imm32,FIELD_UNINIT,"#","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_ADR; + + /* pcode: d = UInt(Rd) */ + res->fields[FIELD_d] = (res->fields[FIELD_Rd]); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: imm32 = ZeroExtend(imm8:'00', 32) */ + res->fields[FIELD_imm32] = (res->fields[FIELD_imm8]<<2)|(0x0); + res->fields_mask[FIELD_imm32 >> 6] |= 1LL << (FIELD_imm32 & 63); + /* pcode: add = TRUE */ + res->fields[FIELD_add] = 1; + res->fields_mask[FIELD_add >> 6] |= 1LL << (FIELD_add & 63); + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* Encoding T2 */ + /* pattern="11110,i.1,10101,0,1111,0,imm3.3,Rd.4,imm8.8" width=32 stringency=17 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFBFF8000)==0xF2AF0000)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ARMv6T2) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_i] = (instr & 0x4000000)>>26; + res->fields_mask[FIELD_i >> 6] |= 1LL << (FIELD_i & 63); + char i_width = 1; + res->fields[FIELD_imm3] = (instr & 0x7000)>>12; + res->fields_mask[FIELD_imm3 >> 6] |= 1LL << (FIELD_imm3 & 63); + char imm3_width = 3; + res->fields[FIELD_Rd] = (instr & 0xF00)>>8; + res->fields_mask[FIELD_Rd >> 6] |= 1LL << (FIELD_Rd & 63); + char Rd_width = 4; + res->fields[FIELD_imm8] = instr & 0xFF; + res->fields_mask[FIELD_imm8 >> 6] |= 1LL << (FIELD_imm8 & 63); + char imm8_width = 8; + + static const instruction_format instr_formats[] = + { + { /* SUBW<c> <Rd>,PC,#<imm32> */ + "subw", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rd,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_PC,FIELD_UNINIT,FIELD_UNINIT,"pc","",WRITEBACK_NO}, + {OPERAND_FORMAT_IMM,FIELD_imm32,FIELD_UNINIT,"#","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_SUBW; + + /* pcode: d = UInt(Rd) */ + res->fields[FIELD_d] = (res->fields[FIELD_Rd]); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: imm32 = ZeroExtend(i:imm3:imm8, 32) */ + res->fields[FIELD_imm32] = (res->fields[FIELD_i]<<(8+3))|(res->fields[FIELD_imm3]<<8)|(res->fields[FIELD_imm8]); + res->fields_mask[FIELD_imm32 >> 6] |= 1LL << (FIELD_imm32 & 63); + /* pcode: add = FALSE */ + res->fields[FIELD_add] = 0; + res->fields_mask[FIELD_add >> 6] |= 1LL << (FIELD_add & 63); + /* pcode: if BadReg(d) then UNPREDICTABLE */ + if(BadReg(res->fields[FIELD_d])) { + res->flags |= FLAG_UNPREDICTABLE; + } + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* Encoding T3 */ + /* pattern="11110,i.1,10000,0,1111,0,imm3.3,Rd.4,imm8.8" width=32 stringency=17 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFBFF8000)==0xF20F0000)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ARMv6T2) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_i] = (instr & 0x4000000)>>26; + res->fields_mask[FIELD_i >> 6] |= 1LL << (FIELD_i & 63); + char i_width = 1; + res->fields[FIELD_imm3] = (instr & 0x7000)>>12; + res->fields_mask[FIELD_imm3 >> 6] |= 1LL << (FIELD_imm3 & 63); + char imm3_width = 3; + res->fields[FIELD_Rd] = (instr & 0xF00)>>8; + res->fields_mask[FIELD_Rd >> 6] |= 1LL << (FIELD_Rd & 63); + char Rd_width = 4; + res->fields[FIELD_imm8] = instr & 0xFF; + res->fields_mask[FIELD_imm8 >> 6] |= 1LL << (FIELD_imm8 & 63); + char imm8_width = 8; + + static const instruction_format instr_formats[] = + { + { /* ADDW <Rd>,PC,#<imm32> */ + "addw", /* .operation (const char *) */ + 0, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rd,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_PC,FIELD_UNINIT,FIELD_UNINIT,"pc","",WRITEBACK_NO}, + {OPERAND_FORMAT_IMM,FIELD_imm32,FIELD_UNINIT,"#","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_ADDW; + + /* pcode: d = UInt(Rd) */ + res->fields[FIELD_d] = (res->fields[FIELD_Rd]); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: imm32 = ZeroExtend(i:imm3:imm8, 32) */ + res->fields[FIELD_imm32] = (res->fields[FIELD_i]<<(8+3))|(res->fields[FIELD_imm3]<<8)|(res->fields[FIELD_imm8]); + res->fields_mask[FIELD_imm32 >> 6] |= 1LL << (FIELD_imm32 & 63); + /* pcode: add = TRUE */ + res->fields[FIELD_add] = 1; + res->fields_mask[FIELD_add >> 6] |= 1LL << (FIELD_add & 63); + /* pcode: if BadReg(d) then UNPREDICTABLE */ + if(BadReg(res->fields[FIELD_d])) { + res->flags |= FLAG_UNPREDICTABLE; + } + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: F64BBD61 +int advanced_simd_data_proc(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + uint32_t instr = req->instr_word32; + uint32_t U = (instr & 0x10000000)>>28; + uint32_t A = (instr & 0xF80000)>>19; + uint32_t B = (instr & 0xF00)>>8; + uint32_t C = (instr & 0xF0)>>4; + if(((U & 0x1)==0x1) && ((A & 0x16)==0x16) && ((B & 0xF)==0xC) && ((C & 0x9)==0x0)) return vdup_scalar(req, res); + if(((U & 0x1)==0x1) && ((A & 0x16)==0x16) && ((B & 0xC)==0x8) && ((C & 0x1)==0x0)) return vtbl(req, res); + if(((A & 0x17)==0x10) && ((C & 0x9)==0x1) && 1) return advsimd_one_reg_mod_imm(req, res); + if(((A & 0x17)==0x11) && ((C & 0x9)==0x1) && 1) return advsimd_two_reg_shift(req, res); + if(((A & 0x16)==0x12) && ((C & 0x9)==0x1) && 1) return advsimd_two_reg_shift(req, res); + if(((A & 0x16)==0x14) && ((C & 0x5)==0x0) && 1) return advsimd_three_reg_diff_len(req, res); + if(((A & 0x16)==0x14) && ((C & 0x5)==0x4) && 1) return advsimd_two_reg_scalar(req, res); + if(((U & 0x1)==0x0) && ((A & 0x16)==0x16) && ((C & 0x1)==0x0) && 1) return vext(req, res); + if(((U & 0x1)==0x1) && ((A & 0x16)==0x16) && ((C & 0x1)==0x0) && 1) return advsimd_two_reg_misc(req, res); + if(((A & 0x14)==0x14) && ((C & 0x9)==0x1) && 1) return advsimd_two_reg_shift(req, res); + if(((A & 0x14)==0x10) && ((C & 0x5)==0x0) && 1) return advsimd_three_reg_diff_len(req, res); + if(((A & 0x14)==0x10) && ((C & 0x5)==0x4) && 1) return advsimd_two_reg_scalar(req, res); + if(((A & 0x10)==0x10) && ((C & 0x9)==0x9) && 1) return advsimd_two_reg_shift(req, res); + if(((A & 0x10)==0x0) && 1) return advsimd_three_reg_same_len(req, res); + return undefined(req, res); +} + +// gen_crc: ECC2A52B +int advanced_simd_elem_struct_load_store(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + uint32_t instr = req->instr_word32; + uint32_t A = (instr & 0x800000)>>23; + uint32_t L = (instr & 0x200000)>>21; + uint32_t B = (instr & 0xF00)>>8; + if(((A & 0x1)==0x0) && ((B & 0xF)==0x2) && ((L & 0x1)==0x0)) return vst1_mult_1elem(req, res); + if(((A & 0x1)==0x0) && ((B & 0xF)==0xA) && ((L & 0x1)==0x0)) return vst1_mult_1elem(req, res); + if(((A & 0x1)==0x0) && ((B & 0xF)==0x3) && ((L & 0x1)==0x0)) return vst2_mult_2elem(req, res); + if(((A & 0x1)==0x1) && ((B & 0xF)==0x8) && ((L & 0x1)==0x0)) return vst1_single_1elem(req, res); + if(((A & 0x1)==0x1) && ((B & 0xF)==0x9) && ((L & 0x1)==0x0)) return vst2_single_2elem(req, res); + if(((A & 0x1)==0x1) && ((B & 0xF)==0xA) && ((L & 0x1)==0x0)) return vst3_single_3elem(req, res); + if(((A & 0x1)==0x1) && ((B & 0xF)==0xB) && ((L & 0x1)==0x0)) return vst4_single_4elem(req, res); + if(((A & 0x1)==0x0) && ((B & 0xF)==0x2) && ((L & 0x1)==0x1)) return vld1_mult_1elem(req, res); + if(((A & 0x1)==0x0) && ((B & 0xF)==0xA) && ((L & 0x1)==0x1)) return vld1_mult_1elem(req, res); + if(((A & 0x1)==0x0) && ((B & 0xF)==0x3) && ((L & 0x1)==0x1)) return vld2_mult_2elem(req, res); + if(((A & 0x1)==0x1) && ((B & 0xF)==0x8) && ((L & 0x1)==0x1)) return vld1_single_1elem_1lane(req, res); + if(((A & 0x1)==0x1) && ((B & 0xF)==0xC) && ((L & 0x1)==0x1)) return vld1_single_1elem_nlanes(req, res); + if(((A & 0x1)==0x1) && ((B & 0xF)==0x9) && ((L & 0x1)==0x1)) return vld2_single_2elem_1lane(req, res); + if(((A & 0x1)==0x1) && ((B & 0xF)==0xD) && ((L & 0x1)==0x1)) return vld2_single_2elem_nlanes(req, res); + if(((A & 0x1)==0x1) && ((B & 0xF)==0xA) && ((L & 0x1)==0x1)) return vld3_single_3elem_1lane(req, res); + if(((A & 0x1)==0x1) && ((B & 0xF)==0xE) && ((L & 0x1)==0x1)) return vld3_single_3elem_nlanes(req, res); + if(((A & 0x1)==0x1) && ((B & 0xF)==0xB) && ((L & 0x1)==0x1)) return vld4_single_4elem_1lane(req, res); + if(((A & 0x1)==0x1) && ((B & 0xF)==0xF) && ((L & 0x1)==0x1)) return vld4_single_4elem_nlanes(req, res); + if(((A & 0x1)==0x0) && ((B & 0xE)==0x6) && ((L & 0x1)==0x0)) return vst1_mult_1elem(req, res); + if(((A & 0x1)==0x0) && ((B & 0xE)==0x8) && ((L & 0x1)==0x0)) return vst2_mult_2elem(req, res); + if(((A & 0x1)==0x0) && ((B & 0xE)==0x4) && ((L & 0x1)==0x0)) return vst3_mult_3elem(req, res); + if(((A & 0x1)==0x0) && ((B & 0xE)==0x0) && ((L & 0x1)==0x0)) return vst4_mult_4elem(req, res); + if(((A & 0x1)==0x1) && ((B & 0xB)==0x0) && ((L & 0x1)==0x0)) return vst1_single_1elem(req, res); + if(((A & 0x1)==0x1) && ((B & 0xB)==0x1) && ((L & 0x1)==0x0)) return vst2_single_2elem(req, res); + if(((A & 0x1)==0x1) && ((B & 0xB)==0x2) && ((L & 0x1)==0x0)) return vst3_single_3elem(req, res); + if(((A & 0x1)==0x1) && ((B & 0xB)==0x3) && ((L & 0x1)==0x0)) return vst4_single_4elem(req, res); + if(((A & 0x1)==0x0) && ((B & 0xE)==0x6) && ((L & 0x1)==0x1)) return vld1_mult_1elem(req, res); + if(((A & 0x1)==0x0) && ((B & 0xE)==0x8) && ((L & 0x1)==0x1)) return vld2_mult_2elem(req, res); + if(((A & 0x1)==0x0) && ((B & 0xE)==0x4) && ((L & 0x1)==0x1)) return vld3_mult_3elem(req, res); + if(((A & 0x1)==0x0) && ((B & 0xE)==0x0) && ((L & 0x1)==0x1)) return vld4_mult_4elem(req, res); + if(((A & 0x1)==0x1) && ((B & 0xB)==0x0) && ((L & 0x1)==0x1)) return vld1_single_1elem_1lane(req, res); + if(((A & 0x1)==0x1) && ((B & 0xB)==0x1) && ((L & 0x1)==0x1)) return vld2_single_2elem_1lane(req, res); + if(((A & 0x1)==0x1) && ((B & 0xB)==0x2) && ((L & 0x1)==0x1)) return vld3_single_3elem_1lane(req, res); + if(((A & 0x1)==0x1) && ((B & 0xB)==0x3) && ((L & 0x1)==0x1)) return vld4_single_4elem_1lane(req, res); + return undefined(req, res); +} + +// gen_crc: FFAE563B +int advsimd_one_reg_mod_imm(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + uint32_t instr = req->instr_word32; + uint32_t a = (instr & 0x10000000)>>28; + uint32_t b = (instr & 0x40000)>>18; + uint32_t c = (instr & 0x20000)>>17; + uint32_t d = (instr & 0x10000)>>16; + uint32_t cmode = (instr & 0xF00)>>8; + uint32_t op = (instr & 0x20)>>5; + uint32_t e = (instr & 0x8)>>3; + uint32_t f = (instr & 0x4)>>2; + uint32_t g = (instr & 0x2)>>1; + uint32_t h = instr & 0x1; + if(((op & 0x1)==0x1) && ((cmode & 0xF)==0xE)) return vmov_immediate(req, res); + if(((op & 0x1)==0x0) && ((cmode & 0xD)==0x8)) return vmov_immediate(req, res); + if(((op & 0x1)==0x0) && ((cmode & 0xD)==0x9)) return vorr_immediate(req, res); + if(((op & 0x1)==0x1) && ((cmode & 0xD)==0x8)) return vmvn_immediate(req, res); + if(((op & 0x1)==0x1) && ((cmode & 0xD)==0x9)) return vbic_immediate(req, res); + if(((op & 0x1)==0x1) && ((cmode & 0xE)==0xC)) return vmvn_immediate(req, res); + if(((op & 0x1)==0x0) && ((cmode & 0x9)==0x0)) return vmov_immediate(req, res); + if(((op & 0x1)==0x0) && ((cmode & 0x9)==0x1)) return vorr_immediate(req, res); + if(((op & 0x1)==0x0) && ((cmode & 0xC)==0xC)) return vmov_immediate(req, res); + if(((op & 0x1)==0x1) && ((cmode & 0x9)==0x0)) return vmvn_immediate(req, res); + if(((op & 0x1)==0x1) && ((cmode & 0x9)==0x1)) return vbic_immediate(req, res); + if(1) return undefined(req, res); + return undefined(req, res); +} + +// gen_crc: 20C28F5C +int advsimd_three_reg_diff_len(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + uint32_t instr = req->instr_word32; + uint32_t U = (instr & 0x10000000)>>28; + uint32_t B = (instr & 0x300000)>>20; + uint32_t A = (instr & 0xF00)>>8; + if(((A & 0xF)==0x4) && ((U & 0x1)==0x0)) return vaddhn(req, res); + if(((A & 0xF)==0x4) && ((U & 0x1)==0x1)) return vraddhn(req, res); + if(((A & 0xF)==0x6) && ((U & 0x1)==0x0)) return vsubhn(req, res); + if(((A & 0xF)==0x6) && ((U & 0x1)==0x1)) return vrsubhn(req, res); + if(((A & 0xF)==0xD) && ((U & 0x1)==0x0)) return vqdmull(req, res); + if(((A & 0xF)==0x7) && 1) return vabd_integer(req, res); + if(((A & 0xF)==0x5) && 1) return vaba(req, res); + if(((A & 0xD)==0x9) && ((U & 0x1)==0x0)) return vqdmlal(req, res); + if(((A & 0xF)==0xC) && 1) return vmul_integer(req, res); + if(((A & 0xF)==0xE) && 1) return vmul_integer(req, res); + if(((A & 0xE)==0x2) && 1) return vsubl(req, res); + if(((A & 0xE)==0x0) && 1) return vaddlw(req, res); + if(((A & 0xD)==0x8) && 1) return vmla_integer(req, res); + if(1) return undefined(req, res); + return undefined(req, res); +} + +// gen_crc: CBBFBD78 +int advsimd_three_reg_same_len(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + uint32_t instr = req->instr_word32; + uint32_t U = (instr & 0x10000000)>>28; + uint32_t C = (instr & 0x300000)>>20; + uint32_t A = (instr & 0xF00)>>8; + uint32_t B = (instr & 0x10)>>4; + if(((A & 0xF)==0x1) && ((B & 0x1)==0x1) && ((U & 0x1)==0x0) && ((C & 0x3)==0x0)) return vand(req, res); + if(((A & 0xF)==0x1) && ((B & 0x1)==0x1) && ((U & 0x1)==0x0) && ((C & 0x3)==0x1)) return vbic_register(req, res); + if(((A & 0xF)==0x1) && ((B & 0x1)==0x1) && ((U & 0x1)==0x0) && ((C & 0x3)==0x2)) return vorr_register(req, res); + if(((A & 0xF)==0x1) && ((B & 0x1)==0x1) && ((U & 0x1)==0x0) && ((C & 0x3)==0x3)) return vorn_register(req, res); + if(((A & 0xF)==0x1) && ((B & 0x1)==0x1) && ((U & 0x1)==0x1) && ((C & 0x3)==0x0)) return veor(req, res); + if(((A & 0xF)==0x1) && ((B & 0x1)==0x1) && ((U & 0x1)==0x1) && ((C & 0x3)==0x1)) return vbsl(req, res); + if(((A & 0xF)==0x1) && ((B & 0x1)==0x1) && ((U & 0x1)==0x1) && ((C & 0x3)==0x2)) return vbit(req, res); + if(((A & 0xF)==0x1) && ((B & 0x1)==0x1) && ((U & 0x1)==0x1) && ((C & 0x3)==0x3)) return vbif(req, res); + if(((A & 0xF)==0xD) && ((B & 0x1)==0x0) && ((U & 0x1)==0x1) && ((C & 0x2)==0x2)) return vabd_float(req, res); + if(((A & 0xF)==0xD) && ((B & 0x1)==0x0) && ((U & 0x1)==0x0) && ((C & 0x2)==0x0)) return vadd_float(req, res); + if(((A & 0xF)==0xD) && ((B & 0x1)==0x0) && ((U & 0x1)==0x0) && ((C & 0x2)==0x2)) return vsub_float(req, res); + if(((A & 0xF)==0xD) && ((B & 0x1)==0x0) && ((U & 0x1)==0x1) && ((C & 0x2)==0x0)) return vpadd_float(req, res); + if(((A & 0xF)==0xD) && ((B & 0x1)==0x1) && ((U & 0x1)==0x1) && ((C & 0x2)==0x0)) return vmul_float(req, res); + if(((A & 0xF)==0xE) && ((B & 0x1)==0x0) && ((U & 0x1)==0x1) && ((C & 0x2)==0x0)) return vcge_register(req, res); + if(((A & 0xF)==0xE) && ((B & 0x1)==0x0) && ((U & 0x1)==0x1) && ((C & 0x2)==0x2)) return vcgt_register(req, res); + if(((A & 0xF)==0xE) && ((B & 0x1)==0x0) && ((U & 0x1)==0x0) && ((C & 0x2)==0x0)) return vceq_register(req, res); + if(((A & 0xF)==0xF) && ((B & 0x1)==0x1) && ((U & 0x1)==0x0) && ((C & 0x2)==0x0)) return vrecps(req, res); + if(((A & 0xF)==0xF) && ((B & 0x1)==0x1) && ((U & 0x1)==0x0) && ((C & 0x2)==0x2)) return vrsqrts(req, res); + if(((A & 0xF)==0x8) && ((B & 0x1)==0x0) && ((U & 0x1)==0x0) && 1) return vadd_integer(req, res); + if(((A & 0xF)==0x8) && ((B & 0x1)==0x0) && ((U & 0x1)==0x1) && 1) return vsub_integer(req, res); + if(((A & 0xF)==0x8) && ((B & 0x1)==0x1) && ((U & 0x1)==0x0) && 1) return vtst(req, res); + if(((A & 0xF)==0x8) && ((B & 0x1)==0x1) && ((U & 0x1)==0x1) && 1) return vceq_register(req, res); + if(((A & 0xF)==0xB) && ((B & 0x1)==0x1) && ((U & 0x1)==0x0) && 1) return vpadd_integer(req, res); + if(((A & 0xF)==0xC) && ((B & 0x1)==0x1) && ((U & 0x1)==0x0) && 1) return vfma(req, res); + if(((A & 0xF)==0xD) && ((B & 0x1)==0x1) && ((U & 0x1)==0x0) && 1) return vmla_float(req, res); + if(((A & 0xF)==0xF) && ((B & 0x1)==0x0) && ((U & 0x1)==0x0) && 1) return vmax_vmin_float(req, res); + if(((A & 0xF)==0xB) && ((B & 0x1)==0x0) && ((U & 0x1)==0x0) && 1) return vqdmulh(req, res); + if(((A & 0xF)==0xB) && ((B & 0x1)==0x0) && ((U & 0x1)==0x1) && 1) return vqrdmulh(req, res); + if(((A & 0xF)==0xE) && ((B & 0x1)==0x1) && ((U & 0x1)==0x1) && 1) return vacge(req, res); + if(((A & 0xF)==0xF) && ((B & 0x1)==0x0) && ((U & 0x1)==0x1) && 1) return vpmax_float(req, res); + if(((A & 0xF)==0x0) && ((B & 0x1)==0x0) && 1) return vhadd(req, res); + if(((A & 0xF)==0x0) && ((B & 0x1)==0x1) && 1) return vqadd(req, res); + if(((A & 0xF)==0x1) && ((B & 0x1)==0x0) && 1) return vrhadd(req, res); + if(((A & 0xF)==0x2) && ((B & 0x1)==0x0) && 1) return vhsub(req, res); + if(((A & 0xF)==0x3) && ((B & 0x1)==0x0) && 1) return vcgt_register(req, res); + if(((A & 0xF)==0x3) && ((B & 0x1)==0x1) && 1) return vcge_register(req, res); + if(((A & 0xF)==0x2) && ((B & 0x1)==0x1) && 1) return vqsub(req, res); + if(((A & 0xF)==0x4) && ((B & 0x1)==0x0) && 1) return vshl_register(req, res); + if(((A & 0xF)==0x4) && ((B & 0x1)==0x1) && 1) return vqshl_register(req, res); + if(((A & 0xF)==0x5) && ((B & 0x1)==0x0) && 1) return vrshl(req, res); + if(((A & 0xF)==0x5) && ((B & 0x1)==0x1) && 1) return vqrshl(req, res); + if(((A & 0xF)==0x7) && ((B & 0x1)==0x0) && 1) return vabd_integer(req, res); + if(((A & 0xF)==0x7) && ((B & 0x1)==0x1) && 1) return vaba(req, res); + if(((A & 0xF)==0x9) && ((B & 0x1)==0x0) && 1) return vmla_integer(req, res); + if(((A & 0xF)==0x9) && ((B & 0x1)==0x1) && 1) return vmul_integer(req, res); + if(((A & 0xF)==0x6) && 1) return vmax_vmin_integer(req, res); + if(((A & 0xF)==0xA) && 1) return vpmax_integer(req, res); + if(1) return undefined(req, res); + return undefined(req, res); +} + +// gen_crc: 42C88A3F +int advsimd_two_reg_misc(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + uint32_t instr = req->instr_word32; + uint32_t A = (instr & 0x30000)>>16; + uint32_t B = (instr & 0x7C0)>>6; + if(((A & 0x3)==0x2) && ((B & 0x1F)==0x8)) return vmovn(req, res); + if(((A & 0x3)==0x2) && ((B & 0x1F)==0x9)) return vqmovn(req, res); + if(((A & 0x3)==0x2) && ((B & 0x1F)==0xC)) return vshll(req, res); + if(((A & 0x3)==0x0) && ((B & 0x1E)==0x4)) return vrev16(req, res); + if(((A & 0x3)==0x0) && ((B & 0x1E)==0x2)) return vrev32(req, res); + if(((A & 0x3)==0x0) && ((B & 0x1E)==0x0)) return vrev64(req, res); + if(((A & 0x3)==0x0) && ((B & 0x1E)==0x10)) return vcls(req, res); + if(((A & 0x3)==0x0) && ((B & 0x1E)==0x12)) return vclz(req, res); + if(((A & 0x3)==0x0) && ((B & 0x1E)==0x14)) return vcnt(req, res); + if(((A & 0x3)==0x0) && ((B & 0x1E)==0x16)) return vmvn(req, res); + if(((A & 0x3)==0x0) && ((B & 0x1E)==0x1C)) return vqabs(req, res); + if(((A & 0x3)==0x0) && ((B & 0x1E)==0x1E)) return vqneg(req, res); + if(((A & 0x3)==0x2) && ((B & 0x1E)==0x0)) return vswp(req, res); + if(((A & 0x3)==0x2) && ((B & 0x1E)==0x2)) return vtrn(req, res); + if(((A & 0x3)==0x2) && ((B & 0x1E)==0x4)) return vuzp(req, res); + if(((A & 0x3)==0x2) && ((B & 0x1E)==0x6)) return vzip(req, res); + if(((A & 0x3)==0x2) && ((B & 0x1E)==0xA)) return vqmovn(req, res); + if(((A & 0x3)==0x2) && ((B & 0x1B)==0x18)) return vcvt_half_single(req, res); + if(((A & 0x3)==0x0) && ((B & 0x1C)==0x8)) return vpaddl(req, res); + if(((A & 0x3)==0x0) && ((B & 0x1C)==0x18)) return vpadal(req, res); + if(((A & 0x3)==0x1) && ((B & 0xE)==0xC)) return vabs(req, res); + if(((A & 0x3)==0x1) && ((B & 0xE)==0xE)) return vneg(req, res); + if(((A & 0x3)==0x1) && ((B & 0xE)==0x0)) return vcgt_immediate(req, res); + if(((A & 0x3)==0x1) && ((B & 0xE)==0x2)) return vcge_immediate(req, res); + if(((A & 0x3)==0x1) && ((B & 0xE)==0x6)) return vcle_immediate(req, res); + if(((A & 0x3)==0x1) && ((B & 0xE)==0x8)) return vclt_immediate(req, res); + if(((A & 0x3)==0x1) && ((B & 0xE)==0x4)) return vceq_immediate(req, res); + if(((A & 0x3)==0x3) && ((B & 0x1A)==0x10)) return vrecpe(req, res); + if(((A & 0x3)==0x3) && ((B & 0x1A)==0x12)) return vrsqrte(req, res); + if(((A & 0x3)==0x3) && ((B & 0x18)==0x18)) return vcvt_float_int(req, res); + return undefined(req, res); +} + +// gen_crc: 8BAAD39C +int advsimd_two_reg_scalar(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + uint32_t instr = req->instr_word32; + uint32_t U = (instr & 0x10000000)>>28; + uint32_t B = (instr & 0x300000)>>20; + uint32_t A = (instr & 0xF00)>>8; + if(((A & 0xF)==0xB) && ((U & 0x1)==0x0)) return vqdmull(req, res); + if(((A & 0xB)==0x3) && ((U & 0x1)==0x0)) return vqdmlal(req, res); + if(((A & 0xF)==0xA) && 1) return vmul_scalar(req, res); + if(((A & 0xF)==0xC) && 1) return vqdmulh(req, res); + if(((A & 0xF)==0xD) && 1) return vqrdmulh(req, res); + if(((A & 0xB)==0x2) && 1) return vmla_scalar(req, res); + if(((A & 0xE)==0x8) && 1) return vmul_scalar(req, res); + if(((A & 0xA)==0x0) && 1) return vmla_scalar(req, res); + if(1) return undefined(req, res); + return undefined(req, res); +} + +// gen_crc: 1469CE4F +int advsimd_two_reg_shift(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + uint32_t instr = req->instr_word32; + uint32_t U = (instr & 0x10000000)>>28; + uint32_t imm3 = (instr & 0x380000)>>19; + uint32_t A = (instr & 0xF00)>>8; + uint32_t L = (instr & 0x80)>>7; + uint32_t B = (instr & 0x40)>>6; + if(((A & 0xF)==0x8) && ((U & 0x1)==0x0) && ((B & 0x1)==0x0) && ((L & 0x1)==0x0)) return vshrn(req, res); + if(((A & 0xF)==0x8) && ((U & 0x1)==0x0) && ((B & 0x1)==0x1) && ((L & 0x1)==0x0)) return vrshrn(req, res); + if(((A & 0xF)==0x8) && ((U & 0x1)==0x1) && ((B & 0x1)==0x0) && ((L & 0x1)==0x0)) return vqshrn(req, res); + if(((A & 0xF)==0x8) && ((U & 0x1)==0x1) && ((B & 0x1)==0x1) && ((L & 0x1)==0x0)) return vqrshrn(req, res); + if(((A & 0xF)==0xA) && ((B & 0x1)==0x0) && ((L & 0x1)==0x0) && 1) return vshll(req, res); + if(((A & 0xF)==0xA) && ((B & 0x1)==0x0) && ((L & 0x1)==0x0) && 1) return vmovl(req, res); + if(((A & 0xF)==0x9) && ((B & 0x1)==0x0) && ((L & 0x1)==0x0) && 1) return vqshrn(req, res); + if(((A & 0xF)==0x9) && ((B & 0x1)==0x1) && ((L & 0x1)==0x0) && 1) return vqrshrn(req, res); + if(((A & 0xF)==0x4) && ((U & 0x1)==0x1) && 1) return vsri(req, res); + if(((A & 0xF)==0x5) && ((U & 0x1)==0x0) && 1) return vshl_immediate(req, res); + if(((A & 0xF)==0x5) && ((U & 0x1)==0x1) && 1) return vsli(req, res); + if(((A & 0xF)==0x0) && 1) return vshr(req, res); + if(((A & 0xF)==0x1) && 1) return vsra(req, res); + if(((A & 0xF)==0x2) && 1) return vrshr(req, res); + if(((A & 0xF)==0x3) && 1) return vrsra(req, res); + if(((A & 0xE)==0xE) && ((L & 0x1)==0x0) && 1) return vcvt_float_fixed(req, res); + if(((A & 0xE)==0x6) && 1) return vqshl_immediate(req, res); + if(1) return undefined(req, res); + return undefined(req, res); +} + +// gen_crc: 83FD8DE8 +int and_immediate(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + /* Encoding T1 */ + /* pattern="11110,i.1,0,0000,S.1,Rn.4,0,imm3.3,Rd.4,imm8.8" width=32 stringency=13 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFBE08000)==0xF0000000)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ARMv6T2) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_i] = (instr & 0x4000000)>>26; + res->fields_mask[FIELD_i >> 6] |= 1LL << (FIELD_i & 63); + char i_width = 1; + res->fields[FIELD_S] = (instr & 0x100000)>>20; + res->fields_mask[FIELD_S >> 6] |= 1LL << (FIELD_S & 63); + char S_width = 1; + res->fields[FIELD_Rn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Rn >> 6] |= 1LL << (FIELD_Rn & 63); + char Rn_width = 4; + res->fields[FIELD_imm3] = (instr & 0x7000)>>12; + res->fields_mask[FIELD_imm3 >> 6] |= 1LL << (FIELD_imm3 & 63); + char imm3_width = 3; + res->fields[FIELD_Rd] = (instr & 0xF00)>>8; + res->fields_mask[FIELD_Rd >> 6] |= 1LL << (FIELD_Rd & 63); + char Rd_width = 4; + res->fields[FIELD_imm8] = instr & 0xFF; + res->fields_mask[FIELD_imm8 >> 6] |= 1LL << (FIELD_imm8 & 63); + char imm8_width = 8; + + static const instruction_format instr_formats[] = + { + { /* AND{S}<c> <Rd>,<Rn>,#<imm32> */ + "and", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_OPTIONAL_STATUS, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rd,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rn,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_IMM,FIELD_imm32,FIELD_UNINIT,"#","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_AND; + + /* pcode: if Rd == '1111' && S == '1' then SEE TST (immediate) */ + if(((res->fields[FIELD_Rd]) == (0xF)) && ((res->fields[FIELD_S]) == (0x1))) { + + return tst_immediate(req, res); + } + /* pcode: d = UInt(Rd) */ + res->fields[FIELD_d] = (res->fields[FIELD_Rd]); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: n = UInt(Rn) */ + res->fields[FIELD_n] = (res->fields[FIELD_Rn]); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: setflags = (S == '1') */ + res->fields[FIELD_setflags] = ((res->fields[FIELD_S]) == (0x1)); + res->fields_mask[FIELD_setflags >> 6] |= 1LL << (FIELD_setflags & 63); + /* pcode: (imm32, carry) = ThumbExpandImm_C(i:imm3:imm8, APSR.C) */ + res->fields[FIELD_imm32] = ThumbExpandImm_C_imm32((res->fields[FIELD_i]<<(8+3))|(res->fields[FIELD_imm3]<<8)|(res->fields[FIELD_imm8]), res->fields[FIELD_APSR_C]); + res->fields_mask[FIELD_imm32 >> 6] |= 1LL << (FIELD_imm32 & 63); + res->fields[FIELD_carry] = ThumbExpandImm_C_cout((res->fields[FIELD_i]<<(8+3))|(res->fields[FIELD_imm3]<<8)|(res->fields[FIELD_imm8]), res->fields[FIELD_APSR_C]); + res->fields_mask[FIELD_carry >> 6] |= 1LL << (FIELD_carry & 63); + /* TODO: handle ThumbExpandImm_C's possible setting of UNPREDICTABLE */ while(0); + /* pcode: if BadReg(d) || BadReg(n) then UNPREDICTABLE */ + if((BadReg(res->fields[FIELD_d])) || (BadReg(res->fields[FIELD_n]))) { + res->flags |= FLAG_UNPREDICTABLE; + } + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: 9DB6B145 +int and_register(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + /* Encoding T1 */ + /* pattern="010000,0000,Rm.3,Rdn.3" width=16 stringency=10 */ + { + uint16_t instr = req->instr_word16; + if(((instr & 0xFFC0)==0x4000)) { + res->instrSize = 16; + if(!(req->arch & ARCH_ARMv4T) && !(req->arch & ARCH_ARMv5T) && !(req->arch & ARCH_ARMv6) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_Rm] = (instr & 0x38)>>3; + res->fields_mask[FIELD_Rm >> 6] |= 1LL << (FIELD_Rm & 63); + char Rm_width = 3; + res->fields[FIELD_Rdn] = instr & 0x7; + res->fields_mask[FIELD_Rdn >> 6] |= 1LL << (FIELD_Rdn & 63); + char Rdn_width = 3; + + static const instruction_format instr_formats[] = + { + { /* ANDS <Rdn>,<Rm> */ + "ands", /* .operation (const char *) */ + 0, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rdn,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rm,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + { /* AND<c> <Rdn>,<Rm> */ + "and", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rdn,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rm,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 2; + res->mnem = armv7::ARMV7_ANDS; + + /* pcode: d = UInt(Rdn) */ + res->fields[FIELD_d] = (res->fields[FIELD_Rdn]); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: n = UInt(Rdn) */ + res->fields[FIELD_n] = (res->fields[FIELD_Rdn]); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: m = UInt(Rm) */ + res->fields[FIELD_m] = (res->fields[FIELD_Rm]); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + /* pcode: setflags = !InITBlock() */ + res->fields[FIELD_setflags] = !(req->inIfThen == IFTHEN_YES); + res->fields_mask[FIELD_setflags >> 6] |= 1LL << (FIELD_setflags & 63); + /* pcode: (shift_t, shift_n) = (SRType_LSL, 0) */ + res->fields[FIELD_shift_t] = 0; + res->fields_mask[FIELD_shift_t >> 6] |= 1LL << (FIELD_shift_t & 63); + res->fields[FIELD_shift_n] = 0; + res->fields_mask[FIELD_shift_n >> 6] |= 1LL << (FIELD_shift_n & 63); + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* Encoding T2 */ + /* pattern="11101,01,0000,S.1,Rn.4,(0),imm3.3,Rd.4,imm2.2,type.2,Rm.4" width=32 stringency=13 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFFE00000)==0xEA000000)) { + res->instrSize = 32; + if(!((instr & 0x8000)==0x0)) { + res->flags |= FLAG_UNPREDICTABLE; + } + if(!(req->arch & ARCH_ARMv6T2) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_S] = (instr & 0x100000)>>20; + res->fields_mask[FIELD_S >> 6] |= 1LL << (FIELD_S & 63); + char S_width = 1; + res->fields[FIELD_Rn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Rn >> 6] |= 1LL << (FIELD_Rn & 63); + char Rn_width = 4; + res->fields[FIELD_imm3] = (instr & 0x7000)>>12; + res->fields_mask[FIELD_imm3 >> 6] |= 1LL << (FIELD_imm3 & 63); + char imm3_width = 3; + res->fields[FIELD_Rd] = (instr & 0xF00)>>8; + res->fields_mask[FIELD_Rd >> 6] |= 1LL << (FIELD_Rd & 63); + char Rd_width = 4; + res->fields[FIELD_imm2] = (instr & 0xC0)>>6; + res->fields_mask[FIELD_imm2 >> 6] |= 1LL << (FIELD_imm2 & 63); + char imm2_width = 2; + res->fields[FIELD_type] = (instr & 0x30)>>4; + res->fields_mask[FIELD_type >> 6] |= 1LL << (FIELD_type & 63); + char type_width = 2; + res->fields[FIELD_Rm] = instr & 0xF; + res->fields_mask[FIELD_Rm >> 6] |= 1LL << (FIELD_Rm & 63); + char Rm_width = 4; + + static const instruction_format instr_formats[] = + { + { /* AND{S}<c> <Rd>,<Rn>,<Rm>{,<shift>} */ + "and", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_OPTIONAL_STATUS, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rd,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rn,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rm,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_SHIFT,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 4 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_AND; + + /* pcode: d = UInt(Rd) */ + res->fields[FIELD_d] = (res->fields[FIELD_Rd]); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: n = UInt(Rn) */ + res->fields[FIELD_n] = (res->fields[FIELD_Rn]); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: m = UInt(Rm) */ + res->fields[FIELD_m] = (res->fields[FIELD_Rm]); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + /* pcode: setflags = (S == '1') */ + res->fields[FIELD_setflags] = ((res->fields[FIELD_S]) == (0x1)); + res->fields_mask[FIELD_setflags >> 6] |= 1LL << (FIELD_setflags & 63); + /* pcode: (shift_t, shift_n) = DecodeImmShift(type, imm3:imm2) */ + res->fields[FIELD_shift_t] = DecodeImmShift_shift_t(res->fields[FIELD_type], (res->fields[FIELD_imm3]<<2)|(res->fields[FIELD_imm2])); + res->fields_mask[FIELD_shift_t >> 6] |= 1LL << (FIELD_shift_t & 63); + res->fields[FIELD_shift_n] = DecodeImmShift_shift_n(res->fields[FIELD_type], (res->fields[FIELD_imm3]<<2)|(res->fields[FIELD_imm2])); + res->fields_mask[FIELD_shift_n >> 6] |= 1LL << (FIELD_shift_n & 63); + /* pcode: if BadReg(d) || BadReg(n) || BadReg(m) then UNPREDICTABLE */ + if(((BadReg(res->fields[FIELD_d])) || (BadReg(res->fields[FIELD_n]))) || (BadReg(res->fields[FIELD_m]))) { + res->flags |= FLAG_UNPREDICTABLE; + } + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: A6FBE861 +int asr_immediate(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + /* Encoding T1 */ + /* pattern="000,10,imm5.5,Rm.3,Rd.3" width=16 stringency=5 */ + { + uint16_t instr = req->instr_word16; + if(((instr & 0xF800)==0x1000)) { + res->instrSize = 16; + if(!(req->arch & ARCH_ARMv4T) && !(req->arch & ARCH_ARMv5T) && !(req->arch & ARCH_ARMv6) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_imm5] = (instr & 0x7C0)>>6; + res->fields_mask[FIELD_imm5 >> 6] |= 1LL << (FIELD_imm5 & 63); + char imm5_width = 5; + res->fields[FIELD_Rm] = (instr & 0x38)>>3; + res->fields_mask[FIELD_Rm >> 6] |= 1LL << (FIELD_Rm & 63); + char Rm_width = 3; + res->fields[FIELD_Rd] = instr & 0x7; + res->fields_mask[FIELD_Rd >> 6] |= 1LL << (FIELD_Rd & 63); + char Rd_width = 3; + + static const instruction_format instr_formats[] = + { + { /* ASRS <Rd>,<Rm>,#<shift_n> */ + "asrs", /* .operation (const char *) */ + 0, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rd,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rm,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_IMM,FIELD_shift_n,FIELD_UNINIT,"#","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + { /* ASR<c> <Rd>,<Rm>,#<shift_n> */ + "asr", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rd,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rm,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_IMM,FIELD_shift_n,FIELD_UNINIT,"#","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 2; + res->mnem = armv7::ARMV7_ASRS; + + /* pcode: d = UInt(Rd) */ + res->fields[FIELD_d] = (res->fields[FIELD_Rd]); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: m = UInt(Rm) */ + res->fields[FIELD_m] = (res->fields[FIELD_Rm]); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + /* pcode: setflags = !InITBlock() */ + res->fields[FIELD_setflags] = !(req->inIfThen == IFTHEN_YES); + res->fields_mask[FIELD_setflags >> 6] |= 1LL << (FIELD_setflags & 63); + /* pcode: (-, shift_n) = DecodeImmShift('10', imm5) */ + res->fields[FIELD_shift_n] = DecodeImmShift_shift_n(0x2, res->fields[FIELD_imm5]); + res->fields_mask[FIELD_shift_n >> 6] |= 1LL << (FIELD_shift_n & 63); + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* Encoding T2 */ + /* pattern="11101,01,0010,S.1,1111,(0),imm3.3,Rd.4,imm2.2,10,Rm.4" width=32 stringency=19 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFFEF0030)==0xEA4F0020)) { + res->instrSize = 32; + if(!((instr & 0x8000)==0x0)) { + res->flags |= FLAG_UNPREDICTABLE; + } + if(!(req->arch & ARCH_ARMv6T2) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_S] = (instr & 0x100000)>>20; + res->fields_mask[FIELD_S >> 6] |= 1LL << (FIELD_S & 63); + char S_width = 1; + res->fields[FIELD_imm3] = (instr & 0x7000)>>12; + res->fields_mask[FIELD_imm3 >> 6] |= 1LL << (FIELD_imm3 & 63); + char imm3_width = 3; + res->fields[FIELD_Rd] = (instr & 0xF00)>>8; + res->fields_mask[FIELD_Rd >> 6] |= 1LL << (FIELD_Rd & 63); + char Rd_width = 4; + res->fields[FIELD_imm2] = (instr & 0xC0)>>6; + res->fields_mask[FIELD_imm2 >> 6] |= 1LL << (FIELD_imm2 & 63); + char imm2_width = 2; + res->fields[FIELD_Rm] = instr & 0xF; + res->fields_mask[FIELD_Rm >> 6] |= 1LL << (FIELD_Rm & 63); + char Rm_width = 4; + + static const instruction_format instr_formats[] = + { + { /* ASR{S}<c> <Rd>,<Rm>,#<shift_n> */ + "asr", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_OPTIONAL_STATUS, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rd,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rm,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_IMM,FIELD_shift_n,FIELD_UNINIT,"#","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_ASR; + + /* pcode: d = UInt(Rd) */ + res->fields[FIELD_d] = (res->fields[FIELD_Rd]); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: m = UInt(Rm) */ + res->fields[FIELD_m] = (res->fields[FIELD_Rm]); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + /* pcode: setflags = (S == '1') */ + res->fields[FIELD_setflags] = ((res->fields[FIELD_S]) == (0x1)); + res->fields_mask[FIELD_setflags >> 6] |= 1LL << (FIELD_setflags & 63); + /* pcode: (-, shift_n) = DecodeImmShift('10', imm3:imm2) */ + res->fields[FIELD_shift_n] = DecodeImmShift_shift_n(0x2, (res->fields[FIELD_imm3]<<2)|(res->fields[FIELD_imm2])); + res->fields_mask[FIELD_shift_n >> 6] |= 1LL << (FIELD_shift_n & 63); + /* pcode: if BadReg(d) || BadReg(m) then UNPREDICTABLE */ + if((BadReg(res->fields[FIELD_d])) || (BadReg(res->fields[FIELD_m]))) { + res->flags |= FLAG_UNPREDICTABLE; + } + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: 0533CBD6 +int asr_register(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + /* Encoding T1 */ + /* pattern="010000,0100,Rm.3,Rdn.3" width=16 stringency=10 */ + { + uint16_t instr = req->instr_word16; + if(((instr & 0xFFC0)==0x4100)) { + res->instrSize = 16; + if(!(req->arch & ARCH_ARMv4T) && !(req->arch & ARCH_ARMv5T) && !(req->arch & ARCH_ARMv6) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_Rm] = (instr & 0x38)>>3; + res->fields_mask[FIELD_Rm >> 6] |= 1LL << (FIELD_Rm & 63); + char Rm_width = 3; + res->fields[FIELD_Rdn] = instr & 0x7; + res->fields_mask[FIELD_Rdn >> 6] |= 1LL << (FIELD_Rdn & 63); + char Rdn_width = 3; + + static const instruction_format instr_formats[] = + { + { /* ASRS <Rdn>,<Rm> */ + "asrs", /* .operation (const char *) */ + 0, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rdn,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rm,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + { /* ASR<c> <Rdn>,<Rm> */ + "asr", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rdn,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rm,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 2; + res->mnem = armv7::ARMV7_ASRS; + + /* pcode: d = UInt(Rdn) */ + res->fields[FIELD_d] = (res->fields[FIELD_Rdn]); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: n = UInt(Rdn) */ + res->fields[FIELD_n] = (res->fields[FIELD_Rdn]); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: m = UInt(Rm) */ + res->fields[FIELD_m] = (res->fields[FIELD_Rm]); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + /* pcode: setflags = !InITBlock() */ + res->fields[FIELD_setflags] = !(req->inIfThen == IFTHEN_YES); + res->fields_mask[FIELD_setflags >> 6] |= 1LL << (FIELD_setflags & 63); + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* Encoding T2 */ + /* pattern="11111,010,0,10,S.1,Rn.4,1111,Rd.4,0,000,Rm.4" width=32 stringency=20 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFFE0F0F0)==0xFA40F000)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ARMv6T2) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_S] = (instr & 0x100000)>>20; + res->fields_mask[FIELD_S >> 6] |= 1LL << (FIELD_S & 63); + char S_width = 1; + res->fields[FIELD_Rn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Rn >> 6] |= 1LL << (FIELD_Rn & 63); + char Rn_width = 4; + res->fields[FIELD_Rd] = (instr & 0xF00)>>8; + res->fields_mask[FIELD_Rd >> 6] |= 1LL << (FIELD_Rd & 63); + char Rd_width = 4; + res->fields[FIELD_Rm] = instr & 0xF; + res->fields_mask[FIELD_Rm >> 6] |= 1LL << (FIELD_Rm & 63); + char Rm_width = 4; + + static const instruction_format instr_formats[] = + { + { /* ASR{S}<c> <Rd>,<Rn>,<Rm> */ + "asr", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_OPTIONAL_STATUS, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rd,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rn,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rm,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_ASR; + + /* pcode: d = UInt(Rd) */ + res->fields[FIELD_d] = (res->fields[FIELD_Rd]); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: n = UInt(Rn) */ + res->fields[FIELD_n] = (res->fields[FIELD_Rn]); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: m = UInt(Rm) */ + res->fields[FIELD_m] = (res->fields[FIELD_Rm]); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + /* pcode: setflags = (S == '1') */ + res->fields[FIELD_setflags] = ((res->fields[FIELD_S]) == (0x1)); + res->fields_mask[FIELD_setflags >> 6] |= 1LL << (FIELD_setflags & 63); + /* pcode: if BadReg(d) || BadReg(n) || BadReg(m) then UNPREDICTABLE */ + if(((BadReg(res->fields[FIELD_d])) || (BadReg(res->fields[FIELD_n]))) || (BadReg(res->fields[FIELD_m]))) { + res->flags |= FLAG_UNPREDICTABLE; + } + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: BF25CCBB +int b(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + /* Encoding T1 */ + /* pattern="1101,cond.4,imm8.8" width=16 stringency=4 */ + { + uint16_t instr = req->instr_word16; + if(((instr & 0xF000)==0xD000)) { + res->instrSize = 16; + if(!(req->arch & ARCH_ARMv4T) && !(req->arch & ARCH_ARMv5T) && !(req->arch & ARCH_ARMv6) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = (instr & 0xF00)>>8; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + char cond_width = 4; + res->fields[FIELD_imm8] = instr & 0xFF; + res->fields_mask[FIELD_imm8 >> 6] |= 1LL << (FIELD_imm8 & 63); + char imm8_width = 8; + + static const instruction_format instr_formats[] = + { + { /* B<c> #<imm32> */ + "b", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_IMM,FIELD_imm32,FIELD_UNINIT,"#","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 1 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_B; + + /* pcode: if cond == '1110' then UNDEFINED */ + if((res->fields[FIELD_cond]) == (0xE)) { + res->status |= STATUS_UNDEFINED; + } + /* pcode: if cond == '1111' then SEE SVC */ + if((res->fields[FIELD_cond]) == (0xF)) { + + return svc(req, res); + } + /* pcode: imm32 = SignExtend(imm8:'0', 32) */ + res->fields[FIELD_imm32] = SignExtend((res->fields[FIELD_imm8]<<1)|(0x0),1+8); + res->fields_mask[FIELD_imm32 >> 6] |= 1LL << (FIELD_imm32 & 63); + /* pcode: if InITBlock() then UNPREDICTABLE */ + if(req->inIfThen == IFTHEN_YES) { + res->flags |= FLAG_UNPREDICTABLE; + } + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* Encoding T2 */ + /* pattern="11100,imm11.11" width=16 stringency=9 */ + { + uint16_t instr = req->instr_word16; + if(((instr & 0xF800)==0xE000)) { + res->instrSize = 16; + if(!(req->arch & ARCH_ARMv4T) && !(req->arch & ARCH_ARMv5T) && !(req->arch & ARCH_ARMv6) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_imm11] = instr & 0x7FF; + res->fields_mask[FIELD_imm11 >> 6] |= 1LL << (FIELD_imm11 & 63); + char imm11_width = 11; + + static const instruction_format instr_formats[] = + { + { /* B<c> #<imm32> */ + "b", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_IMM,FIELD_imm32,FIELD_UNINIT,"#","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 1 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_B; + + /* pcode: imm32 = SignExtend(imm11:'0', 32) */ + res->fields[FIELD_imm32] = SignExtend((res->fields[FIELD_imm11]<<1)|(0x0),1+11); + res->fields_mask[FIELD_imm32 >> 6] |= 1LL << (FIELD_imm32 & 63); + /* pcode: if InITBlock() && !LastInITBlock() then UNPREDICTABLE */ + if((req->inIfThen == IFTHEN_YES) && (!(req->inIfThenLast == IFTHENLAST_YES))) { + res->flags |= FLAG_UNPREDICTABLE; + } + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* Encoding T3 */ + /* pattern="11110,S.1,cond.4,imm6.6,10,J1.1,0,K1.1,imm11.11" width=32 stringency=17 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xF800D000)==0xF0008000)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ARMv6T2) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_S] = (instr & 0x4000000)>>26; + res->fields_mask[FIELD_S >> 6] |= 1LL << (FIELD_S & 63); + char S_width = 1; + res->fields[FIELD_cond] = (instr & 0x3C00000)>>22; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + char cond_width = 4; + res->fields[FIELD_imm6] = (instr & 0x3F0000)>>16; + res->fields_mask[FIELD_imm6 >> 6] |= 1LL << (FIELD_imm6 & 63); + char imm6_width = 6; + res->fields[FIELD_J1] = (instr & 0x2000)>>13; + res->fields_mask[FIELD_J1 >> 6] |= 1LL << (FIELD_J1 & 63); + char J1_width = 1; + res->fields[FIELD_K1] = (instr & 0x800)>>11; + res->fields_mask[FIELD_K1 >> 6] |= 1LL << (FIELD_K1 & 63); + char K1_width = 1; + res->fields[FIELD_imm11] = instr & 0x7FF; + res->fields_mask[FIELD_imm11 >> 6] |= 1LL << (FIELD_imm11 & 63); + char imm11_width = 11; + + static const instruction_format instr_formats[] = + { + { /* B<c> #<imm32> */ + "b", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_IMM,FIELD_imm32,FIELD_UNINIT,"#","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 1 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_B; + + /* pcode: imm32 = SignExtend(S:K1:J1:imm6:imm11:'0', 32) */ + res->fields[FIELD_imm32] = SignExtend((res->fields[FIELD_S]<<(1+11+6+1+1))|(res->fields[FIELD_K1]<<(1+11+6+1))|(res->fields[FIELD_J1]<<(1+11+6))|(res->fields[FIELD_imm6]<<(1+11))|(res->fields[FIELD_imm11]<<1)|(0x0),1+11+6+1+1+S_width); + res->fields_mask[FIELD_imm32 >> 6] |= 1LL << (FIELD_imm32 & 63); + /* pcode: if InITBlock() then UNPREDICTABLE */ + if(req->inIfThen == IFTHEN_YES) { + res->flags |= FLAG_UNPREDICTABLE; + } + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* Encoding T4 */ + /* pattern="11110,S.1,imm10.10,10,J1.1,1,K1.1,imm11.11" width=32 stringency=21 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xF800D000)==0xF0009000)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ARMv6T2) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_S] = (instr & 0x4000000)>>26; + res->fields_mask[FIELD_S >> 6] |= 1LL << (FIELD_S & 63); + char S_width = 1; + res->fields[FIELD_imm10] = (instr & 0x3FF0000)>>16; + res->fields_mask[FIELD_imm10 >> 6] |= 1LL << (FIELD_imm10 & 63); + char imm10_width = 10; + res->fields[FIELD_J1] = (instr & 0x2000)>>13; + res->fields_mask[FIELD_J1 >> 6] |= 1LL << (FIELD_J1 & 63); + char J1_width = 1; + res->fields[FIELD_K1] = (instr & 0x800)>>11; + res->fields_mask[FIELD_K1 >> 6] |= 1LL << (FIELD_K1 & 63); + char K1_width = 1; + res->fields[FIELD_imm11] = instr & 0x7FF; + res->fields_mask[FIELD_imm11 >> 6] |= 1LL << (FIELD_imm11 & 63); + char imm11_width = 11; + + static const instruction_format instr_formats[] = + { + { /* B<c> #<imm32> */ + "b", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_IMM,FIELD_imm32,FIELD_UNINIT,"#","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 1 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_B; + + /* pcode: I1 = NOT(J1 EOR S) */ + res->fields[FIELD_I1] = (~((res->fields[FIELD_J1]) ^ (res->fields[FIELD_S])) & 1); + res->fields_mask[FIELD_I1 >> 6] |= 1LL << (FIELD_I1 & 63); + /* pcode: X1 = NOT(K1 EOR S) */ + res->fields[FIELD_X1] = (~((res->fields[FIELD_K1]) ^ (res->fields[FIELD_S])) & 1); + res->fields_mask[FIELD_X1 >> 6] |= 1LL << (FIELD_X1 & 63); + /* pcode: imm32 = SignExtend(S:I1:X1:imm10:imm11:'0', 32) */ + res->fields[FIELD_imm32] = SignExtend((res->fields[FIELD_S]<<(1+11+10+1+1))|(res->fields[FIELD_I1]<<(1+11+10+1))|(res->fields[FIELD_X1]<<(1+11+10))|(res->fields[FIELD_imm10]<<(1+11))|(res->fields[FIELD_imm11]<<1)|(0x0),1+11+10+1+1+S_width); + res->fields_mask[FIELD_imm32 >> 6] |= 1LL << (FIELD_imm32 & 63); + /* pcode: if InITBlock() && !LastInITBlock() then UNPREDICTABLE */ + if((req->inIfThen == IFTHEN_YES) && (!(req->inIfThenLast == IFTHENLAST_YES))) { + res->flags |= FLAG_UNPREDICTABLE; + } + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: CC97D1F3 +int bfc(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + /* Encoding T1 */ + /* pattern="11110,(0),11,011,0,1111,0,imm3.3,Rd.4,imm2.2,(0),msb.5" width=32 stringency=18 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFBFF8000)==0xF36F0000)) { + res->instrSize = 32; + if(!((instr & 0x4000020)==0x0)) { + res->flags |= FLAG_UNPREDICTABLE; + } + if(!(req->arch & ARCH_ARMv6T2) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_imm3] = (instr & 0x7000)>>12; + res->fields_mask[FIELD_imm3 >> 6] |= 1LL << (FIELD_imm3 & 63); + char imm3_width = 3; + res->fields[FIELD_Rd] = (instr & 0xF00)>>8; + res->fields_mask[FIELD_Rd >> 6] |= 1LL << (FIELD_Rd & 63); + char Rd_width = 4; + res->fields[FIELD_imm2] = (instr & 0xC0)>>6; + res->fields_mask[FIELD_imm2 >> 6] |= 1LL << (FIELD_imm2 & 63); + char imm2_width = 2; + res->fields[FIELD_msb] = instr & 0x1F; + res->fields_mask[FIELD_msb >> 6] |= 1LL << (FIELD_msb & 63); + char msb_width = 5; + + static const instruction_format instr_formats[] = + { + { /* BFC<c> <Rd>,#<lsbit>,#<width> */ + "bfc", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rd,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_IMM,FIELD_lsbit,FIELD_UNINIT,"#","",WRITEBACK_NO}, + {OPERAND_FORMAT_IMM,FIELD_width,FIELD_UNINIT,"#","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_BFC; + + /* pcode: d = UInt(Rd) */ + res->fields[FIELD_d] = (res->fields[FIELD_Rd]); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: msbit = UInt(msb) */ + res->fields[FIELD_msbit] = (res->fields[FIELD_msb]); + res->fields_mask[FIELD_msbit >> 6] |= 1LL << (FIELD_msbit & 63); + /* pcode: lsbit = UInt(imm3:imm2) */ + res->fields[FIELD_lsbit] = ((res->fields[FIELD_imm3]<<2)|(res->fields[FIELD_imm2])); + res->fields_mask[FIELD_lsbit >> 6] |= 1LL << (FIELD_lsbit & 63); + /* pcode: width=msbit-lsbit+1 */ + res->fields[FIELD_width] = ((res->fields[FIELD_msbit]) - (res->fields[FIELD_lsbit])) + (1); + res->fields_mask[FIELD_width >> 6] |= 1LL << (FIELD_width & 63); + /* pcode: if BadReg(d) then UNPREDICTABLE */ + if(BadReg(res->fields[FIELD_d])) { + res->flags |= FLAG_UNPREDICTABLE; + } + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: 0BBEF6F8 +int bfi(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + /* Encoding T1 */ + /* pattern="11110,(0),11,011,0,Rn.4,0,imm3.3,Rd.4,imm2.2,(0),msb.5" width=32 stringency=14 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFBF08000)==0xF3600000)) { + res->instrSize = 32; + if(!((instr & 0x4000020)==0x0)) { + res->flags |= FLAG_UNPREDICTABLE; + } + if(!(req->arch & ARCH_ARMv6T2) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_Rn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Rn >> 6] |= 1LL << (FIELD_Rn & 63); + char Rn_width = 4; + res->fields[FIELD_imm3] = (instr & 0x7000)>>12; + res->fields_mask[FIELD_imm3 >> 6] |= 1LL << (FIELD_imm3 & 63); + char imm3_width = 3; + res->fields[FIELD_Rd] = (instr & 0xF00)>>8; + res->fields_mask[FIELD_Rd >> 6] |= 1LL << (FIELD_Rd & 63); + char Rd_width = 4; + res->fields[FIELD_imm2] = (instr & 0xC0)>>6; + res->fields_mask[FIELD_imm2 >> 6] |= 1LL << (FIELD_imm2 & 63); + char imm2_width = 2; + res->fields[FIELD_msb] = instr & 0x1F; + res->fields_mask[FIELD_msb >> 6] |= 1LL << (FIELD_msb & 63); + char msb_width = 5; + + static const instruction_format instr_formats[] = + { + { /* BFI<c> <Rd>,<Rn>,#<lsbit>,#<width> */ + "bfi", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rd,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rn,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_IMM,FIELD_lsbit,FIELD_UNINIT,"#","",WRITEBACK_NO}, + {OPERAND_FORMAT_IMM,FIELD_width,FIELD_UNINIT,"#","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 4 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_BFI; + + /* pcode: if Rn == '1111' then SEE BFC */ + if((res->fields[FIELD_Rn]) == (0xF)) { + + return bfc(req, res); + } + /* pcode: d = UInt(Rd) */ + res->fields[FIELD_d] = (res->fields[FIELD_Rd]); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: n = UInt(Rn) */ + res->fields[FIELD_n] = (res->fields[FIELD_Rn]); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: msbit = UInt(msb) */ + res->fields[FIELD_msbit] = (res->fields[FIELD_msb]); + res->fields_mask[FIELD_msbit >> 6] |= 1LL << (FIELD_msbit & 63); + /* pcode: lsbit = UInt(imm3:imm2) */ + res->fields[FIELD_lsbit] = ((res->fields[FIELD_imm3]<<2)|(res->fields[FIELD_imm2])); + res->fields_mask[FIELD_lsbit >> 6] |= 1LL << (FIELD_lsbit & 63); + /* pcode: width=msbit - lsbit + 1 */ + res->fields[FIELD_width] = ((res->fields[FIELD_msbit]) - (res->fields[FIELD_lsbit])) + (1); + res->fields_mask[FIELD_width >> 6] |= 1LL << (FIELD_width & 63); + /* pcode: if BadReg(d) || n == 13 then UNPREDICTABLE */ + if((BadReg(res->fields[FIELD_d])) || ((res->fields[FIELD_n]) == (13))) { + res->flags |= FLAG_UNPREDICTABLE; + } + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: 8BD0C25F +int bic_immediate(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + /* Encoding T1 */ + /* pattern="11110,i.1,0,0001,S.1,Rn.4,0,imm3.3,Rd.4,imm8.8" width=32 stringency=13 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFBE08000)==0xF0200000)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ARMv6T2) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_i] = (instr & 0x4000000)>>26; + res->fields_mask[FIELD_i >> 6] |= 1LL << (FIELD_i & 63); + char i_width = 1; + res->fields[FIELD_S] = (instr & 0x100000)>>20; + res->fields_mask[FIELD_S >> 6] |= 1LL << (FIELD_S & 63); + char S_width = 1; + res->fields[FIELD_Rn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Rn >> 6] |= 1LL << (FIELD_Rn & 63); + char Rn_width = 4; + res->fields[FIELD_imm3] = (instr & 0x7000)>>12; + res->fields_mask[FIELD_imm3 >> 6] |= 1LL << (FIELD_imm3 & 63); + char imm3_width = 3; + res->fields[FIELD_Rd] = (instr & 0xF00)>>8; + res->fields_mask[FIELD_Rd >> 6] |= 1LL << (FIELD_Rd & 63); + char Rd_width = 4; + res->fields[FIELD_imm8] = instr & 0xFF; + res->fields_mask[FIELD_imm8 >> 6] |= 1LL << (FIELD_imm8 & 63); + char imm8_width = 8; + + static const instruction_format instr_formats[] = + { + { /* BIC{S}<c> <Rd>,<Rn>,#<imm32> */ + "bic", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_OPTIONAL_STATUS, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rd,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rn,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_IMM,FIELD_imm32,FIELD_UNINIT,"#","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_BIC; + + /* pcode: d = UInt(Rd) */ + res->fields[FIELD_d] = (res->fields[FIELD_Rd]); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: n = UInt(Rn) */ + res->fields[FIELD_n] = (res->fields[FIELD_Rn]); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: setflags = (S == '1') */ + res->fields[FIELD_setflags] = ((res->fields[FIELD_S]) == (0x1)); + res->fields_mask[FIELD_setflags >> 6] |= 1LL << (FIELD_setflags & 63); + /* pcode: (imm32, carry) = ThumbExpandImm_C(i:imm3:imm8, APSR.C) */ + res->fields[FIELD_imm32] = ThumbExpandImm_C_imm32((res->fields[FIELD_i]<<(8+3))|(res->fields[FIELD_imm3]<<8)|(res->fields[FIELD_imm8]), res->fields[FIELD_APSR_C]); + res->fields_mask[FIELD_imm32 >> 6] |= 1LL << (FIELD_imm32 & 63); + res->fields[FIELD_carry] = ThumbExpandImm_C_cout((res->fields[FIELD_i]<<(8+3))|(res->fields[FIELD_imm3]<<8)|(res->fields[FIELD_imm8]), res->fields[FIELD_APSR_C]); + res->fields_mask[FIELD_carry >> 6] |= 1LL << (FIELD_carry & 63); + /* TODO: handle ThumbExpandImm_C's possible setting of UNPREDICTABLE */ while(0); + /* pcode: if BadReg(d) || BadReg(n) then UNPREDICTABLE */ + if((BadReg(res->fields[FIELD_d])) || (BadReg(res->fields[FIELD_n]))) { + res->flags |= FLAG_UNPREDICTABLE; + } + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: CB2345F8 +int bic_register(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + /* Encoding T1 */ + /* pattern="010000,1110,Rm.3,Rdn.3" width=16 stringency=10 */ + { + uint16_t instr = req->instr_word16; + if(((instr & 0xFFC0)==0x4380)) { + res->instrSize = 16; + if(!(req->arch & ARCH_ARMv4T) && !(req->arch & ARCH_ARMv5T) && !(req->arch & ARCH_ARMv6) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_Rm] = (instr & 0x38)>>3; + res->fields_mask[FIELD_Rm >> 6] |= 1LL << (FIELD_Rm & 63); + char Rm_width = 3; + res->fields[FIELD_Rdn] = instr & 0x7; + res->fields_mask[FIELD_Rdn >> 6] |= 1LL << (FIELD_Rdn & 63); + char Rdn_width = 3; + + static const instruction_format instr_formats[] = + { + { /* BICS <Rdn>,<Rm> */ + "bics", /* .operation (const char *) */ + 0, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rdn,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rm,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + { /* BIC<c> <Rdn>,<Rm> */ + "bic", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rdn,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rm,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 2; + res->mnem = armv7::ARMV7_BICS; + + /* pcode: d = UInt(Rdn) */ + res->fields[FIELD_d] = (res->fields[FIELD_Rdn]); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: n = UInt(Rdn) */ + res->fields[FIELD_n] = (res->fields[FIELD_Rdn]); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: m = UInt(Rm) */ + res->fields[FIELD_m] = (res->fields[FIELD_Rm]); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + /* pcode: setflags = !InITBlock() */ + res->fields[FIELD_setflags] = !(req->inIfThen == IFTHEN_YES); + res->fields_mask[FIELD_setflags >> 6] |= 1LL << (FIELD_setflags & 63); + /* pcode: (shift_t, shift_n) = (SRType_LSL, 0) */ + res->fields[FIELD_shift_t] = 0; + res->fields_mask[FIELD_shift_t >> 6] |= 1LL << (FIELD_shift_t & 63); + res->fields[FIELD_shift_n] = 0; + res->fields_mask[FIELD_shift_n >> 6] |= 1LL << (FIELD_shift_n & 63); + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* Encoding T2 */ + /* pattern="11101,01,0001,S.1,Rn.4,(0),imm3.3,Rd.4,imm2.2,type.2,Rm.4" width=32 stringency=13 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFFE00000)==0xEA200000)) { + res->instrSize = 32; + if(!((instr & 0x8000)==0x0)) { + res->flags |= FLAG_UNPREDICTABLE; + } + if(!(req->arch & ARCH_ARMv6T2) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_S] = (instr & 0x100000)>>20; + res->fields_mask[FIELD_S >> 6] |= 1LL << (FIELD_S & 63); + char S_width = 1; + res->fields[FIELD_Rn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Rn >> 6] |= 1LL << (FIELD_Rn & 63); + char Rn_width = 4; + res->fields[FIELD_imm3] = (instr & 0x7000)>>12; + res->fields_mask[FIELD_imm3 >> 6] |= 1LL << (FIELD_imm3 & 63); + char imm3_width = 3; + res->fields[FIELD_Rd] = (instr & 0xF00)>>8; + res->fields_mask[FIELD_Rd >> 6] |= 1LL << (FIELD_Rd & 63); + char Rd_width = 4; + res->fields[FIELD_imm2] = (instr & 0xC0)>>6; + res->fields_mask[FIELD_imm2 >> 6] |= 1LL << (FIELD_imm2 & 63); + char imm2_width = 2; + res->fields[FIELD_type] = (instr & 0x30)>>4; + res->fields_mask[FIELD_type >> 6] |= 1LL << (FIELD_type & 63); + char type_width = 2; + res->fields[FIELD_Rm] = instr & 0xF; + res->fields_mask[FIELD_Rm >> 6] |= 1LL << (FIELD_Rm & 63); + char Rm_width = 4; + + static const instruction_format instr_formats[] = + { + { /* BIC{S}<c> <Rd>,<Rn>,<Rm>{,<shift>} */ + "bic", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_OPTIONAL_STATUS, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rd,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rn,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rm,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_SHIFT,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 4 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_BIC; + + /* pcode: d = UInt(Rd) */ + res->fields[FIELD_d] = (res->fields[FIELD_Rd]); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: n = UInt(Rn) */ + res->fields[FIELD_n] = (res->fields[FIELD_Rn]); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: m = UInt(Rm) */ + res->fields[FIELD_m] = (res->fields[FIELD_Rm]); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + /* pcode: setflags = (S == '1') */ + res->fields[FIELD_setflags] = ((res->fields[FIELD_S]) == (0x1)); + res->fields_mask[FIELD_setflags >> 6] |= 1LL << (FIELD_setflags & 63); + /* pcode: (shift_t, shift_n) = DecodeImmShift(type, imm3:imm2) */ + res->fields[FIELD_shift_t] = DecodeImmShift_shift_t(res->fields[FIELD_type], (res->fields[FIELD_imm3]<<2)|(res->fields[FIELD_imm2])); + res->fields_mask[FIELD_shift_t >> 6] |= 1LL << (FIELD_shift_t & 63); + res->fields[FIELD_shift_n] = DecodeImmShift_shift_n(res->fields[FIELD_type], (res->fields[FIELD_imm3]<<2)|(res->fields[FIELD_imm2])); + res->fields_mask[FIELD_shift_n >> 6] |= 1LL << (FIELD_shift_n & 63); + /* pcode: if BadReg(d) || BadReg(n) || BadReg(m) then UNPREDICTABLE */ + if(((BadReg(res->fields[FIELD_d])) || (BadReg(res->fields[FIELD_n]))) || (BadReg(res->fields[FIELD_m]))) { + res->flags |= FLAG_UNPREDICTABLE; + } + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: 36E084E8 +int bkpt(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + /* Encoding T1 */ + /* pattern="1011,1110,imm8.8" width=16 stringency=8 */ + { + uint16_t instr = req->instr_word16; + if(((instr & 0xFF00)==0xBE00)) { + res->instrSize = 16; + if(!(req->arch & ARCH_ARMv5T) && !(req->arch & ARCH_ARMv6) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_imm8] = instr & 0xFF; + res->fields_mask[FIELD_imm8 >> 6] |= 1LL << (FIELD_imm8 & 63); + char imm8_width = 8; + + static const instruction_format instr_formats[] = + { + { /* BKPT #<imm32> */ + "bkpt", /* .operation (const char *) */ + 0, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_IMM,FIELD_imm32,FIELD_UNINIT,"#","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 1 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_BKPT; + + /* pcode: imm32 = ZeroExtend(imm8, 32) */ + res->fields[FIELD_imm32] = res->fields[FIELD_imm8]; + res->fields_mask[FIELD_imm32 >> 6] |= 1LL << (FIELD_imm32 & 63); + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: 5F05EB70 +int bl_blx_immediate(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + /* Encoding T1 */ + /* pattern="11110,S.1,imm10.10,11,1,1,1,imm11.11" width=32 stringency=19 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xF800F800)==0xF000F800)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ARMv4T) && !(req->arch & ARCH_ARMv5T) && !(req->arch & ARCH_ARMv6) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_S] = (instr & 0x4000000)>>26; + res->fields_mask[FIELD_S >> 6] |= 1LL << (FIELD_S & 63); + char S_width = 1; + res->fields[FIELD_imm10] = (instr & 0x3FF0000)>>16; + res->fields_mask[FIELD_imm10 >> 6] |= 1LL << (FIELD_imm10 & 63); + char imm10_width = 10; + res->fields[FIELD_imm11] = instr & 0x7FF; + res->fields_mask[FIELD_imm11 >> 6] |= 1LL << (FIELD_imm11 & 63); + char imm11_width = 11; + + static const instruction_format instr_formats[] = + { + { /* BL<c> #<imm32> */ + "bl", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_IMM,FIELD_imm32,FIELD_UNINIT,"#","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 1 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_BL; + + /* pcode: I1 = NOT(1 EOR S) */ + res->fields[FIELD_I1] = (~((1) ^ (res->fields[FIELD_S])) & 1); + res->fields_mask[FIELD_I1 >> 6] |= 1LL << (FIELD_I1 & 63); + /* pcode: X1 = NOT(1 EOR S) */ + res->fields[FIELD_X1] = (~((1) ^ (res->fields[FIELD_S])) & 1); + res->fields_mask[FIELD_X1 >> 6] |= 1LL << (FIELD_X1 & 63); + /* pcode: imm32 = SignExtend(S:I1:X1:imm10:imm11:'0', 32) */ + res->fields[FIELD_imm32] = SignExtend((res->fields[FIELD_S]<<(1+11+10+1+1))|(res->fields[FIELD_I1]<<(1+11+10+1))|(res->fields[FIELD_X1]<<(1+11+10))|(res->fields[FIELD_imm10]<<(1+11))|(res->fields[FIELD_imm11]<<1)|(0x0),1+11+10+1+1+S_width); + res->fields_mask[FIELD_imm32 >> 6] |= 1LL << (FIELD_imm32 & 63); + /* pcode: toARM = FALSE */ + res->fields[FIELD_toARM] = 0; + res->fields_mask[FIELD_toARM >> 6] |= 1LL << (FIELD_toARM & 63); + /* pcode: if InITBlock() && !LastInITBlock() then UNPREDICTABLE */ + if((req->inIfThen == IFTHEN_YES) && (!(req->inIfThenLast == IFTHENLAST_YES))) { + res->flags |= FLAG_UNPREDICTABLE; + } + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* Encoding T1 */ + /* pattern="11110,S.1,imm10.10,11,J1.1,1,K1.1,imm11.11" width=32 stringency=21 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xF800D000)==0xF000D000)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ARMv6T2) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_S] = (instr & 0x4000000)>>26; + res->fields_mask[FIELD_S >> 6] |= 1LL << (FIELD_S & 63); + char S_width = 1; + res->fields[FIELD_imm10] = (instr & 0x3FF0000)>>16; + res->fields_mask[FIELD_imm10 >> 6] |= 1LL << (FIELD_imm10 & 63); + char imm10_width = 10; + res->fields[FIELD_J1] = (instr & 0x2000)>>13; + res->fields_mask[FIELD_J1 >> 6] |= 1LL << (FIELD_J1 & 63); + char J1_width = 1; + res->fields[FIELD_K1] = (instr & 0x800)>>11; + res->fields_mask[FIELD_K1 >> 6] |= 1LL << (FIELD_K1 & 63); + char K1_width = 1; + res->fields[FIELD_imm11] = instr & 0x7FF; + res->fields_mask[FIELD_imm11 >> 6] |= 1LL << (FIELD_imm11 & 63); + char imm11_width = 11; + + static const instruction_format instr_formats[] = + { + { /* BL<c> #<imm32> */ + "bl", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_IMM,FIELD_imm32,FIELD_UNINIT,"#","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 1 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_BL; + + /* pcode: I1 = NOT(J1 EOR S) */ + res->fields[FIELD_I1] = (~((res->fields[FIELD_J1]) ^ (res->fields[FIELD_S])) & 1); + res->fields_mask[FIELD_I1 >> 6] |= 1LL << (FIELD_I1 & 63); + /* pcode: X1 = NOT(K1 EOR S) */ + res->fields[FIELD_X1] = (~((res->fields[FIELD_K1]) ^ (res->fields[FIELD_S])) & 1); + res->fields_mask[FIELD_X1 >> 6] |= 1LL << (FIELD_X1 & 63); + /* pcode: imm32 = SignExtend(S:I1:X1:imm10:imm11:'0', 32) */ + res->fields[FIELD_imm32] = SignExtend((res->fields[FIELD_S]<<(1+11+10+1+1))|(res->fields[FIELD_I1]<<(1+11+10+1))|(res->fields[FIELD_X1]<<(1+11+10))|(res->fields[FIELD_imm10]<<(1+11))|(res->fields[FIELD_imm11]<<1)|(0x0),1+11+10+1+1+S_width); + res->fields_mask[FIELD_imm32 >> 6] |= 1LL << (FIELD_imm32 & 63); + /* pcode: toARM = FALSE */ + res->fields[FIELD_toARM] = 0; + res->fields_mask[FIELD_toARM >> 6] |= 1LL << (FIELD_toARM & 63); + /* pcode: if InITBlock() && !LastInITBlock() then UNPREDICTABLE */ + if((req->inIfThen == IFTHEN_YES) && (!(req->inIfThenLast == IFTHENLAST_YES))) { + res->flags |= FLAG_UNPREDICTABLE; + } + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* Encoding T2 */ + /* pattern="11110,S.1,imm10H.10,11,1,0,1,imm10L.10,0" width=32 stringency=20 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xF800F801)==0xF000E800)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ARMv5T) && !(req->arch & ARCH_ARMv6) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_S] = (instr & 0x4000000)>>26; + res->fields_mask[FIELD_S >> 6] |= 1LL << (FIELD_S & 63); + char S_width = 1; + res->fields[FIELD_imm10H] = (instr & 0x3FF0000)>>16; + res->fields_mask[FIELD_imm10H >> 6] |= 1LL << (FIELD_imm10H & 63); + char imm10H_width = 10; + res->fields[FIELD_imm10L] = (instr & 0x7FE)>>1; + res->fields_mask[FIELD_imm10L >> 6] |= 1LL << (FIELD_imm10L & 63); + char imm10L_width = 10; + + static const instruction_format instr_formats[] = + { + { /* BLX<c> #<imm32> */ + "blx", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_IMM,FIELD_imm32,FIELD_UNINIT,"#","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 1 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_BLX; + + /* pcode: if CurrentInstrSet() == InstrSet_ThumbEE then UNDEFINED */ + if((req->instrSet) == (INSTRSET_THUMBEE)) { + res->status |= STATUS_UNDEFINED; + } + /* pcode: I1 = NOT(1 EOR S) */ + res->fields[FIELD_I1] = (~((1) ^ (res->fields[FIELD_S])) & 1); + res->fields_mask[FIELD_I1 >> 6] |= 1LL << (FIELD_I1 & 63); + /* pcode: X1 = NOT(1 EOR S) */ + res->fields[FIELD_X1] = (~((1) ^ (res->fields[FIELD_S])) & 1); + res->fields_mask[FIELD_X1 >> 6] |= 1LL << (FIELD_X1 & 63); + /* pcode: imm32 = SignExtend(S:I1:X1:imm10H:imm10L:'00', 32) */ + res->fields[FIELD_imm32] = SignExtend((res->fields[FIELD_S]<<(2+imm10L_width+imm10H_width+1+1))|(res->fields[FIELD_I1]<<(2+imm10L_width+imm10H_width+1))|(res->fields[FIELD_X1]<<(2+imm10L_width+imm10H_width))|(res->fields[FIELD_imm10H]<<(2+imm10L_width))|(res->fields[FIELD_imm10L]<<2)|(0x0),2+imm10L_width+imm10H_width+1+1+S_width); + res->fields_mask[FIELD_imm32 >> 6] |= 1LL << (FIELD_imm32 & 63); + /* pcode: toARM = TRUE */ + res->fields[FIELD_toARM] = 1; + res->fields_mask[FIELD_toARM >> 6] |= 1LL << (FIELD_toARM & 63); + /* pcode: if InITBlock() && !LastInITBlock() then UNPREDICTABLE */ + if((req->inIfThen == IFTHEN_YES) && (!(req->inIfThenLast == IFTHENLAST_YES))) { + res->flags |= FLAG_UNPREDICTABLE; + } + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* Encoding T2 */ + /* pattern="11110,S.1,imm10H.10,11,J1.1,0,K1.1,imm10L.10,0" width=32 stringency=22 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xF800D001)==0xF000C000)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ARMv6T2) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_S] = (instr & 0x4000000)>>26; + res->fields_mask[FIELD_S >> 6] |= 1LL << (FIELD_S & 63); + char S_width = 1; + res->fields[FIELD_imm10H] = (instr & 0x3FF0000)>>16; + res->fields_mask[FIELD_imm10H >> 6] |= 1LL << (FIELD_imm10H & 63); + char imm10H_width = 10; + res->fields[FIELD_J1] = (instr & 0x2000)>>13; + res->fields_mask[FIELD_J1 >> 6] |= 1LL << (FIELD_J1 & 63); + char J1_width = 1; + res->fields[FIELD_K1] = (instr & 0x800)>>11; + res->fields_mask[FIELD_K1 >> 6] |= 1LL << (FIELD_K1 & 63); + char K1_width = 1; + res->fields[FIELD_imm10L] = (instr & 0x7FE)>>1; + res->fields_mask[FIELD_imm10L >> 6] |= 1LL << (FIELD_imm10L & 63); + char imm10L_width = 10; + + static const instruction_format instr_formats[] = + { + { /* BLX<c> #<imm32> */ + "blx", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_IMM,FIELD_imm32,FIELD_UNINIT,"#","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 1 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_BLX; + + /* pcode: if CurrentInstrSet() == InstrSet_ThumbEE then UNDEFINED */ + if((req->instrSet) == (INSTRSET_THUMBEE)) { + res->status |= STATUS_UNDEFINED; + } + /* pcode: I1 = NOT(J1 EOR S) */ + res->fields[FIELD_I1] = (~((res->fields[FIELD_J1]) ^ (res->fields[FIELD_S])) & 1); + res->fields_mask[FIELD_I1 >> 6] |= 1LL << (FIELD_I1 & 63); + /* pcode: X1 = NOT(K1 EOR S) */ + res->fields[FIELD_X1] = (~((res->fields[FIELD_K1]) ^ (res->fields[FIELD_S])) & 1); + res->fields_mask[FIELD_X1 >> 6] |= 1LL << (FIELD_X1 & 63); + /* pcode: imm32 = SignExtend(S:I1:X1:imm10H:imm10L:'00', 32) */ + res->fields[FIELD_imm32] = SignExtend((res->fields[FIELD_S]<<(2+imm10L_width+imm10H_width+1+1))|(res->fields[FIELD_I1]<<(2+imm10L_width+imm10H_width+1))|(res->fields[FIELD_X1]<<(2+imm10L_width+imm10H_width))|(res->fields[FIELD_imm10H]<<(2+imm10L_width))|(res->fields[FIELD_imm10L]<<2)|(0x0),2+imm10L_width+imm10H_width+1+1+S_width); + res->fields_mask[FIELD_imm32 >> 6] |= 1LL << (FIELD_imm32 & 63); + /* pcode: toARM = TRUE */ + res->fields[FIELD_toARM] = 1; + res->fields_mask[FIELD_toARM >> 6] |= 1LL << (FIELD_toARM & 63); + /* pcode: if InITBlock() && !LastInITBlock() then UNPREDICTABLE */ + if((req->inIfThen == IFTHEN_YES) && (!(req->inIfThenLast == IFTHENLAST_YES))) { + res->flags |= FLAG_UNPREDICTABLE; + } + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: 7382B915 +int blx(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + /* Encoding T1 */ + /* pattern="010001,11,1,Rm.4,(0)(0)(0)" width=16 stringency=12 */ + { + uint16_t instr = req->instr_word16; + if(((instr & 0xFF80)==0x4780)) { + res->instrSize = 16; + if(!((instr & 0x7)==0x0)) { + res->flags |= FLAG_UNPREDICTABLE; + } + if(!(req->arch & ARCH_ARMv5T) && !(req->arch & ARCH_ARMv6) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_Rm] = (instr & 0x78)>>3; + res->fields_mask[FIELD_Rm >> 6] |= 1LL << (FIELD_Rm & 63); + char Rm_width = 4; + + static const instruction_format instr_formats[] = + { + { /* BLX<c> <Rm> */ + "blx", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rm,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 1 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_BLX; + + /* pcode: m = UInt(Rm) */ + res->fields[FIELD_m] = (res->fields[FIELD_Rm]); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + /* pcode: if m == 15 then UNPREDICTABLE */ + if((res->fields[FIELD_m]) == (15)) { + res->flags |= FLAG_UNPREDICTABLE; + } + /* pcode: if InITBlock() && !LastInITBlock() then UNPREDICTABLE */ + if((req->inIfThen == IFTHEN_YES) && (!(req->inIfThenLast == IFTHENLAST_YES))) { + res->flags |= FLAG_UNPREDICTABLE; + } + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: ACE5CA84 +int branches_misc_control(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + uint32_t instr = req->instr_word32; + uint32_t op = (instr & 0x7F00000)>>20; + uint32_t op1 = (instr & 0x7000)>>12; + uint32_t op2 = (instr & 0xF00)>>8; + if(((op1 & 0x7)==0x0) && ((op & 0x7F)==0x38) && ((op2 & 0x3)==0x0)) return msr_reg_app(req, res); + if(((op1 & 0x7)==0x0) && ((op & 0x7F)==0x38) && ((op2 & 0x3)==0x1)) return msr_reg_sys(req, res); + if(((op1 & 0x7)==0x0) && ((op & 0x7F)==0x38) && ((op2 & 0x2)==0x2)) return msr_reg_sys(req, res); + if(((op1 & 0x7)==0x0) && ((op & 0x7F)==0x39) && 1) return msr_reg_sys(req, res); + if(((op1 & 0x7)==0x0) && ((op & 0x7F)==0x3A) && 1) return change_proc_state_and_hints(req, res); + if(((op1 & 0x7)==0x0) && ((op & 0x7F)==0x3B) && 1) return misc_control(req, res); + if(((op1 & 0x7)==0x0) && ((op & 0x7F)==0x3C) && 1) return bxj(req, res); + if(((op1 & 0x7)==0x0) && ((op & 0x7F)==0x3D) && 1) return subs_pc_lr_related(req, res); + if(((op1 & 0x7)==0x0) && ((op & 0x7F)==0x7F) && 1) return smc(req, res); + if(((op1 & 0x7)==0x2) && ((op & 0x7F)==0x7F) && 1) return undefined(req, res); + if(((op1 & 0x7)==0x0) && ((op & 0x7E)==0x3E) && 1) return mrs(req, res); + if(((op1 & 0x5)==0x0) && !((op & 0x38)==0x38) && 1) return b(req, res); + if(((op1 & 0x5)==0x1) && 1) return b(req, res); + if(((op1 & 0x5)==0x4) && 1) return bl_blx_immediate(req, res); + if(((op1 & 0x5)==0x5) && 1) return bl_blx_immediate(req, res); + return undefined(req, res); +} + +// gen_crc: 7A24C8EC +int bx(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + /* Encoding T1 */ + /* pattern="010001,11,0,Rm.4,(0)(0)(0)" width=16 stringency=12 */ + { + uint16_t instr = req->instr_word16; + if(((instr & 0xFF80)==0x4700)) { + res->instrSize = 16; + if(!((instr & 0x7)==0x0)) { + res->flags |= FLAG_UNPREDICTABLE; + } + if(!(req->arch & ARCH_ARMv4T) && !(req->arch & ARCH_ARMv5T) && !(req->arch & ARCH_ARMv6) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_Rm] = (instr & 0x78)>>3; + res->fields_mask[FIELD_Rm >> 6] |= 1LL << (FIELD_Rm & 63); + char Rm_width = 4; + + static const instruction_format instr_formats[] = + { + { /* BX<c> <Rm> */ + "bx", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rm,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 1 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_BX; + + /* pcode: m = UInt(Rm) */ + res->fields[FIELD_m] = (res->fields[FIELD_Rm]); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + /* pcode: if InITBlock() && !LastInITBlock() then UNPREDICTABLE */ + if((req->inIfThen == IFTHEN_YES) && (!(req->inIfThenLast == IFTHENLAST_YES))) { + res->flags |= FLAG_UNPREDICTABLE; + } + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: 241AD678 +int bxj(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + /* Encoding T1 */ + /* pattern="11110,0,1111,00,Rm.4,10,(0),0,(1)(1)(1)(1),(0)(0)(0)(0)(0)(0)(0)(0)" width=32 stringency=28 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFFF0D000)==0xF3C08000)) { + res->instrSize = 32; + if(!((instr & 0x2FFF)==0xF00)) { + res->flags |= FLAG_UNPREDICTABLE; + } + if(!(req->arch & ARCH_ARMv6T2) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_Rm] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Rm >> 6] |= 1LL << (FIELD_Rm & 63); + char Rm_width = 4; + + static const instruction_format instr_formats[] = + { + { /* BXJ<c> <Rm> */ + "bxj", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rm,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 1 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_BXJ; + + /* pcode: m = UInt(Rm) */ + res->fields[FIELD_m] = (res->fields[FIELD_Rm]); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + /* pcode: if BadReg(m) then UNPREDICTABLE */ + if(BadReg(res->fields[FIELD_m])) { + res->flags |= FLAG_UNPREDICTABLE; + } + /* pcode: if InITBlock() && !LastInITBlock() then UNPREDICTABLE */ + if((req->inIfThen == IFTHEN_YES) && (!(req->inIfThenLast == IFTHENLAST_YES))) { + res->flags |= FLAG_UNPREDICTABLE; + } + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: 549FB7F4 +int cbnz_cbz(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + /* Encoding T1 */ + /* pattern="1011,1,0,i.1,1,imm5.5,Rn.3" width=16 stringency=8 */ + { + uint16_t instr = req->instr_word16; + if(((instr & 0xFD00)==0xB900)) { + res->instrSize = 16; + if(!(req->arch & ARCH_ARMv6T2) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_i] = (instr & 0x200)>>9; + res->fields_mask[FIELD_i >> 6] |= 1LL << (FIELD_i & 63); + char i_width = 1; + res->fields[FIELD_imm5] = (instr & 0xF8)>>3; + res->fields_mask[FIELD_imm5 >> 6] |= 1LL << (FIELD_imm5 & 63); + char imm5_width = 5; + res->fields[FIELD_Rn] = instr & 0x7; + res->fields_mask[FIELD_Rn >> 6] |= 1LL << (FIELD_Rn & 63); + char Rn_width = 3; + + static const instruction_format instr_formats[] = + { + { /* CBNZ <Rn>,#<imm32> */ + "cbnz", /* .operation (const char *) */ + 0, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rn,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_IMM,FIELD_imm32,FIELD_UNINIT,"#","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_CBNZ; + + /* pcode: n = UInt(Rn) */ + res->fields[FIELD_n] = (res->fields[FIELD_Rn]); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: imm32 = ZeroExtend(i:imm5:'0', 32)+4 */ + res->fields[FIELD_imm32] = ((res->fields[FIELD_i]<<(1+5))|(res->fields[FIELD_imm5]<<1)|(0x0)) + (4); + res->fields_mask[FIELD_imm32 >> 6] |= 1LL << (FIELD_imm32 & 63); + /* pcode: if InITBlock() then UNPREDICTABLE */ + if(req->inIfThen == IFTHEN_YES) { + res->flags |= FLAG_UNPREDICTABLE; + } + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* Encoding T1 */ + /* pattern="1011,0,0,i.1,1,imm5.5,Rn.3" width=16 stringency=8 */ + { + uint16_t instr = req->instr_word16; + if(((instr & 0xFD00)==0xB100)) { + res->instrSize = 16; + if(!(req->arch & ARCH_ARMv6T2) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_i] = (instr & 0x200)>>9; + res->fields_mask[FIELD_i >> 6] |= 1LL << (FIELD_i & 63); + char i_width = 1; + res->fields[FIELD_imm5] = (instr & 0xF8)>>3; + res->fields_mask[FIELD_imm5 >> 6] |= 1LL << (FIELD_imm5 & 63); + char imm5_width = 5; + res->fields[FIELD_Rn] = instr & 0x7; + res->fields_mask[FIELD_Rn >> 6] |= 1LL << (FIELD_Rn & 63); + char Rn_width = 3; + + static const instruction_format instr_formats[] = + { + { /* CBZ <Rn>,#<imm32> */ + "cbz", /* .operation (const char *) */ + 0, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rn,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_IMM,FIELD_imm32,FIELD_UNINIT,"#","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_CBZ; + + /* pcode: n = UInt(Rn) */ + res->fields[FIELD_n] = (res->fields[FIELD_Rn]); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: imm32 = ZeroExtend(i:imm5:'0', 32)+4 */ + res->fields[FIELD_imm32] = ((res->fields[FIELD_i]<<(1+5))|(res->fields[FIELD_imm5]<<1)|(0x0)) + (4); + res->fields_mask[FIELD_imm32 >> 6] |= 1LL << (FIELD_imm32 & 63); + /* pcode: if InITBlock() then UNPREDICTABLE */ + if(req->inIfThen == IFTHEN_YES) { + res->flags |= FLAG_UNPREDICTABLE; + } + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: 82339136 +int cdp_cdp2(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + /* Encoding T1 */ + /* pattern="1110,1110,opc1.4,CRn.4,CRd.4,coproc.4,opc2.3,0,CRm.4" width=32 stringency=10 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFF000010)==0xEE000000)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ARMv6T2) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_opc1] = (instr & 0xF00000)>>20; + res->fields_mask[FIELD_opc1 >> 6] |= 1LL << (FIELD_opc1 & 63); + char opc1_width = 4; + res->fields[FIELD_CRn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_CRn >> 6] |= 1LL << (FIELD_CRn & 63); + char CRn_width = 4; + res->fields[FIELD_CRd] = (instr & 0xF000)>>12; + res->fields_mask[FIELD_CRd >> 6] |= 1LL << (FIELD_CRd & 63); + char CRd_width = 4; + res->fields[FIELD_coproc] = (instr & 0xF00)>>8; + res->fields_mask[FIELD_coproc >> 6] |= 1LL << (FIELD_coproc & 63); + char coproc_width = 4; + res->fields[FIELD_opc2] = (instr & 0xE0)>>5; + res->fields_mask[FIELD_opc2 >> 6] |= 1LL << (FIELD_opc2 & 63); + char opc2_width = 3; + res->fields[FIELD_CRm] = instr & 0xF; + res->fields_mask[FIELD_CRm >> 6] |= 1LL << (FIELD_CRm & 63); + char CRm_width = 4; + + static const instruction_format instr_formats[] = + { + { /* CDP<c> <coproc>,#<opc1>,<CRd>,<CRn>,<CRm>,#<opc2> */ + "cdp", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_COPROC,FIELD_coproc,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_IMM,FIELD_opc1,FIELD_UNINIT,"#","",WRITEBACK_NO}, + {OPERAND_FORMAT_COPROC_REG,FIELD_CRd,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_COPROC_REG,FIELD_CRn,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_COPROC_REG,FIELD_CRm,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_IMM,FIELD_opc2,FIELD_UNINIT,"#","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 6 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_CDP; + + /* pcode: if coproc == '1010' || coproc == '1011' then SEE "nop" */ + if(((res->fields[FIELD_coproc]) == (0xA)) || ((res->fields[FIELD_coproc]) == (0xB))) { + + return nop(req, res); + } + /* pcode: cp = UInt(coproc) */ + res->fields[FIELD_cp] = (res->fields[FIELD_coproc]); + res->fields_mask[FIELD_cp >> 6] |= 1LL << (FIELD_cp & 63); + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* Encoding T2 */ + /* pattern="1111,1110,opc1.4,CRn.4,CRd.4,coproc.4,opc2.3,0,CRm.4" width=32 stringency=10 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFF000010)==0xFE000000)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ARMv6T2) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_opc1] = (instr & 0xF00000)>>20; + res->fields_mask[FIELD_opc1 >> 6] |= 1LL << (FIELD_opc1 & 63); + char opc1_width = 4; + res->fields[FIELD_CRn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_CRn >> 6] |= 1LL << (FIELD_CRn & 63); + char CRn_width = 4; + res->fields[FIELD_CRd] = (instr & 0xF000)>>12; + res->fields_mask[FIELD_CRd >> 6] |= 1LL << (FIELD_CRd & 63); + char CRd_width = 4; + res->fields[FIELD_coproc] = (instr & 0xF00)>>8; + res->fields_mask[FIELD_coproc >> 6] |= 1LL << (FIELD_coproc & 63); + char coproc_width = 4; + res->fields[FIELD_opc2] = (instr & 0xE0)>>5; + res->fields_mask[FIELD_opc2 >> 6] |= 1LL << (FIELD_opc2 & 63); + char opc2_width = 3; + res->fields[FIELD_CRm] = instr & 0xF; + res->fields_mask[FIELD_CRm >> 6] |= 1LL << (FIELD_CRm & 63); + char CRm_width = 4; + + static const instruction_format instr_formats[] = + { + { /* CDP2<c> <coproc>,#<opc1>,<CRd>,<CRn>,<CRm>,#<opc2> */ + "cdp2", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_COPROC,FIELD_coproc,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_IMM,FIELD_opc1,FIELD_UNINIT,"#","",WRITEBACK_NO}, + {OPERAND_FORMAT_COPROC_REG,FIELD_CRd,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_COPROC_REG,FIELD_CRn,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_COPROC_REG,FIELD_CRm,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_IMM,FIELD_opc2,FIELD_UNINIT,"#","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 6 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_CDP2; + + /* pcode: cp = UInt(coproc) */ + res->fields[FIELD_cp] = (res->fields[FIELD_coproc]); + res->fields_mask[FIELD_cp >> 6] |= 1LL << (FIELD_cp & 63); + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: 8802732B +int change_proc_state_and_hints(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + uint32_t instr = req->instr_word32; + uint32_t op1 = (instr & 0x700)>>8; + uint32_t op2 = instr & 0xFF; + if(((op1 & 0x7)==0x0) && ((op2 & 0xFF)==0x0)) return nop(req, res); + if(((op1 & 0x7)==0x0) && ((op2 & 0xFF)==0x1)) return yield(req, res); + if(((op1 & 0x7)==0x0) && ((op2 & 0xFF)==0x2)) return wfe(req, res); + if(((op1 & 0x7)==0x0) && ((op2 & 0xFF)==0x3)) return wfi(req, res); + if(((op1 & 0x7)==0x0) && ((op2 & 0xFF)==0x4)) return sev(req, res); + if(((op1 & 0x7)==0x0) && ((op2 & 0xF0)==0xF0)) return dbg(req, res); + if(!((op1 & 0x7)==0x0) && 1) return cps(req, res); + if(((op1 & 0x7)==0x0) && 1) return hint_undoc(req, res); + return undefined(req, res); +} + +// gen_crc: B00AE121 +int clrex(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + /* Encoding T1 */ + /* pattern="11110,0,111,01,1,(1)(1)(1)(1),10,(0),0,(1)(1)(1)(1),0010,(1)(1)(1)(1)" width=32 stringency=32 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFFF0D0F0)==0xF3B08020)) { + res->instrSize = 32; + if(!((instr & 0xF2F0F)==0xF0F0F)) { + res->flags |= FLAG_UNPREDICTABLE; + } + if(!(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + static const instruction_format instr_formats[] = + { + { /* CLREX<c> */ + "clrex", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 0 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_CLREX; + + /* pcode: nop */ + while(0); + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: 9A0BF909 +int clz(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + /* Encoding T1 */ + /* pattern="11111,010,1,011,Rm.4,1111,Rd.4,1,000,Rm.4" width=32 stringency=20 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFFF0F0F0)==0xFAB0F080)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ARMv6T2) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_Rm] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Rm >> 6] |= 1LL << (FIELD_Rm & 63); + char Rm_width = 4; + res->fields[FIELD_Rd] = (instr & 0xF00)>>8; + res->fields_mask[FIELD_Rd >> 6] |= 1LL << (FIELD_Rd & 63); + char Rd_width = 4; + res->fields[FIELD_Rm_check] = instr & 0xF; + res->fields_mask[FIELD_Rm_check >> 6] |= 1LL << (FIELD_Rm_check & 63); + char Rm_check_width = 4; + + static const instruction_format instr_formats[] = + { + { /* CLZ<c> <Rd>,<Rm> */ + "clz", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rd,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rm,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_CLZ; + + /* pcode: if !Consistent(Rm) then UNPREDICTABLE */ + if(!((res->fields[FIELD_Rm] == res->fields[FIELD_Rm_check]))) { + res->flags |= FLAG_UNPREDICTABLE; + } + /* pcode: d = UInt(Rd) */ + res->fields[FIELD_d] = (res->fields[FIELD_Rd]); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: m = UInt(Rm) */ + res->fields[FIELD_m] = (res->fields[FIELD_Rm]); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + /* pcode: if BadReg(d) || BadReg(m) then UNPREDICTABLE */ + if((BadReg(res->fields[FIELD_d])) || (BadReg(res->fields[FIELD_m]))) { + res->flags |= FLAG_UNPREDICTABLE; + } + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: E6A88D29 +int cmn_immediate(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + /* Encoding T1 */ + /* pattern="11110,i.1,0,1000,1,Rn.4,0,imm3.3,1111,imm8.8" width=32 stringency=17 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFBF08F00)==0xF1100F00)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ARMv6T2) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_i] = (instr & 0x4000000)>>26; + res->fields_mask[FIELD_i >> 6] |= 1LL << (FIELD_i & 63); + char i_width = 1; + res->fields[FIELD_Rn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Rn >> 6] |= 1LL << (FIELD_Rn & 63); + char Rn_width = 4; + res->fields[FIELD_imm3] = (instr & 0x7000)>>12; + res->fields_mask[FIELD_imm3 >> 6] |= 1LL << (FIELD_imm3 & 63); + char imm3_width = 3; + res->fields[FIELD_imm8] = instr & 0xFF; + res->fields_mask[FIELD_imm8 >> 6] |= 1LL << (FIELD_imm8 & 63); + char imm8_width = 8; + + static const instruction_format instr_formats[] = + { + { /* CMN<c> <Rn>,#<imm32> */ + "cmn", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rn,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_IMM,FIELD_imm32,FIELD_UNINIT,"#","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_CMN; + + /* pcode: n = UInt(Rn) */ + res->fields[FIELD_n] = (res->fields[FIELD_Rn]); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: imm32 = ThumbExpandImm(i:imm3:imm8) */ + res->fields[FIELD_imm32] = ThumbExpandImm_C_imm32((res->fields[FIELD_i]<<(8+3))|(res->fields[FIELD_imm3]<<8)|(res->fields[FIELD_imm8]), req->carry_in); + /* TODO: handle ThumbExpandImm_C's possible setting of UNPREDICTABLE */ while(0); + res->fields_mask[FIELD_imm32 >> 6] |= 1LL << (FIELD_imm32 & 63); + /* pcode: if n == 15 then UNPREDICTABLE */ + if((res->fields[FIELD_n]) == (15)) { + res->flags |= FLAG_UNPREDICTABLE; + } + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: 76B10EF0 +int cmn_register(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + /* Encoding T1 */ + /* pattern="010000,1011,Rm.3,Rn.3" width=16 stringency=10 */ + { + uint16_t instr = req->instr_word16; + if(((instr & 0xFFC0)==0x42C0)) { + res->instrSize = 16; + if(!(req->arch & ARCH_ARMv4T) && !(req->arch & ARCH_ARMv5T) && !(req->arch & ARCH_ARMv6) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_Rm] = (instr & 0x38)>>3; + res->fields_mask[FIELD_Rm >> 6] |= 1LL << (FIELD_Rm & 63); + char Rm_width = 3; + res->fields[FIELD_Rn] = instr & 0x7; + res->fields_mask[FIELD_Rn >> 6] |= 1LL << (FIELD_Rn & 63); + char Rn_width = 3; + + static const instruction_format instr_formats[] = + { + { /* CMN<c> <Rn>,<Rm> */ + "cmn", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rn,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rm,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_CMN; + + /* pcode: n = UInt(Rn) */ + res->fields[FIELD_n] = (res->fields[FIELD_Rn]); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: m = UInt(Rm) */ + res->fields[FIELD_m] = (res->fields[FIELD_Rm]); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + /* pcode: (shift_t, shift_n) = (SRType_LSL, 0) */ + res->fields[FIELD_shift_t] = 0; + res->fields_mask[FIELD_shift_t >> 6] |= 1LL << (FIELD_shift_t & 63); + res->fields[FIELD_shift_n] = 0; + res->fields_mask[FIELD_shift_n >> 6] |= 1LL << (FIELD_shift_n & 63); + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* Encoding T2 */ + /* pattern="11101,01,1000,1,Rn.4,(0),imm3.3,1111,imm2.2,type.2,Rm.4" width=32 stringency=17 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFFF00F00)==0xEB100F00)) { + res->instrSize = 32; + if(!((instr & 0x8000)==0x0)) { + res->flags |= FLAG_UNPREDICTABLE; + } + if(!(req->arch & ARCH_ARMv6T2) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_Rn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Rn >> 6] |= 1LL << (FIELD_Rn & 63); + char Rn_width = 4; + res->fields[FIELD_imm3] = (instr & 0x7000)>>12; + res->fields_mask[FIELD_imm3 >> 6] |= 1LL << (FIELD_imm3 & 63); + char imm3_width = 3; + res->fields[FIELD_imm2] = (instr & 0xC0)>>6; + res->fields_mask[FIELD_imm2 >> 6] |= 1LL << (FIELD_imm2 & 63); + char imm2_width = 2; + res->fields[FIELD_type] = (instr & 0x30)>>4; + res->fields_mask[FIELD_type >> 6] |= 1LL << (FIELD_type & 63); + char type_width = 2; + res->fields[FIELD_Rm] = instr & 0xF; + res->fields_mask[FIELD_Rm >> 6] |= 1LL << (FIELD_Rm & 63); + char Rm_width = 4; + + static const instruction_format instr_formats[] = + { + { /* CMN<c> <Rn>,<Rm>{,<shift>} */ + "cmn", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rn,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rm,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_SHIFT,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_CMN; + + /* pcode: n = UInt(Rn) */ + res->fields[FIELD_n] = (res->fields[FIELD_Rn]); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: m = UInt(Rm) */ + res->fields[FIELD_m] = (res->fields[FIELD_Rm]); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + /* pcode: (shift_t, shift_n) = DecodeImmShift(type, imm3:imm2) */ + res->fields[FIELD_shift_t] = DecodeImmShift_shift_t(res->fields[FIELD_type], (res->fields[FIELD_imm3]<<2)|(res->fields[FIELD_imm2])); + res->fields_mask[FIELD_shift_t >> 6] |= 1LL << (FIELD_shift_t & 63); + res->fields[FIELD_shift_n] = DecodeImmShift_shift_n(res->fields[FIELD_type], (res->fields[FIELD_imm3]<<2)|(res->fields[FIELD_imm2])); + res->fields_mask[FIELD_shift_n >> 6] |= 1LL << (FIELD_shift_n & 63); + /* pcode: if n == 15 || BadReg(m) then UNPREDICTABLE */ + if(((res->fields[FIELD_n]) == (15)) || (BadReg(res->fields[FIELD_m]))) { + res->flags |= FLAG_UNPREDICTABLE; + } + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: E70E2E3F +int cmp_immediate(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + /* Encoding T1 */ + /* pattern="001,01,Rn.3,imm8.8" width=16 stringency=5 */ + { + uint16_t instr = req->instr_word16; + if(((instr & 0xF800)==0x2800)) { + res->instrSize = 16; + if(!(req->arch & ARCH_ARMv4T) && !(req->arch & ARCH_ARMv5T) && !(req->arch & ARCH_ARMv6) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_Rn] = (instr & 0x700)>>8; + res->fields_mask[FIELD_Rn >> 6] |= 1LL << (FIELD_Rn & 63); + char Rn_width = 3; + res->fields[FIELD_imm8] = instr & 0xFF; + res->fields_mask[FIELD_imm8 >> 6] |= 1LL << (FIELD_imm8 & 63); + char imm8_width = 8; + + static const instruction_format instr_formats[] = + { + { /* CMP<c> <Rn>,#<imm8> */ + "cmp", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rn,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_IMM,FIELD_imm8,FIELD_UNINIT,"#","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_CMP; + + /* pcode: n = UInt(Rn) */ + res->fields[FIELD_n] = (res->fields[FIELD_Rn]); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: imm32 = ZeroExtend(imm8, 32) */ + res->fields[FIELD_imm32] = res->fields[FIELD_imm8]; + res->fields_mask[FIELD_imm32 >> 6] |= 1LL << (FIELD_imm32 & 63); + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* Encoding T2 */ + /* pattern="11110,i.1,0,1101,1,Rn.4,0,imm3.3,1111,imm8.8" width=32 stringency=17 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFBF08F00)==0xF1B00F00)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ARMv6T2) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_i] = (instr & 0x4000000)>>26; + res->fields_mask[FIELD_i >> 6] |= 1LL << (FIELD_i & 63); + char i_width = 1; + res->fields[FIELD_Rn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Rn >> 6] |= 1LL << (FIELD_Rn & 63); + char Rn_width = 4; + res->fields[FIELD_imm3] = (instr & 0x7000)>>12; + res->fields_mask[FIELD_imm3 >> 6] |= 1LL << (FIELD_imm3 & 63); + char imm3_width = 3; + res->fields[FIELD_imm8] = instr & 0xFF; + res->fields_mask[FIELD_imm8 >> 6] |= 1LL << (FIELD_imm8 & 63); + char imm8_width = 8; + + static const instruction_format instr_formats[] = + { + { /* CMP<c> <Rn>,#<imm32> */ + "cmp", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rn,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_IMM,FIELD_imm32,FIELD_UNINIT,"#","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_CMP; + + /* pcode: n = UInt(Rn) */ + res->fields[FIELD_n] = (res->fields[FIELD_Rn]); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: imm32 = ThumbExpandImm(i:imm3:imm8) */ + res->fields[FIELD_imm32] = ThumbExpandImm_C_imm32((res->fields[FIELD_i]<<(8+3))|(res->fields[FIELD_imm3]<<8)|(res->fields[FIELD_imm8]), req->carry_in); + /* TODO: handle ThumbExpandImm_C's possible setting of UNPREDICTABLE */ while(0); + res->fields_mask[FIELD_imm32 >> 6] |= 1LL << (FIELD_imm32 & 63); + /* pcode: if n == 15 then UNPREDICTABLE */ + if((res->fields[FIELD_n]) == (15)) { + res->flags |= FLAG_UNPREDICTABLE; + } + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: 12CBCA9C +int cmp_register(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + /* Encoding T1 */ + /* pattern="010000,1010,Rm.3,Rn.3" width=16 stringency=10 */ + { + uint16_t instr = req->instr_word16; + if(((instr & 0xFFC0)==0x4280)) { + res->instrSize = 16; + if(!(req->arch & ARCH_ARMv4T) && !(req->arch & ARCH_ARMv5T) && !(req->arch & ARCH_ARMv6) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_Rm] = (instr & 0x38)>>3; + res->fields_mask[FIELD_Rm >> 6] |= 1LL << (FIELD_Rm & 63); + char Rm_width = 3; + res->fields[FIELD_Rn] = instr & 0x7; + res->fields_mask[FIELD_Rn >> 6] |= 1LL << (FIELD_Rn & 63); + char Rn_width = 3; + + static const instruction_format instr_formats[] = + { + { /* CMP<c> <Rn>,<Rm> */ + "cmp", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rn,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rm,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_CMP; + + /* pcode: n = UInt(Rn) */ + res->fields[FIELD_n] = (res->fields[FIELD_Rn]); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: m = UInt(Rm) */ + res->fields[FIELD_m] = (res->fields[FIELD_Rm]); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + /* pcode: (shift_t, shift_n) = (SRType_LSL, 0) */ + res->fields[FIELD_shift_t] = 0; + res->fields_mask[FIELD_shift_t >> 6] |= 1LL << (FIELD_shift_t & 63); + res->fields[FIELD_shift_n] = 0; + res->fields_mask[FIELD_shift_n >> 6] |= 1LL << (FIELD_shift_n & 63); + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* Encoding T2 */ + /* pattern="010001,01,N.1,Rm.4,Rn.3" width=16 stringency=9 */ + { + uint16_t instr = req->instr_word16; + if(((instr & 0xFF00)==0x4500)) { + res->instrSize = 16; + if(!(req->arch & ARCH_ARMv4T) && !(req->arch & ARCH_ARMv5T) && !(req->arch & ARCH_ARMv6) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_N] = (instr & 0x80)>>7; + res->fields_mask[FIELD_N >> 6] |= 1LL << (FIELD_N & 63); + char N_width = 1; + res->fields[FIELD_Rm] = (instr & 0x78)>>3; + res->fields_mask[FIELD_Rm >> 6] |= 1LL << (FIELD_Rm & 63); + char Rm_width = 4; + res->fields[FIELD_Rn] = instr & 0x7; + res->fields_mask[FIELD_Rn >> 6] |= 1LL << (FIELD_Rn & 63); + char Rn_width = 3; + + static const instruction_format instr_formats[] = + { + { /* CMP<c> <Rn>,<Rm> */ + "cmp", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rn,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rm,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_CMP; + + /* pcode: n = UInt(N:Rn) */ + res->fields[FIELD_n] = ((res->fields[FIELD_N]<<Rn_width)|(res->fields[FIELD_Rn])); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: m = UInt(Rm) */ + res->fields[FIELD_m] = (res->fields[FIELD_Rm]); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + /* pcode: (shift_t, shift_n) = (SRType_LSL, 0) */ + res->fields[FIELD_shift_t] = 0; + res->fields_mask[FIELD_shift_t >> 6] |= 1LL << (FIELD_shift_t & 63); + res->fields[FIELD_shift_n] = 0; + res->fields_mask[FIELD_shift_n >> 6] |= 1LL << (FIELD_shift_n & 63); + /* pcode: if n < 8 && m < 8 then UNPREDICTABLE */ + if(((res->fields[FIELD_n]) < (8)) && ((res->fields[FIELD_m]) < (8))) { + res->flags |= FLAG_UNPREDICTABLE; + } + /* pcode: if n == 15 || m == 15 then UNPREDICTABLE */ + if(((res->fields[FIELD_n]) == (15)) || ((res->fields[FIELD_m]) == (15))) { + res->flags |= FLAG_UNPREDICTABLE; + } + /* pcode: Rn = UInt(N:Rn) */ + res->fields[FIELD_Rn] = ((res->fields[FIELD_N]<<Rn_width)|(res->fields[FIELD_Rn])); + res->fields_mask[FIELD_Rn >> 6] |= 1LL << (FIELD_Rn & 63); + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* Encoding T3 */ + /* pattern="11101,01,1101,1,Rn.4,(0),imm3.3,1111,imm2.2,type.2,Rm.4" width=32 stringency=17 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFFF00F00)==0xEBB00F00)) { + res->instrSize = 32; + if(!((instr & 0x8000)==0x0)) { + res->flags |= FLAG_UNPREDICTABLE; + } + if(!(req->arch & ARCH_ARMv6T2) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_Rn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Rn >> 6] |= 1LL << (FIELD_Rn & 63); + char Rn_width = 4; + res->fields[FIELD_imm3] = (instr & 0x7000)>>12; + res->fields_mask[FIELD_imm3 >> 6] |= 1LL << (FIELD_imm3 & 63); + char imm3_width = 3; + res->fields[FIELD_imm2] = (instr & 0xC0)>>6; + res->fields_mask[FIELD_imm2 >> 6] |= 1LL << (FIELD_imm2 & 63); + char imm2_width = 2; + res->fields[FIELD_type] = (instr & 0x30)>>4; + res->fields_mask[FIELD_type >> 6] |= 1LL << (FIELD_type & 63); + char type_width = 2; + res->fields[FIELD_Rm] = instr & 0xF; + res->fields_mask[FIELD_Rm >> 6] |= 1LL << (FIELD_Rm & 63); + char Rm_width = 4; + + static const instruction_format instr_formats[] = + { + { /* CMP<c> <Rn>,<Rm>{,<shift>} */ + "cmp", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rn,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rm,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_SHIFT,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_CMP; + + /* pcode: n = UInt(Rn) */ + res->fields[FIELD_n] = (res->fields[FIELD_Rn]); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: m = UInt(Rm) */ + res->fields[FIELD_m] = (res->fields[FIELD_Rm]); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + /* pcode: (shift_t, shift_n) = DecodeImmShift(type, imm3:imm2) */ + res->fields[FIELD_shift_t] = DecodeImmShift_shift_t(res->fields[FIELD_type], (res->fields[FIELD_imm3]<<2)|(res->fields[FIELD_imm2])); + res->fields_mask[FIELD_shift_t >> 6] |= 1LL << (FIELD_shift_t & 63); + res->fields[FIELD_shift_n] = DecodeImmShift_shift_n(res->fields[FIELD_type], (res->fields[FIELD_imm3]<<2)|(res->fields[FIELD_imm2])); + res->fields_mask[FIELD_shift_n >> 6] |= 1LL << (FIELD_shift_n & 63); + /* pcode: if n == 15 || BadReg(m) then UNPREDICTABLE */ + if(((res->fields[FIELD_n]) == (15)) || (BadReg(res->fields[FIELD_m]))) { + res->flags |= FLAG_UNPREDICTABLE; + } + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: C9675F31 +int cond_branch_superv_call(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + uint16_t instr = req->instr_word16; + uint16_t Opcode = (instr & 0xF00)>>8; + if(((Opcode & 0xF)==0xE)) return udf(req, res); + if(((Opcode & 0xF)==0xF)) return svc(req, res); + if(!((Opcode & 0xE)==0xE)) return b(req, res); + return undefined(req, res); +} + +// gen_crc: 0D4467B1 +int coprocessor_instructions(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + uint32_t instr = req->instr_word32; + uint32_t op1 = (instr & 0x3F00000)>>20; + uint32_t Rn = (instr & 0xF0000)>>16; + uint32_t coproc = (instr & 0xF00)>>8; + uint32_t op = (instr & 0x10)>>4; + if(((op1 & 0x3B)==0x3) && !((coproc & 0xE)==0xA) && !((Rn & 0xF)==0xF) && 1) return ldc_immediate(req, res); + if(((op1 & 0x3B)==0x3) && !((coproc & 0xE)==0xA) && ((Rn & 0xF)==0xF) && 1) return ldc_literal(req, res); + if(((op1 & 0x39)==0x9) && !((coproc & 0xE)==0xA) && !((Rn & 0xF)==0xF) && 1) return ldc_immediate(req, res); + if(((op1 & 0x39)==0x9) && !((coproc & 0xE)==0xA) && ((Rn & 0xF)==0xF) && 1) return ldc_literal(req, res); + if(((op1 & 0x31)==0x11) && !((coproc & 0xE)==0xA) && !((Rn & 0xF)==0xF) && 1) return ldc_immediate(req, res); + if(((op1 & 0x31)==0x11) && !((coproc & 0xE)==0xA) && ((Rn & 0xF)==0xF) && 1) return ldc_literal(req, res); + if(((op1 & 0x3F)==0x4) && !((coproc & 0xE)==0xA) && 1) return mcrr_mcrr2(req, res); + if(((op1 & 0x3F)==0x5) && !((coproc & 0xE)==0xA) && 1) return mrrc_mrrc2(req, res); + if(((op1 & 0x3B)==0x2) && !((coproc & 0xE)==0xA) && 1) return stc_stc2(req, res); + if(((op1 & 0x3E)==0x4) && ((coproc & 0xE)==0xA) && 1) return xfer_64_core_ext_regs(req, res); + if(((op1 & 0x3A)==0x2) && ((coproc & 0xE)==0xA) && 1) return extension_reg_load_store(req, res); + if(((op1 & 0x39)==0x8) && !((coproc & 0xE)==0xA) && 1) return stc_stc2(req, res); + if(((op1 & 0x31)==0x20) && ((op & 0x1)==0x1) && !((coproc & 0xE)==0xA) && 1) return mcr_mcr2(req, res); + if(((op1 & 0x31)==0x21) && ((op & 0x1)==0x1) && !((coproc & 0xE)==0xA) && 1) return mrc_mrc2(req, res); + if(((op1 & 0x38)==0x8) && ((coproc & 0xE)==0xA) && 1) return extension_reg_load_store(req, res); + if(((op1 & 0x31)==0x10) && !((coproc & 0xE)==0xA) && 1) return stc_stc2(req, res); + if(((op1 & 0x30)==0x20) && ((op & 0x1)==0x0) && ((coproc & 0xE)==0xA) && 1) return vfp_data_proc(req, res); + if(((op1 & 0x30)==0x20) && ((op & 0x1)==0x0) && !((coproc & 0xE)==0xA) && 1) return cdp_cdp2(req, res); + if(((op1 & 0x30)==0x20) && ((op & 0x1)==0x1) && ((coproc & 0xE)==0xA) && 1) return xfer_8_16_32_core_extension(req, res); + if(((op1 & 0x30)==0x10) && ((coproc & 0xE)==0xA) && 1) return extension_reg_load_store(req, res); + if(((op1 & 0x3E)==0x0) && 1) return undefined(req, res); + if(((op1 & 0x30)==0x30) && 1) return advanced_simd_data_proc(req, res); + return undefined(req, res); +} + +// gen_crc: 3900C839 +int cps(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + /* Encoding T1 */ + /* pattern="1011,0110,011,im.1,(0),A.1,I.1,F.1" width=16 stringency=16 */ + { + uint16_t instr = req->instr_word16; + if(((instr & 0xFFE0)==0xB660)) { + res->instrSize = 16; + if(!((instr & 0x8)==0x0)) { + res->flags |= FLAG_UNPREDICTABLE; + } + if(!(req->arch & ARCH_ARMv6) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_im] = (instr & 0x10)>>4; + res->fields_mask[FIELD_im >> 6] |= 1LL << (FIELD_im & 63); + char im_width = 1; + res->fields[FIELD_A] = (instr & 0x4)>>2; + res->fields_mask[FIELD_A >> 6] |= 1LL << (FIELD_A & 63); + char A_width = 1; + res->fields[FIELD_I] = (instr & 0x2)>>1; + res->fields_mask[FIELD_I >> 6] |= 1LL << (FIELD_I & 63); + char I_width = 1; + res->fields[FIELD_F] = instr & 0x1; + res->fields_mask[FIELD_F >> 6] |= 1LL << (FIELD_F & 63); + char F_width = 1; + + static const instruction_format instr_formats[] = + { + { /* CPS<effect> <iflags> */ + "cps", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_EFFECT, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_IFLAGS,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 1 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_CPS; + + /* pcode: enable = (im == '0') */ + res->fields[FIELD_enable] = ((res->fields[FIELD_im]) == (0x0)); + res->fields_mask[FIELD_enable >> 6] |= 1LL << (FIELD_enable & 63); + /* pcode: disable = (im == '1') */ + res->fields[FIELD_disable] = ((res->fields[FIELD_im]) == (0x1)); + res->fields_mask[FIELD_disable >> 6] |= 1LL << (FIELD_disable & 63); + /* pcode: changemode = FALSE */ + res->fields[FIELD_changemode] = 0; + res->fields_mask[FIELD_changemode >> 6] |= 1LL << (FIELD_changemode & 63); + /* pcode: affectA = (A == '1') */ + res->fields[FIELD_affectA] = ((res->fields[FIELD_A]) == (0x1)); + res->fields_mask[FIELD_affectA >> 6] |= 1LL << (FIELD_affectA & 63); + /* pcode: affectI = (I == '1') */ + res->fields[FIELD_affectI] = ((res->fields[FIELD_I]) == (0x1)); + res->fields_mask[FIELD_affectI >> 6] |= 1LL << (FIELD_affectI & 63); + /* pcode: affectF = (F == '1') */ + res->fields[FIELD_affectF] = ((res->fields[FIELD_F]) == (0x1)); + res->fields_mask[FIELD_affectF >> 6] |= 1LL << (FIELD_affectF & 63); + /* pcode: if InITBlock() then UNPREDICTABLE */ + if(req->inIfThen == IFTHEN_YES) { + res->flags |= FLAG_UNPREDICTABLE; + } + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* Encoding T2 */ + /* pattern="11110,0,1110,1,0,(1)(1)(1)(1),10,(0),0,(0),imod.2,M.1,A.1,I.1,F.1,mode.5" width=32 stringency=25 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFFF0D000)==0xF3A08000)) { + res->instrSize = 32; + if(!((instr & 0xF2800)==0xF0000)) { + res->flags |= FLAG_UNPREDICTABLE; + } + if(!(req->arch & ARCH_ARMv6T2) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_imod] = (instr & 0x600)>>9; + res->fields_mask[FIELD_imod >> 6] |= 1LL << (FIELD_imod & 63); + char imod_width = 2; + res->fields[FIELD_M] = (instr & 0x100)>>8; + res->fields_mask[FIELD_M >> 6] |= 1LL << (FIELD_M & 63); + char M_width = 1; + res->fields[FIELD_A] = (instr & 0x80)>>7; + res->fields_mask[FIELD_A >> 6] |= 1LL << (FIELD_A & 63); + char A_width = 1; + res->fields[FIELD_I] = (instr & 0x40)>>6; + res->fields_mask[FIELD_I >> 6] |= 1LL << (FIELD_I & 63); + char I_width = 1; + res->fields[FIELD_F] = (instr & 0x20)>>5; + res->fields_mask[FIELD_F >> 6] |= 1LL << (FIELD_F & 63); + char F_width = 1; + res->fields[FIELD_mode] = instr & 0x1F; + res->fields_mask[FIELD_mode >> 6] |= 1LL << (FIELD_mode & 63); + char mode_width = 5; + + static const instruction_format instr_formats[] = + { + { /* CPS<effect> <iflags>{,#<mode>} */ + "cps", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_EFFECT, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_IFLAGS,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_OPTIONAL_IMM,FIELD_mode,FIELD_UNINIT,"#","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_CPS; + + /* pcode: if mode != '00000' && M == '0' then UNPREDICTABLE */ + if(((res->fields[FIELD_mode]) != (0x0)) && ((res->fields[FIELD_M]) == (0x0))) { + res->flags |= FLAG_UNPREDICTABLE; + } + /* pcode: if (imod<1>=='1' && A:I:F=='000') || (imod<1> == '0' && A:I:F != '000') then UNPREDICTABLE */ + if(((((((res->fields[FIELD_imod] >> 1) & 1)) == (0x1)) && (((res->fields[FIELD_A]<<(F_width+I_width))|(res->fields[FIELD_I]<<F_width)|(res->fields[FIELD_F])) == (0x0)))) || ((((((res->fields[FIELD_imod] >> 1) & 1)) == (0x0)) && (((res->fields[FIELD_A]<<(F_width+I_width))|(res->fields[FIELD_I]<<F_width)|(res->fields[FIELD_F])) != (0x0))))) { + res->flags |= FLAG_UNPREDICTABLE; + } + /* pcode: enable = (imod == '10') */ + res->fields[FIELD_enable] = ((res->fields[FIELD_imod]) == (0x2)); + res->fields_mask[FIELD_enable >> 6] |= 1LL << (FIELD_enable & 63); + /* pcode: disable = (imod == '11') */ + res->fields[FIELD_disable] = ((res->fields[FIELD_imod]) == (0x3)); + res->fields_mask[FIELD_disable >> 6] |= 1LL << (FIELD_disable & 63); + /* pcode: changemode = (M == '1') */ + res->fields[FIELD_changemode] = ((res->fields[FIELD_M]) == (0x1)); + res->fields_mask[FIELD_changemode >> 6] |= 1LL << (FIELD_changemode & 63); + /* pcode: affectA = (A == '1') */ + res->fields[FIELD_affectA] = ((res->fields[FIELD_A]) == (0x1)); + res->fields_mask[FIELD_affectA >> 6] |= 1LL << (FIELD_affectA & 63); + /* pcode: affectI = (I == '1') */ + res->fields[FIELD_affectI] = ((res->fields[FIELD_I]) == (0x1)); + res->fields_mask[FIELD_affectI >> 6] |= 1LL << (FIELD_affectI & 63); + /* pcode: affectF = (F == '1') */ + res->fields[FIELD_affectF] = ((res->fields[FIELD_F]) == (0x1)); + res->fields_mask[FIELD_affectF >> 6] |= 1LL << (FIELD_affectF & 63); + /* pcode: if imod == '01' || InITBlock() then UNPREDICTABLE */ + if(((res->fields[FIELD_imod]) == (0x1)) || (req->inIfThen == IFTHEN_YES)) { + res->flags |= FLAG_UNPREDICTABLE; + } + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: E8AB6A7C +int data_proc(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + uint16_t instr = req->instr_word16; + uint16_t Opcode = (instr & 0x3C0)>>6; + if(((Opcode & 0xF)==0x0)) return and_register(req, res); + if(((Opcode & 0xF)==0x1)) return eor_register(req, res); + if(((Opcode & 0xF)==0x2)) return lsl_register(req, res); + if(((Opcode & 0xF)==0x3)) return lsr_register(req, res); + if(((Opcode & 0xF)==0x4)) return asr_register(req, res); + if(((Opcode & 0xF)==0x5)) return adc_register(req, res); + if(((Opcode & 0xF)==0x6)) return sbc_register(req, res); + if(((Opcode & 0xF)==0x7)) return ror_register(req, res); + if(((Opcode & 0xF)==0x8)) return tst_register(req, res); + if(((Opcode & 0xF)==0x9)) return rsb_immediate(req, res); + if(((Opcode & 0xF)==0xA)) return cmp_register(req, res); + if(((Opcode & 0xF)==0xB)) return cmn_register(req, res); + if(((Opcode & 0xF)==0xC)) return orr_register(req, res); + if(((Opcode & 0xF)==0xD)) return mul_register(req, res); + if(((Opcode & 0xF)==0xE)) return bic_register(req, res); + if(((Opcode & 0xF)==0xF)) return mvn_register(req, res); + return undefined(req, res); +} + +// gen_crc: 0C7A491F +int data_processing_modified_immediate(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + uint32_t instr = req->instr_word32; + uint32_t op = (instr & 0x1E00000)>>21; + uint32_t S = (instr & 0x100000)>>20; + uint32_t Rn = (instr & 0xF0000)>>16; + uint32_t Rd = (instr & 0xF00)>>8; + if(((op & 0xF)==0x0) && ((Rd & 0xF)==0xF) && ((S & 0x1)==0x0) && 1) return unpredictable(req, res); + if(((op & 0xF)==0x0) && ((Rd & 0xF)==0xF) && ((S & 0x1)==0x1) && 1) return tst_immediate(req, res); + if(((op & 0xF)==0x4) && ((Rd & 0xF)==0xF) && ((S & 0x1)==0x0) && 1) return unpredictable(req, res); + if(((op & 0xF)==0x4) && ((Rd & 0xF)==0xF) && ((S & 0x1)==0x1) && 1) return teq_immediate(req, res); + if(((op & 0xF)==0x8) && ((Rd & 0xF)==0xF) && ((S & 0x1)==0x0) && 1) return unpredictable(req, res); + if(((op & 0xF)==0x8) && ((Rd & 0xF)==0xF) && ((S & 0x1)==0x1) && 1) return cmn_immediate(req, res); + if(((op & 0xF)==0xD) && ((Rd & 0xF)==0xF) && ((S & 0x1)==0x0) && 1) return unpredictable(req, res); + if(((op & 0xF)==0xD) && ((Rd & 0xF)==0xF) && ((S & 0x1)==0x1) && 1) return cmp_immediate(req, res); + if(((op & 0xF)==0x0) && !((Rd & 0xF)==0xF) && 1) return and_immediate(req, res); + if(((op & 0xF)==0x2) && !((Rn & 0xF)==0xF) && 1) return orr_immediate(req, res); + if(((op & 0xF)==0x2) && ((Rn & 0xF)==0xF) && 1) return mov_immediate(req, res); + if(((op & 0xF)==0x3) && !((Rn & 0xF)==0xF) && 1) return orn_immediate(req, res); + if(((op & 0xF)==0x3) && ((Rn & 0xF)==0xF) && 1) return mvn_immediate(req, res); + if(((op & 0xF)==0x4) && !((Rd & 0xF)==0xF) && 1) return eor_immediate(req, res); + if(((op & 0xF)==0x8) && !((Rd & 0xF)==0xF) && 1) return add_immediate(req, res); + if(((op & 0xF)==0xD) && !((Rd & 0xF)==0xF) && 1) return sub_immediate(req, res); + if(((op & 0xF)==0x1) && 1) return bic_immediate(req, res); + if(((op & 0xF)==0xA) && 1) return adc_immediate(req, res); + if(((op & 0xF)==0xB) && 1) return sbc_immediate(req, res); + if(((op & 0xF)==0xE) && 1) return rsb_immediate(req, res); + return undefined(req, res); +} + +// gen_crc: 943B5AEA +int data_processing_plain_binary_immediate(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + uint32_t instr = req->instr_word32; + uint32_t op = (instr & 0x1F00000)>>20; + uint32_t Rn = (instr & 0xF0000)>>16; + uint32_t wookie = (instr & 0x7FC0)>>6; + if(((op & 0x1F)==0x12) && ((wookie & 0x1C3)==0x0) && 1) return ssat16(req, res); + if(((op & 0x1F)==0x1A) && ((wookie & 0x1C3)==0x0) && 1) return usat16(req, res); + if(((op & 0x1F)==0x0) && !((Rn & 0xF)==0xF) && 1) return add_immediate(req, res); + if(((op & 0x1F)==0x0) && ((Rn & 0xF)==0xF) && 1) return adr(req, res); + if(((op & 0x1F)==0xA) && !((Rn & 0xF)==0xF) && 1) return sub_immediate(req, res); + if(((op & 0x1F)==0xA) && ((Rn & 0xF)==0xF) && 1) return adr(req, res); + if(((op & 0x1F)==0x16) && !((Rn & 0xF)==0xF) && 1) return bfi(req, res); + if(((op & 0x1F)==0x16) && ((Rn & 0xF)==0xF) && 1) return bfc(req, res); + if(((op & 0x1F)==0x4) && 1) return mov_immediate(req, res); + if(((op & 0x1F)==0xC) && 1) return movt(req, res); + if(((op & 0x1F)==0x14) && 1) return sbfx(req, res); + if(((op & 0x1F)==0x1C) && 1) return ubfx(req, res); + if(((op & 0x1D)==0x10) && 1) return ssat(req, res); + if(((op & 0x1D)==0x18) && 1) return usat(req, res); + return undefined(req, res); +} + +// gen_crc: 9AE29DCD +int data_processing_register(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + uint32_t instr = req->instr_word32; + uint32_t op1 = (instr & 0xF00000)>>20; + uint32_t Rn = (instr & 0xF0000)>>16; + uint32_t check = (instr & 0xF000)>>12; + uint32_t op2 = (instr & 0xF0)>>4; + if(((op1 & 0xF)==0x0) && ((op2 & 0x8)==0x8) && !((Rn & 0xF)==0xF)) return sxtah(req, res); + if(((op1 & 0xF)==0x0) && ((op2 & 0x8)==0x8) && ((Rn & 0xF)==0xF)) return sxth(req, res); + if(((op1 & 0xF)==0x1) && ((op2 & 0x8)==0x8) && !((Rn & 0xF)==0xF)) return uxtah(req, res); + if(((op1 & 0xF)==0x1) && ((op2 & 0x8)==0x8) && ((Rn & 0xF)==0xF)) return uxth(req, res); + if(((op1 & 0xF)==0x2) && ((op2 & 0x8)==0x8) && !((Rn & 0xF)==0xF)) return sxtab16(req, res); + if(((op1 & 0xF)==0x2) && ((op2 & 0x8)==0x8) && ((Rn & 0xF)==0xF)) return sxtb16(req, res); + if(((op1 & 0xF)==0x3) && ((op2 & 0x8)==0x8) && !((Rn & 0xF)==0xF)) return uxtab16(req, res); + if(((op1 & 0xF)==0x3) && ((op2 & 0x8)==0x8) && ((Rn & 0xF)==0xF)) return uxtb16(req, res); + if(((op1 & 0xF)==0x4) && ((op2 & 0x8)==0x8) && !((Rn & 0xF)==0xF)) return sxtab(req, res); + if(((op1 & 0xF)==0x4) && ((op2 & 0x8)==0x8) && ((Rn & 0xF)==0xF)) return sxtb(req, res); + if(((op1 & 0xF)==0x5) && ((op2 & 0x8)==0x8) && !((Rn & 0xF)==0xF)) return uxtab(req, res); + if(((op1 & 0xF)==0x5) && ((op2 & 0x8)==0x8) && ((Rn & 0xF)==0xF)) return uxtb(req, res); + if(((op1 & 0xE)==0x0) && ((op2 & 0xF)==0x0) && 1) return lsl_register(req, res); + if(((op1 & 0xE)==0x2) && ((op2 & 0xF)==0x0) && 1) return lsr_register(req, res); + if(((op1 & 0xE)==0x4) && ((op2 & 0xF)==0x0) && 1) return asr_register(req, res); + if(((op1 & 0xE)==0x6) && ((op2 & 0xF)==0x0) && 1) return ror_register(req, res); + if(((op1 & 0xC)==0x8) && ((op2 & 0xC)==0x8) && 1) return misc_operations(req, res); + if(((op1 & 0x8)==0x8) && ((op2 & 0xC)==0x0) && 1) return parallel_add_sub_signed(req, res); + if(((op1 & 0x8)==0x8) && ((op2 & 0xC)==0x4) && 1) return parallel_add_sub_unsigned(req, res); + return undefined(req, res); +} + +// gen_crc: 1BBD93F3 +int data_processing_shifted_register(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + uint32_t instr = req->instr_word32; + uint32_t op = (instr & 0x1E00000)>>21; + uint32_t S = (instr & 0x100000)>>20; + uint32_t Rn = (instr & 0xF0000)>>16; + uint32_t wookie = (instr & 0x7FC0)>>6; + uint32_t type = (instr & 0x30)>>4; + if(((op & 0xF)==0x2) && ((Rn & 0xF)==0xF) && ((wookie & 0x1C3)==0x0) && ((type & 0x3)==0x0) && 1) return mov_register(req, res); + if(((op & 0xF)==0x2) && ((Rn & 0xF)==0xF) && !((wookie & 0x1C3)==0x0) && ((type & 0x3)==0x0) && 1) return lsl_immediate(req, res); + if(((op & 0xF)==0x2) && ((Rn & 0xF)==0xF) && ((wookie & 0x1C3)==0x0) && ((type & 0x3)==0x3) && 1) return rrx(req, res); + if(((op & 0xF)==0x2) && ((Rn & 0xF)==0xF) && !((wookie & 0x1C3)==0x0) && ((type & 0x3)==0x3) && 1) return ror_immediate(req, res); + if(((op & 0xF)==0x2) && ((Rn & 0xF)==0xF) && ((type & 0x3)==0x1) && 1) return lsr_immediate(req, res); + if(((op & 0xF)==0x2) && ((Rn & 0xF)==0xF) && ((type & 0x3)==0x2) && 1) return asr_immediate(req, res); + if(((op & 0xF)==0x0) && ((wookie & 0x3C)==0x3C) && ((S & 0x1)==0x0) && 1) return unpredictable(req, res); + if(((op & 0xF)==0x0) && ((wookie & 0x3C)==0x3C) && ((S & 0x1)==0x1) && 1) return tst_register(req, res); + if(((op & 0xF)==0x4) && ((wookie & 0x3C)==0x3C) && ((S & 0x1)==0x0) && 1) return unpredictable(req, res); + if(((op & 0xF)==0x4) && ((wookie & 0x3C)==0x3C) && ((S & 0x1)==0x1) && 1) return teq_register(req, res); + if(((op & 0xF)==0x8) && ((wookie & 0x3C)==0x3C) && ((S & 0x1)==0x1) && 1) return cmn_register(req, res); + if(((op & 0xF)==0xD) && ((wookie & 0x3C)==0x3C) && ((S & 0x1)==0x0) && 1) return unpredictable(req, res); + if(((op & 0xF)==0xD) && ((wookie & 0x3C)==0x3C) && ((S & 0x1)==0x1) && 1) return cmp_register(req, res); + if(((op & 0xF)==0x0) && !((wookie & 0x3C)==0x3C) && 1) return and_register(req, res); + if(((op & 0xF)==0x2) && !((Rn & 0xF)==0xF) && 1) return orr_register(req, res); + if(((op & 0xF)==0x3) && !((Rn & 0xF)==0xF) && 1) return orn_register(req, res); + if(((op & 0xF)==0x3) && ((Rn & 0xF)==0xF) && 1) return mvn_register(req, res); + if(((op & 0xF)==0x4) && !((wookie & 0x3C)==0x3C) && 1) return eor_register(req, res); + if(((op & 0xF)==0x8) && !((wookie & 0x3C)==0x3C) && 1) return add_register(req, res); + if(((op & 0xF)==0xD) && !((wookie & 0x3C)==0x3C) && 1) return sub_register(req, res); + if(((wookie & 0x3C)==0x3C) && ((S & 0x1)==0x0) && 1) return unpredictable(req, res); + if(((op & 0xF)==0x1) && 1) return bic_register(req, res); + if(((op & 0xF)==0x6) && 1) return pkh(req, res); + if(((op & 0xF)==0xA) && 1) return adc_register(req, res); + if(((op & 0xF)==0xB) && 1) return sbc_register(req, res); + if(((op & 0xF)==0xE) && 1) return rsb_register(req, res); + return undefined(req, res); +} + +// gen_crc: 9F789699 +int dbg(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + /* Encoding T1 */ + /* pattern="11110,0,111,01,0,(1)(1)(1)(1),10,(0),0,(0),000,1111,option.4" width=32 stringency=28 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFFF0D7F0)==0xF3A080F0)) { + res->instrSize = 32; + if(!((instr & 0xF2800)==0xF0000)) { + res->flags |= FLAG_UNPREDICTABLE; + } + if(!(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_option] = instr & 0xF; + res->fields_mask[FIELD_option >> 6] |= 1LL << (FIELD_option & 63); + char option_width = 4; + + static const instruction_format instr_formats[] = + { + { /* DBG<c> #<option> */ + "dbg", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_IMM,FIELD_option,FIELD_UNINIT,"#","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 1 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_DBG; + + /* pcode: nop */ + while(0); + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: 36813142 +int dmb(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + /* Encoding T1 */ + /* pattern="11110,0,111,01,1,(1)(1)(1)(1),10,(0),0,(1)(1)(1)(1),0101,barrier_option.4" width=32 stringency=28 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFFF0D0F0)==0xF3B08050)) { + res->instrSize = 32; + if(!((instr & 0xF2F00)==0xF0F00)) { + res->flags |= FLAG_UNPREDICTABLE; + } + if(!(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_barrier_option] = instr & 0xF; + res->fields_mask[FIELD_barrier_option >> 6] |= 1LL << (FIELD_barrier_option & 63); + char barrier_option_width = 4; + + static const instruction_format instr_formats[] = + { + { /* DMB<c> <barrier_option> */ + "dmb", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_BARRIER_OPTION,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 1 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_DMB; + + /* pcode: nop */ + while(0); + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: F94126C5 +int dsb(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + /* Encoding T1 */ + /* pattern="11110,0,111,01,1,(1)(1)(1)(1),10,(0),0,(1)(1)(1)(1),0100,barrier_option.4" width=32 stringency=28 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFFF0D0F0)==0xF3B08040)) { + res->instrSize = 32; + if(!((instr & 0xF2F00)==0xF0F00)) { + res->flags |= FLAG_UNPREDICTABLE; + } + if(!(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_barrier_option] = instr & 0xF; + res->fields_mask[FIELD_barrier_option >> 6] |= 1LL << (FIELD_barrier_option & 63); + char barrier_option_width = 4; + + static const instruction_format instr_formats[] = + { + { /* DSB<c> <barrier_option> */ + "dsb", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_BARRIER_OPTION,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 1 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_DSB; + + /* pcode: nop */ + while(0); + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: 9F4325CE +int enterx_leavex(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + /* Encoding T1 */ + /* pattern="11110011101,1,(1)(1)(1)(1),10,(0),0,(1)(1)(1)(1),000,1,(1)(1)(1)(1)" width=32 stringency=32 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFFF0D0F0)==0xF3B08010)) { + res->instrSize = 32; + if(!((instr & 0xF2F0F)==0xF0F0F)) { + res->flags |= FLAG_UNPREDICTABLE; + } + if(!(req->arch & ARCH_ThumbEE)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + static const instruction_format instr_formats[] = + { + { /* ENTERX */ + "enterx", /* .operation (const char *) */ + 0, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 0 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_ENTERX; + + /* pcode: if InITBlock() then NOT_PERMITTED */ + if(req->inIfThen == IFTHEN_YES) { + res->flags |= FLAG_NOTPERMITTED; + } + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* Encoding T1 */ + /* pattern="11110011101,1,(1)(1)(1)(1),10,(0),0,(1)(1)(1)(1),000,0,(1)(1)(1)(1)" width=32 stringency=32 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFFF0D0F0)==0xF3B08000)) { + res->instrSize = 32; + if(!((instr & 0xF2F0F)==0xF0F0F)) { + res->flags |= FLAG_UNPREDICTABLE; + } + if(!(req->arch & ARCH_ThumbEE)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + static const instruction_format instr_formats[] = + { + { /* LEAVEX */ + "leavex", /* .operation (const char *) */ + 0, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 0 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_LEAVEX; + + /* pcode: if InITBlock() then NOT_PERMITTED */ + if(req->inIfThen == IFTHEN_YES) { + res->flags |= FLAG_NOTPERMITTED; + } + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: 5063BADE +int eor_immediate(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + /* Encoding T1 */ + /* pattern="11110,i.1,0,0100,S.1,Rn.4,0,imm3.3,Rd.4,imm8.8" width=32 stringency=13 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFBE08000)==0xF0800000)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ARMv6T2) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_i] = (instr & 0x4000000)>>26; + res->fields_mask[FIELD_i >> 6] |= 1LL << (FIELD_i & 63); + char i_width = 1; + res->fields[FIELD_S] = (instr & 0x100000)>>20; + res->fields_mask[FIELD_S >> 6] |= 1LL << (FIELD_S & 63); + char S_width = 1; + res->fields[FIELD_Rn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Rn >> 6] |= 1LL << (FIELD_Rn & 63); + char Rn_width = 4; + res->fields[FIELD_imm3] = (instr & 0x7000)>>12; + res->fields_mask[FIELD_imm3 >> 6] |= 1LL << (FIELD_imm3 & 63); + char imm3_width = 3; + res->fields[FIELD_Rd] = (instr & 0xF00)>>8; + res->fields_mask[FIELD_Rd >> 6] |= 1LL << (FIELD_Rd & 63); + char Rd_width = 4; + res->fields[FIELD_imm8] = instr & 0xFF; + res->fields_mask[FIELD_imm8 >> 6] |= 1LL << (FIELD_imm8 & 63); + char imm8_width = 8; + + static const instruction_format instr_formats[] = + { + { /* EOR{S}<c> <Rd>,<Rn>,#<imm32> */ + "eor", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_OPTIONAL_STATUS, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rd,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rn,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_IMM,FIELD_imm32,FIELD_UNINIT,"#","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_EOR; + + /* pcode: if Rd == '1111' && S == '1' then SEE TEQ (immediate) */ + if(((res->fields[FIELD_Rd]) == (0xF)) && ((res->fields[FIELD_S]) == (0x1))) { + + return teq_immediate(req, res); + } + /* pcode: d = UInt(Rd) */ + res->fields[FIELD_d] = (res->fields[FIELD_Rd]); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: n = UInt(Rn) */ + res->fields[FIELD_n] = (res->fields[FIELD_Rn]); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: setflags = (S == '1') */ + res->fields[FIELD_setflags] = ((res->fields[FIELD_S]) == (0x1)); + res->fields_mask[FIELD_setflags >> 6] |= 1LL << (FIELD_setflags & 63); + /* pcode: (imm32, carry) = ThumbExpandImm_C(i:imm3:imm8, APSR.C) */ + res->fields[FIELD_imm32] = ThumbExpandImm_C_imm32((res->fields[FIELD_i]<<(8+3))|(res->fields[FIELD_imm3]<<8)|(res->fields[FIELD_imm8]), res->fields[FIELD_APSR_C]); + res->fields_mask[FIELD_imm32 >> 6] |= 1LL << (FIELD_imm32 & 63); + res->fields[FIELD_carry] = ThumbExpandImm_C_cout((res->fields[FIELD_i]<<(8+3))|(res->fields[FIELD_imm3]<<8)|(res->fields[FIELD_imm8]), res->fields[FIELD_APSR_C]); + res->fields_mask[FIELD_carry >> 6] |= 1LL << (FIELD_carry & 63); + /* TODO: handle ThumbExpandImm_C's possible setting of UNPREDICTABLE */ while(0); + /* pcode: if BadReg(d) || BadReg(n) then UNPREDICTABLE */ + if((BadReg(res->fields[FIELD_d])) || (BadReg(res->fields[FIELD_n]))) { + res->flags |= FLAG_UNPREDICTABLE; + } + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: 349692E1 +int eor_register(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + /* Encoding T1 */ + /* pattern="010000,0001,Rm.3,Rdn.3" width=16 stringency=10 */ + { + uint16_t instr = req->instr_word16; + if(((instr & 0xFFC0)==0x4040)) { + res->instrSize = 16; + if(!(req->arch & ARCH_ARMv4T) && !(req->arch & ARCH_ARMv5T) && !(req->arch & ARCH_ARMv6) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_Rm] = (instr & 0x38)>>3; + res->fields_mask[FIELD_Rm >> 6] |= 1LL << (FIELD_Rm & 63); + char Rm_width = 3; + res->fields[FIELD_Rdn] = instr & 0x7; + res->fields_mask[FIELD_Rdn >> 6] |= 1LL << (FIELD_Rdn & 63); + char Rdn_width = 3; + + static const instruction_format instr_formats[] = + { + { /* EORS <Rdn>,<Rm> */ + "eors", /* .operation (const char *) */ + 0, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rdn,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rm,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + { /* EOR<c> <Rdn>,<Rm> */ + "eor", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rdn,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rm,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 2; + res->mnem = armv7::ARMV7_EORS; + + /* pcode: d = UInt(Rdn) */ + res->fields[FIELD_d] = (res->fields[FIELD_Rdn]); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: n = UInt(Rdn) */ + res->fields[FIELD_n] = (res->fields[FIELD_Rdn]); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: m = UInt(Rm) */ + res->fields[FIELD_m] = (res->fields[FIELD_Rm]); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + /* pcode: setflags = !InITBlock() */ + res->fields[FIELD_setflags] = !(req->inIfThen == IFTHEN_YES); + res->fields_mask[FIELD_setflags >> 6] |= 1LL << (FIELD_setflags & 63); + /* pcode: (shift_t, shift_n) = (SRType_LSL, 0) */ + res->fields[FIELD_shift_t] = 0; + res->fields_mask[FIELD_shift_t >> 6] |= 1LL << (FIELD_shift_t & 63); + res->fields[FIELD_shift_n] = 0; + res->fields_mask[FIELD_shift_n >> 6] |= 1LL << (FIELD_shift_n & 63); + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* Encoding T2 */ + /* pattern="11101,01,0100,S.1,Rn.4,(0),imm3.3,Rd.4,imm2.2,type.2,Rm.4" width=32 stringency=13 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFFE00000)==0xEA800000)) { + res->instrSize = 32; + if(!((instr & 0x8000)==0x0)) { + res->flags |= FLAG_UNPREDICTABLE; + } + if(!(req->arch & ARCH_ARMv6T2) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_S] = (instr & 0x100000)>>20; + res->fields_mask[FIELD_S >> 6] |= 1LL << (FIELD_S & 63); + char S_width = 1; + res->fields[FIELD_Rn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Rn >> 6] |= 1LL << (FIELD_Rn & 63); + char Rn_width = 4; + res->fields[FIELD_imm3] = (instr & 0x7000)>>12; + res->fields_mask[FIELD_imm3 >> 6] |= 1LL << (FIELD_imm3 & 63); + char imm3_width = 3; + res->fields[FIELD_Rd] = (instr & 0xF00)>>8; + res->fields_mask[FIELD_Rd >> 6] |= 1LL << (FIELD_Rd & 63); + char Rd_width = 4; + res->fields[FIELD_imm2] = (instr & 0xC0)>>6; + res->fields_mask[FIELD_imm2 >> 6] |= 1LL << (FIELD_imm2 & 63); + char imm2_width = 2; + res->fields[FIELD_type] = (instr & 0x30)>>4; + res->fields_mask[FIELD_type >> 6] |= 1LL << (FIELD_type & 63); + char type_width = 2; + res->fields[FIELD_Rm] = instr & 0xF; + res->fields_mask[FIELD_Rm >> 6] |= 1LL << (FIELD_Rm & 63); + char Rm_width = 4; + + static const instruction_format instr_formats[] = + { + { /* EOR{S}<c> <Rd>,<Rn>,<Rm>{,<shift>} */ + "eor", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_OPTIONAL_STATUS, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rd,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rn,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rm,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_SHIFT,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 4 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_EOR; + + /* pcode: if Rd == '1111' && S == '1' then SEE TEQ (register) */ + if(((res->fields[FIELD_Rd]) == (0xF)) && ((res->fields[FIELD_S]) == (0x1))) { + + return teq_register(req, res); + } + /* pcode: d = UInt(Rd) */ + res->fields[FIELD_d] = (res->fields[FIELD_Rd]); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: n = UInt(Rn) */ + res->fields[FIELD_n] = (res->fields[FIELD_Rn]); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: m = UInt(Rm) */ + res->fields[FIELD_m] = (res->fields[FIELD_Rm]); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + /* pcode: setflags = (S == '1') */ + res->fields[FIELD_setflags] = ((res->fields[FIELD_S]) == (0x1)); + res->fields_mask[FIELD_setflags >> 6] |= 1LL << (FIELD_setflags & 63); + /* pcode: (shift_t, shift_n) = DecodeImmShift(type, imm3:imm2) */ + res->fields[FIELD_shift_t] = DecodeImmShift_shift_t(res->fields[FIELD_type], (res->fields[FIELD_imm3]<<2)|(res->fields[FIELD_imm2])); + res->fields_mask[FIELD_shift_t >> 6] |= 1LL << (FIELD_shift_t & 63); + res->fields[FIELD_shift_n] = DecodeImmShift_shift_n(res->fields[FIELD_type], (res->fields[FIELD_imm3]<<2)|(res->fields[FIELD_imm2])); + res->fields_mask[FIELD_shift_n >> 6] |= 1LL << (FIELD_shift_n & 63); + /* pcode: if BadReg(d) || BadReg(n) || BadReg(m) then UNPREDICTABLE */ + if(((BadReg(res->fields[FIELD_d])) || (BadReg(res->fields[FIELD_n]))) || (BadReg(res->fields[FIELD_m]))) { + res->flags |= FLAG_UNPREDICTABLE; + } + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: 8915EAD0 +int extension_reg_load_store(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + uint32_t instr = req->instr_word32; + uint32_t T = (instr & 0x10000000)>>28; + uint32_t Opcode = (instr & 0x1F00000)>>20; + uint32_t Rn = (instr & 0xF0000)>>16; + if(((Opcode & 0x1B)==0x12) && !((Rn & 0xF)==0xD)) return vstm(req, res); + if(((Opcode & 0x1B)==0x12) && ((Rn & 0xF)==0xD)) return vpush(req, res); + if(((Opcode & 0x1B)==0xB) && ((Rn & 0xF)==0xD)) return vpop(req, res); + if(((Opcode & 0x1B)==0xB) && !((Rn & 0xF)==0xD)) return vldm(req, res); + if(((Opcode & 0x1B)==0xB) && ((Rn & 0xF)==0xD)) return undefined(req, res); + if(((Opcode & 0x1E)==0x4) && 1) return xfer_64_core_ext_regs(req, res); + if(((Opcode & 0x1B)==0x8) && 1) return vstm(req, res); + if(((Opcode & 0x1B)==0xA) && 1) return vstm(req, res); + if(((Opcode & 0x1B)==0x9) && 1) return vldm(req, res); + if(((Opcode & 0x1B)==0x13) && 1) return vldm(req, res); + if(((Opcode & 0x13)==0x10) && 1) return vstr(req, res); + if(((Opcode & 0x13)==0x11) && 1) return vldr(req, res); + return undefined(req, res); +} + +// gen_crc: 82DAE323 +int hint_undoc(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + /* Encoding T1 */ + /* pattern="111,10,0111010,xxxx,10,x,0,x,op1.3,op2.8" width=32 stringency=16 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFFF0D000)==0xF3A08000)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ARMv6T2) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_op1] = (instr & 0x700)>>8; + res->fields_mask[FIELD_op1 >> 6] |= 1LL << (FIELD_op1 & 63); + char op1_width = 3; + res->fields[FIELD_op2] = instr & 0xFF; + res->fields_mask[FIELD_op2 >> 6] |= 1LL << (FIELD_op2 & 63); + char op2_width = 8; + + static const instruction_format instr_formats[] = + { + { /* HINT #<op2> */ + "hint", /* .operation (const char *) */ + 0, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_IMM,FIELD_op2,FIELD_UNINIT,"#","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 1 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_HINT; + + /* pcode: nop */ + while(0); + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: 1A6C8DC9 +int if_then_hints(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + uint16_t instr = req->instr_word16; + uint16_t opA = (instr & 0xF0)>>4; + uint16_t opB = instr & 0xF; + if(((opA & 0xF)==0x0) && ((opB & 0xF)==0x0)) return nop(req, res); + if(((opA & 0xF)==0x1) && ((opB & 0xF)==0x0)) return yield(req, res); + if(((opA & 0xF)==0x2) && ((opB & 0xF)==0x0)) return wfe(req, res); + if(((opA & 0xF)==0x3) && ((opB & 0xF)==0x0)) return wfi(req, res); + if(((opA & 0xF)==0x4) && ((opB & 0xF)==0x0)) return sev(req, res); + if(!((opB & 0xF)==0x0) && 1) return it(req, res); + if(1) return it_related_encodings(req, res); + return undefined(req, res); +} + +// gen_crc: 917C35E9 +int isb(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + /* Encoding T1 */ + /* pattern="11110,0,111,01,1,(1)(1)(1)(1),10,(0),0,(1)(1)(1)(1),0110,barrier_option.4" width=32 stringency=28 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFFF0D0F0)==0xF3B08060)) { + res->instrSize = 32; + if(!((instr & 0xF2F00)==0xF0F00)) { + res->flags |= FLAG_UNPREDICTABLE; + } + if(!(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_barrier_option] = instr & 0xF; + res->fields_mask[FIELD_barrier_option >> 6] |= 1LL << (FIELD_barrier_option & 63); + char barrier_option_width = 4; + + static const instruction_format instr_formats[] = + { + { /* ISB<c> <barrier_option> */ + "isb", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_BARRIER_OPTION,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 1 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_ISB; + + /* pcode: nop */ + while(0); + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: 94A81BC0 +int it(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + /* Encoding T1 */ + /* pattern="1011,1111,firstcond.4,mask.4" width=16 stringency=8 */ + { + uint16_t instr = req->instr_word16; + if(((instr & 0xFF00)==0xBF00)) { + res->instrSize = 16; + if(!(req->arch & ARCH_ARMv6T2) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_firstcond] = (instr & 0xF0)>>4; + res->fields_mask[FIELD_firstcond >> 6] |= 1LL << (FIELD_firstcond & 63); + char firstcond_width = 4; + res->fields[FIELD_mask] = instr & 0xF; + res->fields_mask[FIELD_mask >> 6] |= 1LL << (FIELD_mask & 63); + char mask_width = 4; + + static const instruction_format instr_formats[] = + { + { /* IT<mask> <firstcond> */ + "it", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_MASK, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_FIRSTCOND,FIELD_firstcond,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 1 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_IT; + + /* pcode: if mask == '0000' then SEE it_related_encodings */ + if((res->fields[FIELD_mask]) == (0x0)) { + + return it_related_encodings(req, res); + } + /* pcode: if firstcond == '1111' then UNPREDICTABLE */ + if((res->fields[FIELD_firstcond]) == (0xF)) { + res->flags |= FLAG_UNPREDICTABLE; + } + /* pcode: if firstcond == '1110' && BitCount(mask) != 1 then UNPREDICTABLE */ + if(((res->fields[FIELD_firstcond]) == (0xE)) && ((BitCount(res->fields[FIELD_mask])) != (1))) { + res->flags |= FLAG_UNPREDICTABLE; + } + /* pcode: if InITBlock() then UNPREDICTABLE */ + if(req->inIfThen == IFTHEN_YES) { + res->flags |= FLAG_UNPREDICTABLE; + } + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: 076F0D41 +int it_related_encodings(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + /* Encoding T1 */ + /* pattern="1011,1111,imm.4,xxxx" width=16 stringency=8 */ + { + uint16_t instr = req->instr_word16; + if(((instr & 0xFF00)==0xBF00)) { + res->instrSize = 16; + if(!(req->arch & ARCH_ARMv6T2) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_imm] = (instr & 0xF0)>>4; + res->fields_mask[FIELD_imm >> 6] |= 1LL << (FIELD_imm & 63); + char imm_width = 4; + + static const instruction_format instr_formats[] = + { + { /* HINT #<imm> */ + "hint", /* .operation (const char *) */ + 0, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_IMM,FIELD_imm,FIELD_UNINIT,"#","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 1 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_HINT; + + /* pcode: nop */ + while(0); + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: B0DE7858 +int lda(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + /* Encoding T1 */ + /* pattern="11101,000110,1,Rn.4,Rt.4,(1)(1)(1)(1),1010,(1)(1)(1)(1)" width=32 stringency=24 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFFF000F0)==0xE8D000A0)) { + res->instrSize = 32; + if(!((instr & 0xF0F)==0xF0F)) { + res->flags |= FLAG_UNPREDICTABLE; + } + if(!(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_Rn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Rn >> 6] |= 1LL << (FIELD_Rn & 63); + char Rn_width = 4; + res->fields[FIELD_Rt] = (instr & 0xF000)>>12; + res->fields_mask[FIELD_Rt >> 6] |= 1LL << (FIELD_Rt & 63); + char Rt_width = 4; + + static const instruction_format instr_formats[] = + { + { /* LDA<c> <Rt>,[<Rn>] */ + "lda", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rt,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_MEMORY_ONE_REG,FIELD_Rn,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_LDA; + + /* pcode: t = UInt(Rt) */ + res->fields[FIELD_t] = (res->fields[FIELD_Rt]); + res->fields_mask[FIELD_t >> 6] |= 1LL << (FIELD_t & 63); + /* pcode: n = UInt(Rn) */ + res->fields[FIELD_n] = (res->fields[FIELD_Rn]); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: if BadReg(t) || n == 15 then UNPREDICTABLE */ + if((BadReg(res->fields[FIELD_t])) || ((res->fields[FIELD_n]) == (15))) { + res->flags |= FLAG_UNPREDICTABLE; + } + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: 9C05D1D0 +int ldab(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + /* Encoding T1 */ + /* pattern="11101,000110,1,Rn.4,Rt.4,(1)(1)(1)(1),1000,(1)(1)(1)(1)" width=32 stringency=24 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFFF000F0)==0xE8D00080)) { + res->instrSize = 32; + if(!((instr & 0xF0F)==0xF0F)) { + res->flags |= FLAG_UNPREDICTABLE; + } + if(!(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_Rn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Rn >> 6] |= 1LL << (FIELD_Rn & 63); + char Rn_width = 4; + res->fields[FIELD_Rt] = (instr & 0xF000)>>12; + res->fields_mask[FIELD_Rt >> 6] |= 1LL << (FIELD_Rt & 63); + char Rt_width = 4; + + static const instruction_format instr_formats[] = + { + { /* LDAB<c> <Rt>,[<Rn>] */ + "ldab", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rt,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_MEMORY_ONE_REG,FIELD_Rn,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_LDAB; + + /* pcode: t = UInt(Rt) */ + res->fields[FIELD_t] = (res->fields[FIELD_Rt]); + res->fields_mask[FIELD_t >> 6] |= 1LL << (FIELD_t & 63); + /* pcode: n = UInt(Rn) */ + res->fields[FIELD_n] = (res->fields[FIELD_Rn]); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: if BadReg(t) || n == 15 then UNPREDICTABLE */ + if((BadReg(res->fields[FIELD_t])) || ((res->fields[FIELD_n]) == (15))) { + res->flags |= FLAG_UNPREDICTABLE; + } + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: 9CB16A91 +int ldaex(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + /* Encoding T1 */ + /* pattern="11101,000110,1,Rn.4,Rt.4,(1)(1)(1)(1),1110,(1)(1)(1)(1)" width=32 stringency=24 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFFF000F0)==0xE8D000E0)) { + res->instrSize = 32; + if(!((instr & 0xF0F)==0xF0F)) { + res->flags |= FLAG_UNPREDICTABLE; + } + if(!(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_Rn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Rn >> 6] |= 1LL << (FIELD_Rn & 63); + char Rn_width = 4; + res->fields[FIELD_Rt] = (instr & 0xF000)>>12; + res->fields_mask[FIELD_Rt >> 6] |= 1LL << (FIELD_Rt & 63); + char Rt_width = 4; + + static const instruction_format instr_formats[] = + { + { /* LDAEX<c> <Rt>,[<Rn>] */ + "ldaex", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rt,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_MEMORY_ONE_REG,FIELD_Rn,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_LDAEX; + + /* pcode: t = UInt(Rt) */ + res->fields[FIELD_t] = (res->fields[FIELD_Rt]); + res->fields_mask[FIELD_t >> 6] |= 1LL << (FIELD_t & 63); + /* pcode: n = UInt(Rn) */ + res->fields[FIELD_n] = (res->fields[FIELD_Rn]); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: if BadReg(t) || n == 15 then UNPREDICTABLE */ + if((BadReg(res->fields[FIELD_t])) || ((res->fields[FIELD_n]) == (15))) { + res->flags |= FLAG_UNPREDICTABLE; + } + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: 4B65B815 +int ldaexb(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + /* Encoding T1 */ + /* pattern="11101,000110,1,Rn.4,Rt.4,(1)(1)(1)(1),1100,(1)(1)(1)(1)" width=32 stringency=24 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFFF000F0)==0xE8D000C0)) { + res->instrSize = 32; + if(!((instr & 0xF0F)==0xF0F)) { + res->flags |= FLAG_UNPREDICTABLE; + } + if(!(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_Rn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Rn >> 6] |= 1LL << (FIELD_Rn & 63); + char Rn_width = 4; + res->fields[FIELD_Rt] = (instr & 0xF000)>>12; + res->fields_mask[FIELD_Rt >> 6] |= 1LL << (FIELD_Rt & 63); + char Rt_width = 4; + + static const instruction_format instr_formats[] = + { + { /* LDAEXB<c> <Rt>,[<Rn>] */ + "ldaexb", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rt,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_MEMORY_ONE_REG,FIELD_Rn,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_LDAEXB; + + /* pcode: t = UInt(Rt) */ + res->fields[FIELD_t] = (res->fields[FIELD_Rt]); + res->fields_mask[FIELD_t >> 6] |= 1LL << (FIELD_t & 63); + /* pcode: n = UInt(Rn) */ + res->fields[FIELD_n] = (res->fields[FIELD_Rn]); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: if BadReg(t) || n == 15 then UNPREDICTABLE */ + if((BadReg(res->fields[FIELD_t])) || ((res->fields[FIELD_n]) == (15))) { + res->flags |= FLAG_UNPREDICTABLE; + } + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: AA50FA44 +int ldaexh(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + /* Encoding T1 */ + /* pattern="11101,000110,1,Rn.4,Rt.4,(1)(1)(1)(1),1101,(1)(1)(1)(1)" width=32 stringency=24 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFFF000F0)==0xE8D000D0)) { + res->instrSize = 32; + if(!((instr & 0xF0F)==0xF0F)) { + res->flags |= FLAG_UNPREDICTABLE; + } + if(!(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_Rn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Rn >> 6] |= 1LL << (FIELD_Rn & 63); + char Rn_width = 4; + res->fields[FIELD_Rt] = (instr & 0xF000)>>12; + res->fields_mask[FIELD_Rt >> 6] |= 1LL << (FIELD_Rt & 63); + char Rt_width = 4; + + static const instruction_format instr_formats[] = + { + { /* LDAEXH<c> <Rt>,[<Rn>] */ + "ldaexh", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rt,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_MEMORY_ONE_REG,FIELD_Rn,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_LDAEXH; + + /* pcode: t = UInt(Rt) */ + res->fields[FIELD_t] = (res->fields[FIELD_Rt]); + res->fields_mask[FIELD_t >> 6] |= 1LL << (FIELD_t & 63); + /* pcode: n = UInt(Rn) */ + res->fields[FIELD_n] = (res->fields[FIELD_Rn]); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: if BadReg(t) || n == 15 then UNPREDICTABLE */ + if((BadReg(res->fields[FIELD_t])) || ((res->fields[FIELD_n]) == (15))) { + res->flags |= FLAG_UNPREDICTABLE; + } + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: 7D309381 +int ldah(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + /* Encoding T1 */ + /* pattern="11101,000110,1,Rn.4,Rt.4,(1)(1)(1)(1),1001,(1)(1)(1)(1)" width=32 stringency=24 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFFF000F0)==0xE8D00090)) { + res->instrSize = 32; + if(!((instr & 0xF0F)==0xF0F)) { + res->flags |= FLAG_UNPREDICTABLE; + } + if(!(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_Rn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Rn >> 6] |= 1LL << (FIELD_Rn & 63); + char Rn_width = 4; + res->fields[FIELD_Rt] = (instr & 0xF000)>>12; + res->fields_mask[FIELD_Rt >> 6] |= 1LL << (FIELD_Rt & 63); + char Rt_width = 4; + + static const instruction_format instr_formats[] = + { + { /* LDAH<c> <Rt>,[<Rn>] */ + "ldah", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rt,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_MEMORY_ONE_REG,FIELD_Rn,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_LDAH; + + /* pcode: t = UInt(Rt) */ + res->fields[FIELD_t] = (res->fields[FIELD_Rt]); + res->fields_mask[FIELD_t >> 6] |= 1LL << (FIELD_t & 63); + /* pcode: n = UInt(Rn) */ + res->fields[FIELD_n] = (res->fields[FIELD_Rn]); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: if BadReg(t) || n == 15 then UNPREDICTABLE */ + if((BadReg(res->fields[FIELD_t])) || ((res->fields[FIELD_n]) == (15))) { + res->flags |= FLAG_UNPREDICTABLE; + } + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: 8E052AF0 +int ldc_immediate(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + /* Encoding T1 */ + /* pattern="1110,110,P.1,U.1,0,W.1,1,Rn.4,CRd.4,coproc.4,imm8.8" width=32 stringency=12 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFE500000)==0xEC100000)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ARMv6T2) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_P] = (instr & 0x1000000)>>24; + res->fields_mask[FIELD_P >> 6] |= 1LL << (FIELD_P & 63); + char P_width = 1; + res->fields[FIELD_U] = (instr & 0x800000)>>23; + res->fields_mask[FIELD_U >> 6] |= 1LL << (FIELD_U & 63); + char U_width = 1; + res->fields[FIELD_W] = (instr & 0x200000)>>21; + res->fields_mask[FIELD_W >> 6] |= 1LL << (FIELD_W & 63); + char W_width = 1; + res->fields[FIELD_Rn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Rn >> 6] |= 1LL << (FIELD_Rn & 63); + char Rn_width = 4; + res->fields[FIELD_CRd] = (instr & 0xF000)>>12; + res->fields_mask[FIELD_CRd >> 6] |= 1LL << (FIELD_CRd & 63); + char CRd_width = 4; + res->fields[FIELD_coproc] = (instr & 0xF00)>>8; + res->fields_mask[FIELD_coproc >> 6] |= 1LL << (FIELD_coproc & 63); + char coproc_width = 4; + res->fields[FIELD_imm8] = instr & 0xFF; + res->fields_mask[FIELD_imm8 >> 6] |= 1LL << (FIELD_imm8 & 63); + char imm8_width = 8; + + static const instruction_format instr_formats[] = + { + { /* LDC<c> <coproc>,<CRd>,[<Rn>{,#<+/-><imm32>}] */ + "ldc", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_COPROC,FIELD_coproc,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_COPROC_REG,FIELD_CRd,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_MEMORY_ONE_REG_OPTIONAL_ADD_IMM,FIELD_Rn,FIELD_imm32,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + { /* LDC<c> <coproc>,<CRd>,[<Rn>,#<+/-><imm32>]! */ + "ldc", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_COPROC,FIELD_coproc,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_COPROC_REG,FIELD_CRd,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_MEMORY_ONE_REG_ADD_IMM,FIELD_Rn,FIELD_imm32,"","",WRITEBACK_YES}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + { /* LDC<c> <coproc>,<CRd>,[<Rn>],#<+/-><imm32> */ + "ldc", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_COPROC,FIELD_coproc,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_COPROC_REG,FIELD_CRd,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_MEMORY_ONE_REG,FIELD_Rn,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_ADD_IMM,FIELD_imm32,FIELD_UNINIT,"#","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 4 /* .operandCount */ + }, + { /* LDC<c> <coproc>,<CRd>,[<Rn>],<coproc_option> */ + "ldc", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_COPROC,FIELD_coproc,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_COPROC_REG,FIELD_CRd,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_MEMORY_ONE_REG,FIELD_Rn,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_IMM,FIELD_imm8,FIELD_UNINIT,"{","}",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 4 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 4; + res->mnem = armv7::ARMV7_LDC; + + /* pcode: D=0 */ + res->fields[FIELD_D] = 0; + res->fields_mask[FIELD_D >> 6] |= 1LL << (FIELD_D & 63); + /* pcode: if Rn == '1111' then SEE LDC (literal) */ + if((res->fields[FIELD_Rn]) == (0xF)) { + + return ldc_literal(req, res); + } + /* pcode: if P == '0' && U == '0' && D == '0' && W == '0' then UNDEFINED */ + if(((((res->fields[FIELD_P]) == (0x0)) && ((res->fields[FIELD_U]) == (0x0))) && ((res->fields[FIELD_D]) == (0x0))) && ((res->fields[FIELD_W]) == (0x0))) { + res->status |= STATUS_UNDEFINED; + } + /* pcode: if P == '0' && U == '0' && D == '1' && W == '0' then SEE MRRC, MRRC2 */ + if(((((res->fields[FIELD_P]) == (0x0)) && ((res->fields[FIELD_U]) == (0x0))) && ((res->fields[FIELD_D]) == (0x1))) && ((res->fields[FIELD_W]) == (0x0))) { + + return mrrc_mrrc2(req, res); + } + /* pcode: if coproc == '1010' || coproc == '1011' then SEE "nop" */ + if(((res->fields[FIELD_coproc]) == (0xA)) || ((res->fields[FIELD_coproc]) == (0xB))) { + + return nop(req, res); + } + /* pcode: n = UInt(Rn) */ + res->fields[FIELD_n] = (res->fields[FIELD_Rn]); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: cp = UInt(coproc) */ + res->fields[FIELD_cp] = (res->fields[FIELD_coproc]); + res->fields_mask[FIELD_cp >> 6] |= 1LL << (FIELD_cp & 63); + /* pcode: imm32 = ZeroExtend(imm8:'00', 32) */ + res->fields[FIELD_imm32] = (res->fields[FIELD_imm8]<<2)|(0x0); + res->fields_mask[FIELD_imm32 >> 6] |= 1LL << (FIELD_imm32 & 63); + /* pcode: index = (P == '1') */ + res->fields[FIELD_index] = ((res->fields[FIELD_P]) == (0x1)); + res->fields_mask[FIELD_index >> 6] |= 1LL << (FIELD_index & 63); + /* pcode: add = (U == '1') */ + res->fields[FIELD_add] = ((res->fields[FIELD_U]) == (0x1)); + res->fields_mask[FIELD_add >> 6] |= 1LL << (FIELD_add & 63); + /* pcode: wback = (W == '1') */ + res->fields[FIELD_wback] = ((res->fields[FIELD_W]) == (0x1)); + res->fields_mask[FIELD_wback >> 6] |= 1LL << (FIELD_wback & 63); + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* Encoding T1L */ + /* pattern="1110,110,P.1,U.1,1,W.1,1,Rn.4,CRd.4,coproc.4,imm8.8" width=32 stringency=12 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFE500000)==0xEC500000)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ARMv6T2) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_P] = (instr & 0x1000000)>>24; + res->fields_mask[FIELD_P >> 6] |= 1LL << (FIELD_P & 63); + char P_width = 1; + res->fields[FIELD_U] = (instr & 0x800000)>>23; + res->fields_mask[FIELD_U >> 6] |= 1LL << (FIELD_U & 63); + char U_width = 1; + res->fields[FIELD_W] = (instr & 0x200000)>>21; + res->fields_mask[FIELD_W >> 6] |= 1LL << (FIELD_W & 63); + char W_width = 1; + res->fields[FIELD_Rn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Rn >> 6] |= 1LL << (FIELD_Rn & 63); + char Rn_width = 4; + res->fields[FIELD_CRd] = (instr & 0xF000)>>12; + res->fields_mask[FIELD_CRd >> 6] |= 1LL << (FIELD_CRd & 63); + char CRd_width = 4; + res->fields[FIELD_coproc] = (instr & 0xF00)>>8; + res->fields_mask[FIELD_coproc >> 6] |= 1LL << (FIELD_coproc & 63); + char coproc_width = 4; + res->fields[FIELD_imm8] = instr & 0xFF; + res->fields_mask[FIELD_imm8 >> 6] |= 1LL << (FIELD_imm8 & 63); + char imm8_width = 8; + + static const instruction_format instr_formats[] = + { + { /* LDCL<c> <coproc>,<CRd>,[<Rn>{,#<+/-><imm32>}] */ + "ldcl", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_COPROC,FIELD_coproc,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_COPROC_REG,FIELD_CRd,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_MEMORY_ONE_REG_OPTIONAL_ADD_IMM,FIELD_Rn,FIELD_imm32,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + { /* LDCL<c> <coproc>,<CRd>,[<Rn>,#<+/-><imm32>]! */ + "ldcl", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_COPROC,FIELD_coproc,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_COPROC_REG,FIELD_CRd,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_MEMORY_ONE_REG_ADD_IMM,FIELD_Rn,FIELD_imm32,"","",WRITEBACK_YES}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + { /* LDCL<c> <coproc>,<CRd>,[<Rn>],#<+/-><imm32> */ + "ldcl", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_COPROC,FIELD_coproc,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_COPROC_REG,FIELD_CRd,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_MEMORY_ONE_REG,FIELD_Rn,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_ADD_IMM,FIELD_imm32,FIELD_UNINIT,"#","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 4 /* .operandCount */ + }, + { /* LDCL<c> <coproc>,<CRd>,[<Rn>],<coproc_option> */ + "ldcl", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_COPROC,FIELD_coproc,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_COPROC_REG,FIELD_CRd,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_MEMORY_ONE_REG,FIELD_Rn,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_IMM,FIELD_imm8,FIELD_UNINIT,"{","}",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 4 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 4; + res->mnem = armv7::ARMV7_LDCL; + + /* pcode: D=1 */ + res->fields[FIELD_D] = 1; + res->fields_mask[FIELD_D >> 6] |= 1LL << (FIELD_D & 63); + /* pcode: if Rn == '1111' then SEE LDC (literal) */ + if((res->fields[FIELD_Rn]) == (0xF)) { + + return ldc_literal(req, res); + } + /* pcode: if P == '0' && U == '0' && D == '0' && W == '0' then UNDEFINED */ + if(((((res->fields[FIELD_P]) == (0x0)) && ((res->fields[FIELD_U]) == (0x0))) && ((res->fields[FIELD_D]) == (0x0))) && ((res->fields[FIELD_W]) == (0x0))) { + res->status |= STATUS_UNDEFINED; + } + /* pcode: if P == '0' && U == '0' && D == '1' && W == '0' then SEE MRRC, MRRC2 */ + if(((((res->fields[FIELD_P]) == (0x0)) && ((res->fields[FIELD_U]) == (0x0))) && ((res->fields[FIELD_D]) == (0x1))) && ((res->fields[FIELD_W]) == (0x0))) { + + return mrrc_mrrc2(req, res); + } + /* pcode: if coproc == '1010' || coproc == '1011' then SEE "nop" */ + if(((res->fields[FIELD_coproc]) == (0xA)) || ((res->fields[FIELD_coproc]) == (0xB))) { + + return nop(req, res); + } + /* pcode: n = UInt(Rn) */ + res->fields[FIELD_n] = (res->fields[FIELD_Rn]); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: cp = UInt(coproc) */ + res->fields[FIELD_cp] = (res->fields[FIELD_coproc]); + res->fields_mask[FIELD_cp >> 6] |= 1LL << (FIELD_cp & 63); + /* pcode: imm32 = ZeroExtend(imm8:'00', 32) */ + res->fields[FIELD_imm32] = (res->fields[FIELD_imm8]<<2)|(0x0); + res->fields_mask[FIELD_imm32 >> 6] |= 1LL << (FIELD_imm32 & 63); + /* pcode: index = (P == '1') */ + res->fields[FIELD_index] = ((res->fields[FIELD_P]) == (0x1)); + res->fields_mask[FIELD_index >> 6] |= 1LL << (FIELD_index & 63); + /* pcode: add = (U == '1') */ + res->fields[FIELD_add] = ((res->fields[FIELD_U]) == (0x1)); + res->fields_mask[FIELD_add >> 6] |= 1LL << (FIELD_add & 63); + /* pcode: wback = (W == '1') */ + res->fields[FIELD_wback] = ((res->fields[FIELD_W]) == (0x1)); + res->fields_mask[FIELD_wback >> 6] |= 1LL << (FIELD_wback & 63); + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* Encoding T2 */ + /* pattern="1111,110,P.1,U.1,0,W.1,1,Rn.4,CRd.4,coproc.4,imm8.8" width=32 stringency=12 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFE500000)==0xFC100000)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ARMv6T2) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_P] = (instr & 0x1000000)>>24; + res->fields_mask[FIELD_P >> 6] |= 1LL << (FIELD_P & 63); + char P_width = 1; + res->fields[FIELD_U] = (instr & 0x800000)>>23; + res->fields_mask[FIELD_U >> 6] |= 1LL << (FIELD_U & 63); + char U_width = 1; + res->fields[FIELD_W] = (instr & 0x200000)>>21; + res->fields_mask[FIELD_W >> 6] |= 1LL << (FIELD_W & 63); + char W_width = 1; + res->fields[FIELD_Rn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Rn >> 6] |= 1LL << (FIELD_Rn & 63); + char Rn_width = 4; + res->fields[FIELD_CRd] = (instr & 0xF000)>>12; + res->fields_mask[FIELD_CRd >> 6] |= 1LL << (FIELD_CRd & 63); + char CRd_width = 4; + res->fields[FIELD_coproc] = (instr & 0xF00)>>8; + res->fields_mask[FIELD_coproc >> 6] |= 1LL << (FIELD_coproc & 63); + char coproc_width = 4; + res->fields[FIELD_imm8] = instr & 0xFF; + res->fields_mask[FIELD_imm8 >> 6] |= 1LL << (FIELD_imm8 & 63); + char imm8_width = 8; + + static const instruction_format instr_formats[] = + { + { /* LDC2<c> <coproc>,<CRd>,[<Rn>{,#<+/-><imm32>}] */ + "ldc2", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_COPROC,FIELD_coproc,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_COPROC_REG,FIELD_CRd,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_MEMORY_ONE_REG_OPTIONAL_ADD_IMM,FIELD_Rn,FIELD_imm32,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + { /* LDC2<c> <coproc>,<CRd>,[<Rn>,#<+/-><imm32>]! */ + "ldc2", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_COPROC,FIELD_coproc,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_COPROC_REG,FIELD_CRd,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_MEMORY_ONE_REG_ADD_IMM,FIELD_Rn,FIELD_imm32,"","",WRITEBACK_YES}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + { /* LDC2<c> <coproc>,<CRd>,[<Rn>],#<+/-><imm32> */ + "ldc2", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_COPROC,FIELD_coproc,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_COPROC_REG,FIELD_CRd,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_MEMORY_ONE_REG,FIELD_Rn,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_ADD_IMM,FIELD_imm32,FIELD_UNINIT,"#","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 4 /* .operandCount */ + }, + { /* LDC2<c> <coproc>,<CRd>,[<Rn>],<coproc_option> */ + "ldc2", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_COPROC,FIELD_coproc,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_COPROC_REG,FIELD_CRd,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_MEMORY_ONE_REG,FIELD_Rn,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_IMM,FIELD_imm8,FIELD_UNINIT,"{","}",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 4 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 4; + res->mnem = armv7::ARMV7_LDC2; + + /* pcode: D=0 */ + res->fields[FIELD_D] = 0; + res->fields_mask[FIELD_D >> 6] |= 1LL << (FIELD_D & 63); + /* pcode: if Rn == '1111' then SEE LDC (literal) */ + if((res->fields[FIELD_Rn]) == (0xF)) { + + return ldc_literal(req, res); + } + /* pcode: if P == '0' && U == '0' && D == '0' && W == '0' then UNDEFINED */ + if(((((res->fields[FIELD_P]) == (0x0)) && ((res->fields[FIELD_U]) == (0x0))) && ((res->fields[FIELD_D]) == (0x0))) && ((res->fields[FIELD_W]) == (0x0))) { + res->status |= STATUS_UNDEFINED; + } + /* pcode: if P == '0' && U == '0' && D == '1' && W == '0' then SEE MRRC, MRRC2 */ + if(((((res->fields[FIELD_P]) == (0x0)) && ((res->fields[FIELD_U]) == (0x0))) && ((res->fields[FIELD_D]) == (0x1))) && ((res->fields[FIELD_W]) == (0x0))) { + + return mrrc_mrrc2(req, res); + } + /* pcode: n = UInt(Rn) */ + res->fields[FIELD_n] = (res->fields[FIELD_Rn]); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: cp = UInt(coproc) */ + res->fields[FIELD_cp] = (res->fields[FIELD_coproc]); + res->fields_mask[FIELD_cp >> 6] |= 1LL << (FIELD_cp & 63); + /* pcode: imm32 = ZeroExtend(imm8:'00', 32) */ + res->fields[FIELD_imm32] = (res->fields[FIELD_imm8]<<2)|(0x0); + res->fields_mask[FIELD_imm32 >> 6] |= 1LL << (FIELD_imm32 & 63); + /* pcode: index = (P == '1') */ + res->fields[FIELD_index] = ((res->fields[FIELD_P]) == (0x1)); + res->fields_mask[FIELD_index >> 6] |= 1LL << (FIELD_index & 63); + /* pcode: add = (U == '1') */ + res->fields[FIELD_add] = ((res->fields[FIELD_U]) == (0x1)); + res->fields_mask[FIELD_add >> 6] |= 1LL << (FIELD_add & 63); + /* pcode: wback = (W == '1') */ + res->fields[FIELD_wback] = ((res->fields[FIELD_W]) == (0x1)); + res->fields_mask[FIELD_wback >> 6] |= 1LL << (FIELD_wback & 63); + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* Encoding T2L */ + /* pattern="1111,110,P.1,U.1,1,W.1,1,Rn.4,CRd.4,coproc.4,imm8.8" width=32 stringency=12 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFE500000)==0xFC500000)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ARMv6T2) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_P] = (instr & 0x1000000)>>24; + res->fields_mask[FIELD_P >> 6] |= 1LL << (FIELD_P & 63); + char P_width = 1; + res->fields[FIELD_U] = (instr & 0x800000)>>23; + res->fields_mask[FIELD_U >> 6] |= 1LL << (FIELD_U & 63); + char U_width = 1; + res->fields[FIELD_W] = (instr & 0x200000)>>21; + res->fields_mask[FIELD_W >> 6] |= 1LL << (FIELD_W & 63); + char W_width = 1; + res->fields[FIELD_Rn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Rn >> 6] |= 1LL << (FIELD_Rn & 63); + char Rn_width = 4; + res->fields[FIELD_CRd] = (instr & 0xF000)>>12; + res->fields_mask[FIELD_CRd >> 6] |= 1LL << (FIELD_CRd & 63); + char CRd_width = 4; + res->fields[FIELD_coproc] = (instr & 0xF00)>>8; + res->fields_mask[FIELD_coproc >> 6] |= 1LL << (FIELD_coproc & 63); + char coproc_width = 4; + res->fields[FIELD_imm8] = instr & 0xFF; + res->fields_mask[FIELD_imm8 >> 6] |= 1LL << (FIELD_imm8 & 63); + char imm8_width = 8; + + static const instruction_format instr_formats[] = + { + { /* LDC2L<c> <coproc>,<CRd>,[<Rn>{,#<+/-><imm32>}] */ + "ldc2l", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_COPROC,FIELD_coproc,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_COPROC_REG,FIELD_CRd,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_MEMORY_ONE_REG_OPTIONAL_ADD_IMM,FIELD_Rn,FIELD_imm32,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + { /* LDC2L<c> <coproc>,<CRd>,[<Rn>,#<+/-><imm32>]! */ + "ldc2l", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_COPROC,FIELD_coproc,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_COPROC_REG,FIELD_CRd,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_MEMORY_ONE_REG_ADD_IMM,FIELD_Rn,FIELD_imm32,"","",WRITEBACK_YES}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + { /* LDC2L<c> <coproc>,<CRd>,[<Rn>],#<+/-><imm32> */ + "ldc2l", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_COPROC,FIELD_coproc,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_COPROC_REG,FIELD_CRd,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_MEMORY_ONE_REG,FIELD_Rn,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_ADD_IMM,FIELD_imm32,FIELD_UNINIT,"#","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 4 /* .operandCount */ + }, + { /* LDC2L<c> <coproc>,<CRd>,[<Rn>],<imm8> */ + "ldc2l", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_COPROC,FIELD_coproc,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_COPROC_REG,FIELD_CRd,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_MEMORY_ONE_REG,FIELD_Rn,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_IMM,FIELD_imm8,FIELD_UNINIT,"#","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 4 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 4; + res->mnem = armv7::ARMV7_LDC2L; + + /* pcode: D=1 */ + res->fields[FIELD_D] = 1; + res->fields_mask[FIELD_D >> 6] |= 1LL << (FIELD_D & 63); + /* pcode: if Rn == '1111' then SEE LDC (literal) */ + if((res->fields[FIELD_Rn]) == (0xF)) { + + return ldc_literal(req, res); + } + /* pcode: if P == '0' && U == '0' && D == '0' && W == '0' then UNDEFINED */ + if(((((res->fields[FIELD_P]) == (0x0)) && ((res->fields[FIELD_U]) == (0x0))) && ((res->fields[FIELD_D]) == (0x0))) && ((res->fields[FIELD_W]) == (0x0))) { + res->status |= STATUS_UNDEFINED; + } + /* pcode: if P == '0' && U == '0' && D == '1' && W == '0' then SEE MRRC, MRRC2 */ + if(((((res->fields[FIELD_P]) == (0x0)) && ((res->fields[FIELD_U]) == (0x0))) && ((res->fields[FIELD_D]) == (0x1))) && ((res->fields[FIELD_W]) == (0x0))) { + + return mrrc_mrrc2(req, res); + } + /* pcode: n = UInt(Rn) */ + res->fields[FIELD_n] = (res->fields[FIELD_Rn]); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: cp = UInt(coproc) */ + res->fields[FIELD_cp] = (res->fields[FIELD_coproc]); + res->fields_mask[FIELD_cp >> 6] |= 1LL << (FIELD_cp & 63); + /* pcode: imm32 = ZeroExtend(imm8:'00', 32) */ + res->fields[FIELD_imm32] = (res->fields[FIELD_imm8]<<2)|(0x0); + res->fields_mask[FIELD_imm32 >> 6] |= 1LL << (FIELD_imm32 & 63); + /* pcode: index = (P == '1') */ + res->fields[FIELD_index] = ((res->fields[FIELD_P]) == (0x1)); + res->fields_mask[FIELD_index >> 6] |= 1LL << (FIELD_index & 63); + /* pcode: add = (U == '1') */ + res->fields[FIELD_add] = ((res->fields[FIELD_U]) == (0x1)); + res->fields_mask[FIELD_add >> 6] |= 1LL << (FIELD_add & 63); + /* pcode: wback = (W == '1') */ + res->fields[FIELD_wback] = ((res->fields[FIELD_W]) == (0x1)); + res->fields_mask[FIELD_wback >> 6] |= 1LL << (FIELD_wback & 63); + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: 85A51DE4 +int ldc_literal(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + /* Encoding T1 */ + /* pattern="1110,110,P.1,U.1,0,W.1,1,1111,CRd.4,coproc.4,imm8.8" width=32 stringency=16 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFE5F0000)==0xEC1F0000)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ARMv6T2) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_P] = (instr & 0x1000000)>>24; + res->fields_mask[FIELD_P >> 6] |= 1LL << (FIELD_P & 63); + char P_width = 1; + res->fields[FIELD_U] = (instr & 0x800000)>>23; + res->fields_mask[FIELD_U >> 6] |= 1LL << (FIELD_U & 63); + char U_width = 1; + res->fields[FIELD_W] = (instr & 0x200000)>>21; + res->fields_mask[FIELD_W >> 6] |= 1LL << (FIELD_W & 63); + char W_width = 1; + res->fields[FIELD_CRd] = (instr & 0xF000)>>12; + res->fields_mask[FIELD_CRd >> 6] |= 1LL << (FIELD_CRd & 63); + char CRd_width = 4; + res->fields[FIELD_coproc] = (instr & 0xF00)>>8; + res->fields_mask[FIELD_coproc >> 6] |= 1LL << (FIELD_coproc & 63); + char coproc_width = 4; + res->fields[FIELD_imm8] = instr & 0xFF; + res->fields_mask[FIELD_imm8 >> 6] |= 1LL << (FIELD_imm8 & 63); + char imm8_width = 8; + + static const instruction_format instr_formats[] = + { + { /* LDC<c> <coproc>,<CRd>,<label> */ + "ldc", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_COPROC,FIELD_coproc,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_COPROC_REG,FIELD_CRd,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_LABEL,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + { /* LDC<c> <coproc>,<CRd>,<label>! */ + "ldc", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_COPROC,FIELD_coproc,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_COPROC_REG,FIELD_CRd,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_LABEL,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_YES}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + { /* LDC<c> <coproc>,<CRd>,[PC],#<+/-><imm32> */ + "ldc", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_COPROC,FIELD_coproc,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_COPROC_REG,FIELD_CRd,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_MEMORY_PC,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_ADD_IMM,FIELD_imm32,FIELD_UNINIT,"#","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 4 /* .operandCount */ + }, + { /* LDC<c> <coproc>,<CRd>,[PC],<imm8> */ + "ldc", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_COPROC,FIELD_coproc,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_COPROC_REG,FIELD_CRd,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_MEMORY_PC,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_IMM,FIELD_imm8,FIELD_UNINIT,"#","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 4 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 4; + res->mnem = armv7::ARMV7_LDC; + + /* pcode: D=0 */ + res->fields[FIELD_D] = 0; + res->fields_mask[FIELD_D >> 6] |= 1LL << (FIELD_D & 63); + /* pcode: if P == '0' && U == '0' && D == '0' && W == '0' then UNDEFINED */ + if(((((res->fields[FIELD_P]) == (0x0)) && ((res->fields[FIELD_U]) == (0x0))) && ((res->fields[FIELD_D]) == (0x0))) && ((res->fields[FIELD_W]) == (0x0))) { + res->status |= STATUS_UNDEFINED; + } + /* pcode: if P == '0' && U == '0' && D == '1' && W == '0' then SEE MRRC, MRRC2 */ + if(((((res->fields[FIELD_P]) == (0x0)) && ((res->fields[FIELD_U]) == (0x0))) && ((res->fields[FIELD_D]) == (0x1))) && ((res->fields[FIELD_W]) == (0x0))) { + + return mrrc_mrrc2(req, res); + } + /* pcode: if coproc == '1010' || coproc == '1011' then SEE "nop" */ + if(((res->fields[FIELD_coproc]) == (0xA)) || ((res->fields[FIELD_coproc]) == (0xB))) { + + return nop(req, res); + } + /* pcode: index = (P == '1') */ + res->fields[FIELD_index] = ((res->fields[FIELD_P]) == (0x1)); + res->fields_mask[FIELD_index >> 6] |= 1LL << (FIELD_index & 63); + /* pcode: add = (U == '1') */ + res->fields[FIELD_add] = ((res->fields[FIELD_U]) == (0x1)); + res->fields_mask[FIELD_add >> 6] |= 1LL << (FIELD_add & 63); + /* pcode: cp = UInt(coproc) */ + res->fields[FIELD_cp] = (res->fields[FIELD_coproc]); + res->fields_mask[FIELD_cp >> 6] |= 1LL << (FIELD_cp & 63); + /* pcode: imm32 = ZeroExtend(imm8:'00', 32) */ + res->fields[FIELD_imm32] = (res->fields[FIELD_imm8]<<2)|(0x0); + res->fields_mask[FIELD_imm32 >> 6] |= 1LL << (FIELD_imm32 & 63); + /* pcode: if W == '1' || (P == '0' && CurrentInstrSet() != InstrSet_ARM) then UNPREDICTABLE */ + if(((res->fields[FIELD_W]) == (0x1)) || ((((res->fields[FIELD_P]) == (0x0)) && ((req->instrSet) != (res->fields[FIELD_InstrSet_ARM]))))) { + res->flags |= FLAG_UNPREDICTABLE; + } + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* Encoding T1 */ + /* pattern="1110,110,P.1,U.1,1,W.1,1,1111,CRd.4,coproc.4,imm8.8" width=32 stringency=16 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFE5F0000)==0xEC5F0000)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ARMv6T2) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_P] = (instr & 0x1000000)>>24; + res->fields_mask[FIELD_P >> 6] |= 1LL << (FIELD_P & 63); + char P_width = 1; + res->fields[FIELD_U] = (instr & 0x800000)>>23; + res->fields_mask[FIELD_U >> 6] |= 1LL << (FIELD_U & 63); + char U_width = 1; + res->fields[FIELD_W] = (instr & 0x200000)>>21; + res->fields_mask[FIELD_W >> 6] |= 1LL << (FIELD_W & 63); + char W_width = 1; + res->fields[FIELD_CRd] = (instr & 0xF000)>>12; + res->fields_mask[FIELD_CRd >> 6] |= 1LL << (FIELD_CRd & 63); + char CRd_width = 4; + res->fields[FIELD_coproc] = (instr & 0xF00)>>8; + res->fields_mask[FIELD_coproc >> 6] |= 1LL << (FIELD_coproc & 63); + char coproc_width = 4; + res->fields[FIELD_imm8] = instr & 0xFF; + res->fields_mask[FIELD_imm8 >> 6] |= 1LL << (FIELD_imm8 & 63); + char imm8_width = 8; + + static const instruction_format instr_formats[] = + { + { /* LDCL<c> <coproc>,<CRd>,<label> */ + "ldcl", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_COPROC,FIELD_coproc,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_COPROC_REG,FIELD_CRd,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_LABEL,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + { /* LDCL<c> <coproc>,<CRd>,<label>! */ + "ldcl", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_COPROC,FIELD_coproc,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_COPROC_REG,FIELD_CRd,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_LABEL,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_YES}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + { /* LDCL<c> <coproc>,<CRd>,[PC],#<+/-><imm32> */ + "ldcl", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_COPROC,FIELD_coproc,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_COPROC_REG,FIELD_CRd,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_MEMORY_PC,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_ADD_IMM,FIELD_imm32,FIELD_UNINIT,"#","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 4 /* .operandCount */ + }, + { /* LDCL<c> <coproc>,<CRd>,[PC],<imm8> */ + "ldcl", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_COPROC,FIELD_coproc,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_COPROC_REG,FIELD_CRd,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_MEMORY_PC,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_IMM,FIELD_imm8,FIELD_UNINIT,"#","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 4 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 4; + res->mnem = armv7::ARMV7_LDCL; + + /* pcode: D=1 */ + res->fields[FIELD_D] = 1; + res->fields_mask[FIELD_D >> 6] |= 1LL << (FIELD_D & 63); + /* pcode: if P == '0' && U == '0' && D == '0' && W == '0' then UNDEFINED */ + if(((((res->fields[FIELD_P]) == (0x0)) && ((res->fields[FIELD_U]) == (0x0))) && ((res->fields[FIELD_D]) == (0x0))) && ((res->fields[FIELD_W]) == (0x0))) { + res->status |= STATUS_UNDEFINED; + } + /* pcode: if P == '0' && U == '0' && D == '1' && W == '0' then SEE MRRC, MRRC2 */ + if(((((res->fields[FIELD_P]) == (0x0)) && ((res->fields[FIELD_U]) == (0x0))) && ((res->fields[FIELD_D]) == (0x1))) && ((res->fields[FIELD_W]) == (0x0))) { + + return mrrc_mrrc2(req, res); + } + /* pcode: if coproc == '1010' || coproc == '1011' then SEE "nop" */ + if(((res->fields[FIELD_coproc]) == (0xA)) || ((res->fields[FIELD_coproc]) == (0xB))) { + + return nop(req, res); + } + /* pcode: index = (P == '1') */ + res->fields[FIELD_index] = ((res->fields[FIELD_P]) == (0x1)); + res->fields_mask[FIELD_index >> 6] |= 1LL << (FIELD_index & 63); + /* pcode: add = (U == '1') */ + res->fields[FIELD_add] = ((res->fields[FIELD_U]) == (0x1)); + res->fields_mask[FIELD_add >> 6] |= 1LL << (FIELD_add & 63); + /* pcode: cp = UInt(coproc) */ + res->fields[FIELD_cp] = (res->fields[FIELD_coproc]); + res->fields_mask[FIELD_cp >> 6] |= 1LL << (FIELD_cp & 63); + /* pcode: imm32 = ZeroExtend(imm8:'00', 32) */ + res->fields[FIELD_imm32] = (res->fields[FIELD_imm8]<<2)|(0x0); + res->fields_mask[FIELD_imm32 >> 6] |= 1LL << (FIELD_imm32 & 63); + /* pcode: if W == '1' || (P == '0' && CurrentInstrSet() != InstrSet_ARM) then UNPREDICTABLE */ + if(((res->fields[FIELD_W]) == (0x1)) || ((((res->fields[FIELD_P]) == (0x0)) && ((req->instrSet) != (res->fields[FIELD_InstrSet_ARM]))))) { + res->flags |= FLAG_UNPREDICTABLE; + } + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* Encoding T2 */ + /* pattern="1111,110,P.1,U.1,0,W.1,1,1111,CRd.4,coproc.4,imm8.8" width=32 stringency=16 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFE5F0000)==0xFC1F0000)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ARMv6T2) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_P] = (instr & 0x1000000)>>24; + res->fields_mask[FIELD_P >> 6] |= 1LL << (FIELD_P & 63); + char P_width = 1; + res->fields[FIELD_U] = (instr & 0x800000)>>23; + res->fields_mask[FIELD_U >> 6] |= 1LL << (FIELD_U & 63); + char U_width = 1; + res->fields[FIELD_W] = (instr & 0x200000)>>21; + res->fields_mask[FIELD_W >> 6] |= 1LL << (FIELD_W & 63); + char W_width = 1; + res->fields[FIELD_CRd] = (instr & 0xF000)>>12; + res->fields_mask[FIELD_CRd >> 6] |= 1LL << (FIELD_CRd & 63); + char CRd_width = 4; + res->fields[FIELD_coproc] = (instr & 0xF00)>>8; + res->fields_mask[FIELD_coproc >> 6] |= 1LL << (FIELD_coproc & 63); + char coproc_width = 4; + res->fields[FIELD_imm8] = instr & 0xFF; + res->fields_mask[FIELD_imm8 >> 6] |= 1LL << (FIELD_imm8 & 63); + char imm8_width = 8; + + static const instruction_format instr_formats[] = + { + { /* LDC2<c> <coproc>,<CRd>,<label> */ + "ldc2", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_COPROC,FIELD_coproc,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_COPROC_REG,FIELD_CRd,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_LABEL,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + { /* LDC2<c> <coproc>,<CRd>,<label>! */ + "ldc2", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_COPROC,FIELD_coproc,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_COPROC_REG,FIELD_CRd,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_LABEL,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_YES}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + { /* LDC2<c> <coproc>,<CRd>,[PC],#<+/-><imm32> */ + "ldc2", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_COPROC,FIELD_coproc,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_COPROC_REG,FIELD_CRd,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_MEMORY_PC,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_ADD_IMM,FIELD_imm32,FIELD_UNINIT,"#","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 4 /* .operandCount */ + }, + { /* LDC2<c> <coproc>,<CRd>,[PC],<imm8> */ + "ldc2", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_COPROC,FIELD_coproc,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_COPROC_REG,FIELD_CRd,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_MEMORY_PC,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_IMM,FIELD_imm8,FIELD_UNINIT,"#","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 4 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 4; + res->mnem = armv7::ARMV7_LDC2; + + /* pcode: D=0 */ + res->fields[FIELD_D] = 0; + res->fields_mask[FIELD_D >> 6] |= 1LL << (FIELD_D & 63); + /* pcode: if P == '0' && U == '0' && D == '0' && W == '0' then UNDEFINED */ + if(((((res->fields[FIELD_P]) == (0x0)) && ((res->fields[FIELD_U]) == (0x0))) && ((res->fields[FIELD_D]) == (0x0))) && ((res->fields[FIELD_W]) == (0x0))) { + res->status |= STATUS_UNDEFINED; + } + /* pcode: if P == '0' && U == '0' && D == '1' && W == '0' then SEE MRRC, MRRC2 */ + if(((((res->fields[FIELD_P]) == (0x0)) && ((res->fields[FIELD_U]) == (0x0))) && ((res->fields[FIELD_D]) == (0x1))) && ((res->fields[FIELD_W]) == (0x0))) { + + return mrrc_mrrc2(req, res); + } + /* pcode: index = (P == '1') */ + res->fields[FIELD_index] = ((res->fields[FIELD_P]) == (0x1)); + res->fields_mask[FIELD_index >> 6] |= 1LL << (FIELD_index & 63); + /* pcode: add = (U == '1') */ + res->fields[FIELD_add] = ((res->fields[FIELD_U]) == (0x1)); + res->fields_mask[FIELD_add >> 6] |= 1LL << (FIELD_add & 63); + /* pcode: cp = UInt(coproc) */ + res->fields[FIELD_cp] = (res->fields[FIELD_coproc]); + res->fields_mask[FIELD_cp >> 6] |= 1LL << (FIELD_cp & 63); + /* pcode: imm32 = ZeroExtend(imm8:'00', 32) */ + res->fields[FIELD_imm32] = (res->fields[FIELD_imm8]<<2)|(0x0); + res->fields_mask[FIELD_imm32 >> 6] |= 1LL << (FIELD_imm32 & 63); + /* pcode: if W == '1' || (P == '0' && CurrentInstrSet() != InstrSet_ARM) then UNPREDICTABLE */ + if(((res->fields[FIELD_W]) == (0x1)) || ((((res->fields[FIELD_P]) == (0x0)) && ((req->instrSet) != (res->fields[FIELD_InstrSet_ARM]))))) { + res->flags |= FLAG_UNPREDICTABLE; + } + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* Encoding T2 */ + /* pattern="1111,110,P.1,U.1,1,W.1,1,1111,CRd.4,coproc.4,imm8.8" width=32 stringency=16 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFE5F0000)==0xFC5F0000)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ARMv6T2) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_P] = (instr & 0x1000000)>>24; + res->fields_mask[FIELD_P >> 6] |= 1LL << (FIELD_P & 63); + char P_width = 1; + res->fields[FIELD_U] = (instr & 0x800000)>>23; + res->fields_mask[FIELD_U >> 6] |= 1LL << (FIELD_U & 63); + char U_width = 1; + res->fields[FIELD_W] = (instr & 0x200000)>>21; + res->fields_mask[FIELD_W >> 6] |= 1LL << (FIELD_W & 63); + char W_width = 1; + res->fields[FIELD_CRd] = (instr & 0xF000)>>12; + res->fields_mask[FIELD_CRd >> 6] |= 1LL << (FIELD_CRd & 63); + char CRd_width = 4; + res->fields[FIELD_coproc] = (instr & 0xF00)>>8; + res->fields_mask[FIELD_coproc >> 6] |= 1LL << (FIELD_coproc & 63); + char coproc_width = 4; + res->fields[FIELD_imm8] = instr & 0xFF; + res->fields_mask[FIELD_imm8 >> 6] |= 1LL << (FIELD_imm8 & 63); + char imm8_width = 8; + + static const instruction_format instr_formats[] = + { + { /* LDC2L<c> <coproc>,<CRd>,<label> */ + "ldc2l", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_COPROC,FIELD_coproc,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_COPROC_REG,FIELD_CRd,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_LABEL,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + { /* LDC2L<c> <coproc>,<CRd>,<label>! */ + "ldc2l", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_COPROC,FIELD_coproc,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_COPROC_REG,FIELD_CRd,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_LABEL,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_YES}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + { /* LDC2L<c> <coproc>,<CRd>,[PC],#<+/-><imm32> */ + "ldc2l", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_COPROC,FIELD_coproc,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_COPROC_REG,FIELD_CRd,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_MEMORY_PC,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_ADD_IMM,FIELD_imm32,FIELD_UNINIT,"#","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 4 /* .operandCount */ + }, + { /* LDC2L<c> <coproc>,<CRd>,[PC],<imm8> */ + "ldc2l", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_COPROC,FIELD_coproc,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_COPROC_REG,FIELD_CRd,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_MEMORY_PC,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_IMM,FIELD_imm8,FIELD_UNINIT,"#","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 4 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 4; + res->mnem = armv7::ARMV7_LDC2L; + + /* pcode: D=1 */ + res->fields[FIELD_D] = 1; + res->fields_mask[FIELD_D >> 6] |= 1LL << (FIELD_D & 63); + /* pcode: if P == '0' && U == '0' && D == '0' && W == '0' then UNDEFINED */ + if(((((res->fields[FIELD_P]) == (0x0)) && ((res->fields[FIELD_U]) == (0x0))) && ((res->fields[FIELD_D]) == (0x0))) && ((res->fields[FIELD_W]) == (0x0))) { + res->status |= STATUS_UNDEFINED; + } + /* pcode: if P == '0' && U == '0' && D == '1' && W == '0' then SEE MRRC, MRRC2 */ + if(((((res->fields[FIELD_P]) == (0x0)) && ((res->fields[FIELD_U]) == (0x0))) && ((res->fields[FIELD_D]) == (0x1))) && ((res->fields[FIELD_W]) == (0x0))) { + + return mrrc_mrrc2(req, res); + } + /* pcode: index = (P == '1') */ + res->fields[FIELD_index] = ((res->fields[FIELD_P]) == (0x1)); + res->fields_mask[FIELD_index >> 6] |= 1LL << (FIELD_index & 63); + /* pcode: add = (U == '1') */ + res->fields[FIELD_add] = ((res->fields[FIELD_U]) == (0x1)); + res->fields_mask[FIELD_add >> 6] |= 1LL << (FIELD_add & 63); + /* pcode: cp = UInt(coproc) */ + res->fields[FIELD_cp] = (res->fields[FIELD_coproc]); + res->fields_mask[FIELD_cp >> 6] |= 1LL << (FIELD_cp & 63); + /* pcode: imm32 = ZeroExtend(imm8:'00', 32) */ + res->fields[FIELD_imm32] = (res->fields[FIELD_imm8]<<2)|(0x0); + res->fields_mask[FIELD_imm32 >> 6] |= 1LL << (FIELD_imm32 & 63); + /* pcode: if W == '1' || (P == '0' && CurrentInstrSet() != InstrSet_ARM) then UNPREDICTABLE */ + if(((res->fields[FIELD_W]) == (0x1)) || ((((res->fields[FIELD_P]) == (0x0)) && ((req->instrSet) != (res->fields[FIELD_InstrSet_ARM]))))) { + res->flags |= FLAG_UNPREDICTABLE; + } + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: B2E37868 +int ldm(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + /* Encoding T1 */ + /* pattern="1100,1,Rn.3,register_list.8" width=16 stringency=5 */ + { + uint16_t instr = req->instr_word16; + if(((instr & 0xF800)==0xC800)) { + res->instrSize = 16; + if(!(req->arch & ARCH_ARMv4T) && !(req->arch & ARCH_ARMv5T) && !(req->arch & ARCH_ARMv6) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_Rn] = (instr & 0x700)>>8; + res->fields_mask[FIELD_Rn >> 6] |= 1LL << (FIELD_Rn & 63); + char Rn_width = 3; + res->fields[FIELD_register_list] = instr & 0xFF; + res->fields_mask[FIELD_register_list >> 6] |= 1LL << (FIELD_register_list & 63); + char register_list_width = 8; + + static const instruction_format instr_formats[] = + { + { /* LDM<c> <Rn>{!},<registers> */ + "ldm", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rn,FIELD_UNINIT,"","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REGISTERS,FIELD_registers,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_LDM; + + /* pcode: n = UInt(Rn) */ + res->fields[FIELD_n] = (res->fields[FIELD_Rn]); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: registers = '00000000':register_list */ + res->fields[FIELD_registers] = (0x0<<register_list_width)|(res->fields[FIELD_register_list]); + res->fields_mask[FIELD_registers >> 6] |= 1LL << (FIELD_registers & 63); + /* pcode: wback = (registers<n> == '0') */ + res->fields[FIELD_wback] = (((res->fields[FIELD_registers] & (1<<res->fields[FIELD_n])) >> res->fields[FIELD_n]) == (0x0)); + res->fields_mask[FIELD_wback >> 6] |= 1LL << (FIELD_wback & 63); + /* pcode: if BitCount(registers) < 1 then UNPREDICTABLE */ + if((BitCount(res->fields[FIELD_registers])) < (1)) { + res->flags |= FLAG_UNPREDICTABLE; + } + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* Encoding T2 */ + /* pattern="11101,00,010,W.1,1,Rn.4,P.1,M.1,register_list.14" width=32 stringency=15 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFFD00000)==0xE8900000)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ARMv6T2) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_W] = (instr & 0x200000)>>21; + res->fields_mask[FIELD_W >> 6] |= 1LL << (FIELD_W & 63); + char W_width = 1; + res->fields[FIELD_Rn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Rn >> 6] |= 1LL << (FIELD_Rn & 63); + char Rn_width = 4; + res->fields[FIELD_P] = (instr & 0x8000)>>15; + res->fields_mask[FIELD_P >> 6] |= 1LL << (FIELD_P & 63); + char P_width = 1; + res->fields[FIELD_M] = (instr & 0x4000)>>14; + res->fields_mask[FIELD_M >> 6] |= 1LL << (FIELD_M & 63); + char M_width = 1; + res->fields[FIELD_register_list] = instr & 0x3FFF; + res->fields_mask[FIELD_register_list >> 6] |= 1LL << (FIELD_register_list & 63); + char register_list_width = 14; + + static const instruction_format instr_formats[] = + { + { /* LDM<c> <Rn>{!},<registers> */ + "ldm", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rn,FIELD_UNINIT,"","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REGISTERS,FIELD_registers,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_LDM; + + /* pcode: if W == '1' && Rn == '1101' then SEE POP */ + if(((res->fields[FIELD_W]) == (0x1)) && ((res->fields[FIELD_Rn]) == (0xD))) { + + return pop(req, res); + } + /* pcode: n = UInt(Rn) */ + res->fields[FIELD_n] = (res->fields[FIELD_Rn]); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: registers = P:M:register_list */ + res->fields[FIELD_registers] = (res->fields[FIELD_P]<<(register_list_width+M_width))|(res->fields[FIELD_M]<<register_list_width)|(res->fields[FIELD_register_list]); + res->fields_mask[FIELD_registers >> 6] |= 1LL << (FIELD_registers & 63); + /* pcode: wback = (W == '1') */ + res->fields[FIELD_wback] = ((res->fields[FIELD_W]) == (0x1)); + res->fields_mask[FIELD_wback >> 6] |= 1LL << (FIELD_wback & 63); + /* pcode: if n == 15 || BitCount(registers) < 2 || (P == '1' && M == '1') then UNPREDICTABLE */ + if((((res->fields[FIELD_n]) == (15)) || ((BitCount(res->fields[FIELD_registers])) < (2))) || ((((res->fields[FIELD_P]) == (0x1)) && ((res->fields[FIELD_M]) == (0x1))))) { + res->flags |= FLAG_UNPREDICTABLE; + } + /* pcode: if registers<15> == '1' && InITBlock() && !LastInITBlock() then UNPREDICTABLE */ + if(((((res->fields[FIELD_registers] & (1<<15)) >> 15) == (0x1)) && (req->inIfThen == IFTHEN_YES)) && (!(req->inIfThenLast == IFTHENLAST_YES))) { + res->flags |= FLAG_UNPREDICTABLE; + } + /* pcode: if wback && registers<n> == '1' then UNPREDICTABLE */ + if((res->fields[FIELD_wback]) && (((res->fields[FIELD_registers] & (1<<res->fields[FIELD_n])) >> res->fields[FIELD_n]) == (0x1))) { + res->flags |= FLAG_UNPREDICTABLE; + } + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: 0F64FC44 +int ldmdb(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + /* Encoding T1 */ + /* pattern="11101,00,100,W.1,1,Rn.4,P.1,M.1,register_list.14" width=32 stringency=15 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFFD00000)==0xE9100000)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ARMv6T2) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_W] = (instr & 0x200000)>>21; + res->fields_mask[FIELD_W >> 6] |= 1LL << (FIELD_W & 63); + char W_width = 1; + res->fields[FIELD_Rn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Rn >> 6] |= 1LL << (FIELD_Rn & 63); + char Rn_width = 4; + res->fields[FIELD_P] = (instr & 0x8000)>>15; + res->fields_mask[FIELD_P >> 6] |= 1LL << (FIELD_P & 63); + char P_width = 1; + res->fields[FIELD_M] = (instr & 0x4000)>>14; + res->fields_mask[FIELD_M >> 6] |= 1LL << (FIELD_M & 63); + char M_width = 1; + res->fields[FIELD_register_list] = instr & 0x3FFF; + res->fields_mask[FIELD_register_list >> 6] |= 1LL << (FIELD_register_list & 63); + char register_list_width = 14; + + static const instruction_format instr_formats[] = + { + { /* LDMDB<c> <Rn>{!},<registers> */ + "ldmdb", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rn,FIELD_UNINIT,"","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REGISTERS,FIELD_registers,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_LDMDB; + + /* pcode: n = UInt(Rn) */ + res->fields[FIELD_n] = (res->fields[FIELD_Rn]); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: registers = P:M:register_list */ + res->fields[FIELD_registers] = (res->fields[FIELD_P]<<(register_list_width+M_width))|(res->fields[FIELD_M]<<register_list_width)|(res->fields[FIELD_register_list]); + res->fields_mask[FIELD_registers >> 6] |= 1LL << (FIELD_registers & 63); + /* pcode: wback = (W == '1') */ + res->fields[FIELD_wback] = ((res->fields[FIELD_W]) == (0x1)); + res->fields_mask[FIELD_wback >> 6] |= 1LL << (FIELD_wback & 63); + /* pcode: if n == 15 || BitCount(registers) < 2 || (P == '1' && M == '1') then UNPREDICTABLE */ + if((((res->fields[FIELD_n]) == (15)) || ((BitCount(res->fields[FIELD_registers])) < (2))) || ((((res->fields[FIELD_P]) == (0x1)) && ((res->fields[FIELD_M]) == (0x1))))) { + res->flags |= FLAG_UNPREDICTABLE; + } + /* pcode: if registers<15> == '1' && InITBlock() && !LastInITBlock() then UNPREDICTABLE */ + if(((((res->fields[FIELD_registers] & (1<<15)) >> 15) == (0x1)) && (req->inIfThen == IFTHEN_YES)) && (!(req->inIfThenLast == IFTHENLAST_YES))) { + res->flags |= FLAG_UNPREDICTABLE; + } + /* pcode: if wback && registers<n> == '1' then UNPREDICTABLE */ + if((res->fields[FIELD_wback]) && (((res->fields[FIELD_registers] & (1<<res->fields[FIELD_n])) >> res->fields[FIELD_n]) == (0x1))) { + res->flags |= FLAG_UNPREDICTABLE; + } + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: 4ED32B5D +int ldr_immediate(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + /* Encoding T1 */ + /* pattern="011,0,1,imm5.5,Rn.3,Rt.3" width=16 stringency=5 */ + { + uint16_t instr = req->instr_word16; + if(((instr & 0xF800)==0x6800)) { + res->instrSize = 16; + if(!(req->arch & ARCH_ARMv4T) && !(req->arch & ARCH_ARMv5T) && !(req->arch & ARCH_ARMv6) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_imm5] = (instr & 0x7C0)>>6; + res->fields_mask[FIELD_imm5 >> 6] |= 1LL << (FIELD_imm5 & 63); + char imm5_width = 5; + res->fields[FIELD_Rn] = (instr & 0x38)>>3; + res->fields_mask[FIELD_Rn >> 6] |= 1LL << (FIELD_Rn & 63); + char Rn_width = 3; + res->fields[FIELD_Rt] = instr & 0x7; + res->fields_mask[FIELD_Rt >> 6] |= 1LL << (FIELD_Rt & 63); + char Rt_width = 3; + + static const instruction_format instr_formats[] = + { + { /* LDR<c> <Rt>,[<Rn>{,#<imm32>}] */ + "ldr", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rt,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_MEMORY_ONE_REG_OPTIONAL_IMM,FIELD_Rn,FIELD_imm32,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_LDR; + + /* pcode: t = UInt(Rt) */ + res->fields[FIELD_t] = (res->fields[FIELD_Rt]); + res->fields_mask[FIELD_t >> 6] |= 1LL << (FIELD_t & 63); + /* pcode: n = UInt(Rn) */ + res->fields[FIELD_n] = (res->fields[FIELD_Rn]); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: imm32 = ZeroExtend(imm5:'00', 32) */ + res->fields[FIELD_imm32] = (res->fields[FIELD_imm5]<<2)|(0x0); + res->fields_mask[FIELD_imm32 >> 6] |= 1LL << (FIELD_imm32 & 63); + /* pcode: index = TRUE */ + res->fields[FIELD_index] = 1; + res->fields_mask[FIELD_index >> 6] |= 1LL << (FIELD_index & 63); + /* pcode: add = TRUE */ + res->fields[FIELD_add] = 1; + res->fields_mask[FIELD_add >> 6] |= 1LL << (FIELD_add & 63); + /* pcode: wback = FALSE */ + res->fields[FIELD_wback] = 0; + res->fields_mask[FIELD_wback >> 6] |= 1LL << (FIELD_wback & 63); + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* Encoding T2 */ + /* pattern="1001,1,Rt.3,imm8.8" width=16 stringency=5 */ + { + uint16_t instr = req->instr_word16; + if(((instr & 0xF800)==0x9800)) { + res->instrSize = 16; + if(!(req->arch & ARCH_ARMv4T) && !(req->arch & ARCH_ARMv5T) && !(req->arch & ARCH_ARMv6) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_Rt] = (instr & 0x700)>>8; + res->fields_mask[FIELD_Rt >> 6] |= 1LL << (FIELD_Rt & 63); + char Rt_width = 3; + res->fields[FIELD_imm8] = instr & 0xFF; + res->fields_mask[FIELD_imm8 >> 6] |= 1LL << (FIELD_imm8 & 63); + char imm8_width = 8; + + static const instruction_format instr_formats[] = + { + { /* LDR<c> <Rt>,[SP{,#<imm32>}] */ + "ldr", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rt,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_MEMORY_SP_OPTIONAL_IMM,FIELD_imm32,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_LDR; + + /* pcode: t = UInt(Rt) */ + res->fields[FIELD_t] = (res->fields[FIELD_Rt]); + res->fields_mask[FIELD_t >> 6] |= 1LL << (FIELD_t & 63); + /* pcode: n = 13 */ + res->fields[FIELD_n] = 13; + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: imm32 = ZeroExtend(imm8:'00', 32) */ + res->fields[FIELD_imm32] = (res->fields[FIELD_imm8]<<2)|(0x0); + res->fields_mask[FIELD_imm32 >> 6] |= 1LL << (FIELD_imm32 & 63); + /* pcode: index = TRUE */ + res->fields[FIELD_index] = 1; + res->fields_mask[FIELD_index >> 6] |= 1LL << (FIELD_index & 63); + /* pcode: add = TRUE */ + res->fields[FIELD_add] = 1; + res->fields_mask[FIELD_add >> 6] |= 1LL << (FIELD_add & 63); + /* pcode: wback = FALSE */ + res->fields[FIELD_wback] = 0; + res->fields_mask[FIELD_wback >> 6] |= 1LL << (FIELD_wback & 63); + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* Encoding T3 */ + /* pattern="11111,00,0,1,10,1,Rn.4,Rt.4,imm12.12" width=32 stringency=14 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFFF00000)==0xF8D00000)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ARMv6T2) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_Rn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Rn >> 6] |= 1LL << (FIELD_Rn & 63); + char Rn_width = 4; + res->fields[FIELD_Rt] = (instr & 0xF000)>>12; + res->fields_mask[FIELD_Rt >> 6] |= 1LL << (FIELD_Rt & 63); + char Rt_width = 4; + res->fields[FIELD_imm12] = instr & 0xFFF; + res->fields_mask[FIELD_imm12 >> 6] |= 1LL << (FIELD_imm12 & 63); + char imm12_width = 12; + + static const instruction_format instr_formats[] = + { + { /* LDR<c> <Rt>,[<Rn>{,#<imm32>}] */ + "ldr", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rt,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_MEMORY_ONE_REG_OPTIONAL_IMM,FIELD_Rn,FIELD_imm32,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_LDR; + + /* pcode: if Rn == '1111' then SEE LDR (literal) */ + if((res->fields[FIELD_Rn]) == (0xF)) { + + return ldr_literal(req, res); + } + /* pcode: t = UInt(Rt) */ + res->fields[FIELD_t] = (res->fields[FIELD_Rt]); + res->fields_mask[FIELD_t >> 6] |= 1LL << (FIELD_t & 63); + /* pcode: n = UInt(Rn) */ + res->fields[FIELD_n] = (res->fields[FIELD_Rn]); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: imm32 = ZeroExtend(imm12, 32) */ + res->fields[FIELD_imm32] = res->fields[FIELD_imm12]; + res->fields_mask[FIELD_imm32 >> 6] |= 1LL << (FIELD_imm32 & 63); + /* pcode: index = TRUE */ + res->fields[FIELD_index] = 1; + res->fields_mask[FIELD_index >> 6] |= 1LL << (FIELD_index & 63); + /* pcode: add = TRUE */ + res->fields[FIELD_add] = 1; + res->fields_mask[FIELD_add >> 6] |= 1LL << (FIELD_add & 63); + /* pcode: wback = FALSE */ + res->fields[FIELD_wback] = 0; + res->fields_mask[FIELD_wback >> 6] |= 1LL << (FIELD_wback & 63); + /* pcode: if t == 15 && InITBlock() && !LastInITBlock() then UNPREDICTABLE */ + if((((res->fields[FIELD_t]) == (15)) && (req->inIfThen == IFTHEN_YES)) && (!(req->inIfThenLast == IFTHENLAST_YES))) { + res->flags |= FLAG_UNPREDICTABLE; + } + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* Encoding T4 */ + /* pattern="11111,00,0,0,10,1,Rn.4,Rt.4,1,P.1,U.1,W.1,imm8.8" width=32 stringency=16 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFFF00800)==0xF8500800)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ARMv6T2) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_Rn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Rn >> 6] |= 1LL << (FIELD_Rn & 63); + char Rn_width = 4; + res->fields[FIELD_Rt] = (instr & 0xF000)>>12; + res->fields_mask[FIELD_Rt >> 6] |= 1LL << (FIELD_Rt & 63); + char Rt_width = 4; + res->fields[FIELD_P] = (instr & 0x400)>>10; + res->fields_mask[FIELD_P >> 6] |= 1LL << (FIELD_P & 63); + char P_width = 1; + res->fields[FIELD_U] = (instr & 0x200)>>9; + res->fields_mask[FIELD_U >> 6] |= 1LL << (FIELD_U & 63); + char U_width = 1; + res->fields[FIELD_W] = (instr & 0x100)>>8; + res->fields_mask[FIELD_W >> 6] |= 1LL << (FIELD_W & 63); + char W_width = 1; + res->fields[FIELD_imm8] = instr & 0xFF; + res->fields_mask[FIELD_imm8 >> 6] |= 1LL << (FIELD_imm8 & 63); + char imm8_width = 8; + + static const instruction_format instr_formats[] = + { + { /* LDR<c> <Rt>,[<Rn>,#-<imm32>] */ + "ldr", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rt,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_MEMORY_ONE_REG_NEG_IMM,FIELD_Rn,FIELD_imm32,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + { /* LDR<c> <Rt>,[<Rn>,#<+/-><imm32>]! */ + "ldr", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rt,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_MEMORY_ONE_REG_ADD_IMM,FIELD_Rn,FIELD_imm32,"","",WRITEBACK_YES}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + { /* LDR<c> <Rt>,[<Rn>],#<+/-><imm32> */ + "ldr", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rt,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_MEMORY_ONE_REG,FIELD_Rn,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_ADD_IMM,FIELD_imm32,FIELD_UNINIT,"#","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 3; + res->mnem = armv7::ARMV7_LDR; + + /* pcode: if Rn == '1111' then SEE LDR (literal) */ + if((res->fields[FIELD_Rn]) == (0xF)) { + + return ldr_literal(req, res); + } + /* pcode: if P == '1' && U == '1' && W == '0' then SEE LDRT */ + if((((res->fields[FIELD_P]) == (0x1)) && ((res->fields[FIELD_U]) == (0x1))) && ((res->fields[FIELD_W]) == (0x0))) { + + return ldrt(req, res); + } + /* pcode: if Rn == '1101' && P == '0' && U == '1' && W == '1' && imm8 == '00000100' then SEE POP */ + if((((((res->fields[FIELD_Rn]) == (0xD)) && ((res->fields[FIELD_P]) == (0x0))) && ((res->fields[FIELD_U]) == (0x1))) && ((res->fields[FIELD_W]) == (0x1))) && ((res->fields[FIELD_imm8]) == (0x4))) { + + return pop(req, res); + } + /* pcode: if P == '0' && W == '0' then UNDEFINED */ + if(((res->fields[FIELD_P]) == (0x0)) && ((res->fields[FIELD_W]) == (0x0))) { + res->status |= STATUS_UNDEFINED; + } + /* pcode: t = UInt(Rt) */ + res->fields[FIELD_t] = (res->fields[FIELD_Rt]); + res->fields_mask[FIELD_t >> 6] |= 1LL << (FIELD_t & 63); + /* pcode: n = UInt(Rn) */ + res->fields[FIELD_n] = (res->fields[FIELD_Rn]); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: imm32 = ZeroExtend(imm8, 32) */ + res->fields[FIELD_imm32] = res->fields[FIELD_imm8]; + res->fields_mask[FIELD_imm32 >> 6] |= 1LL << (FIELD_imm32 & 63); + /* pcode: index = (P == '1') */ + res->fields[FIELD_index] = ((res->fields[FIELD_P]) == (0x1)); + res->fields_mask[FIELD_index >> 6] |= 1LL << (FIELD_index & 63); + /* pcode: add = (U == '1') */ + res->fields[FIELD_add] = ((res->fields[FIELD_U]) == (0x1)); + res->fields_mask[FIELD_add >> 6] |= 1LL << (FIELD_add & 63); + /* pcode: wback = (W == '1') */ + res->fields[FIELD_wback] = ((res->fields[FIELD_W]) == (0x1)); + res->fields_mask[FIELD_wback >> 6] |= 1LL << (FIELD_wback & 63); + /* pcode: if (wback && n == t) || (t == 15 && InITBlock() && !LastInITBlock()) then UNPREDICTABLE */ + if((((res->fields[FIELD_wback]) && ((res->fields[FIELD_n]) == (res->fields[FIELD_t])))) || (((((res->fields[FIELD_t]) == (15)) && (req->inIfThen == IFTHEN_YES)) && (!(req->inIfThenLast == IFTHENLAST_YES))))) { + res->flags |= FLAG_UNPREDICTABLE; + } + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: BCCC885B +int ldr_literal(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + /* Encoding T1 */ + /* pattern="01001,Rt.3,imm8.8" width=16 stringency=5 */ + { + uint16_t instr = req->instr_word16; + if(((instr & 0xF800)==0x4800)) { + res->instrSize = 16; + if(!(req->arch & ARCH_ARMv4T) && !(req->arch & ARCH_ARMv5T) && !(req->arch & ARCH_ARMv6) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_Rt] = (instr & 0x700)>>8; + res->fields_mask[FIELD_Rt >> 6] |= 1LL << (FIELD_Rt & 63); + char Rt_width = 3; + res->fields[FIELD_imm8] = instr & 0xFF; + res->fields_mask[FIELD_imm8 >> 6] |= 1LL << (FIELD_imm8 & 63); + char imm8_width = 8; + + static const instruction_format instr_formats[] = + { + { /* LDR<c> <Rt>,<label> */ + "ldr", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rt,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_LABEL,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_LDR; + + /* pcode: t = UInt(Rt) */ + res->fields[FIELD_t] = (res->fields[FIELD_Rt]); + res->fields_mask[FIELD_t >> 6] |= 1LL << (FIELD_t & 63); + /* pcode: imm32 = ZeroExtend(imm8:'00', 32) */ + res->fields[FIELD_imm32] = (res->fields[FIELD_imm8]<<2)|(0x0); + res->fields_mask[FIELD_imm32 >> 6] |= 1LL << (FIELD_imm32 & 63); + /* pcode: add = TRUE */ + res->fields[FIELD_add] = 1; + res->fields_mask[FIELD_add >> 6] |= 1LL << (FIELD_add & 63); + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* Encoding T2 */ + /* pattern="11111,00,0,U.1,10,1,1111,Rt.4,imm12.12" width=32 stringency=18 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFF7F0000)==0xF85F0000)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ARMv6T2) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_U] = (instr & 0x800000)>>23; + res->fields_mask[FIELD_U >> 6] |= 1LL << (FIELD_U & 63); + char U_width = 1; + res->fields[FIELD_Rt] = (instr & 0xF000)>>12; + res->fields_mask[FIELD_Rt >> 6] |= 1LL << (FIELD_Rt & 63); + char Rt_width = 4; + res->fields[FIELD_imm12] = instr & 0xFFF; + res->fields_mask[FIELD_imm12 >> 6] |= 1LL << (FIELD_imm12 & 63); + char imm12_width = 12; + + static const instruction_format instr_formats[] = + { + { /* LDR<c> <Rt>,<label> */ + "ldr", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rt,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_LABEL,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_LDR; + + /* pcode: t = UInt(Rt) */ + res->fields[FIELD_t] = (res->fields[FIELD_Rt]); + res->fields_mask[FIELD_t >> 6] |= 1LL << (FIELD_t & 63); + /* pcode: imm32 = ZeroExtend(imm12, 32) */ + res->fields[FIELD_imm32] = res->fields[FIELD_imm12]; + res->fields_mask[FIELD_imm32 >> 6] |= 1LL << (FIELD_imm32 & 63); + /* pcode: add = (U == '1') */ + res->fields[FIELD_add] = ((res->fields[FIELD_U]) == (0x1)); + res->fields_mask[FIELD_add >> 6] |= 1LL << (FIELD_add & 63); + /* pcode: if t == 15 && InITBlock() && !LastInITBlock() then UNPREDICTABLE */ + if((((res->fields[FIELD_t]) == (15)) && (req->inIfThen == IFTHEN_YES)) && (!(req->inIfThenLast == IFTHENLAST_YES))) { + res->flags |= FLAG_UNPREDICTABLE; + } + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: 124F9ABD +int ldr_register(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + /* Encoding T1 */ + /* pattern="0101,100,Rm.3,Rn.3,Rt.3" width=16 stringency=7 */ + { + uint16_t instr = req->instr_word16; + if(((instr & 0xFE00)==0x5800)) { + res->instrSize = 16; + if(!(req->arch & ARCH_ARMv4T) && !(req->arch & ARCH_ARMv5T) && !(req->arch & ARCH_ARMv6) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_Rm] = (instr & 0x1C0)>>6; + res->fields_mask[FIELD_Rm >> 6] |= 1LL << (FIELD_Rm & 63); + char Rm_width = 3; + res->fields[FIELD_Rn] = (instr & 0x38)>>3; + res->fields_mask[FIELD_Rn >> 6] |= 1LL << (FIELD_Rn & 63); + char Rn_width = 3; + res->fields[FIELD_Rt] = instr & 0x7; + res->fields_mask[FIELD_Rt >> 6] |= 1LL << (FIELD_Rt & 63); + char Rt_width = 3; + + static const instruction_format instr_formats[] = + { + { /* LDR<c> <Rt>,[<Rn>,<Rm>] */ + "ldr", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rt,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_MEMORY_TWO_REG,FIELD_Rn,FIELD_Rm,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_LDR; + + /* pcode: t = UInt(Rt) */ + res->fields[FIELD_t] = (res->fields[FIELD_Rt]); + res->fields_mask[FIELD_t >> 6] |= 1LL << (FIELD_t & 63); + /* pcode: n = UInt(Rn) */ + res->fields[FIELD_n] = (res->fields[FIELD_Rn]); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: m = UInt(Rm) */ + res->fields[FIELD_m] = (res->fields[FIELD_Rm]); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + /* pcode: index = TRUE */ + res->fields[FIELD_index] = 1; + res->fields_mask[FIELD_index >> 6] |= 1LL << (FIELD_index & 63); + /* pcode: add = TRUE */ + res->fields[FIELD_add] = 1; + res->fields_mask[FIELD_add >> 6] |= 1LL << (FIELD_add & 63); + /* pcode: wback = FALSE */ + res->fields[FIELD_wback] = 0; + res->fields_mask[FIELD_wback >> 6] |= 1LL << (FIELD_wback & 63); + /* pcode: (shift_t, shift_n) = (SRType_LSL, 0) */ + res->fields[FIELD_shift_t] = 0; + res->fields_mask[FIELD_shift_t >> 6] |= 1LL << (FIELD_shift_t & 63); + res->fields[FIELD_shift_n] = 0; + res->fields_mask[FIELD_shift_n >> 6] |= 1LL << (FIELD_shift_n & 63); + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* Encoding T2 */ + /* pattern="11111,00,0,0,10,1,Rn.4,Rt.4,0,00000,imm2.2,Rm.4" width=32 stringency=18 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFFF00FC0)==0xF8500000)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ARMv6T2) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_Rn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Rn >> 6] |= 1LL << (FIELD_Rn & 63); + char Rn_width = 4; + res->fields[FIELD_Rt] = (instr & 0xF000)>>12; + res->fields_mask[FIELD_Rt >> 6] |= 1LL << (FIELD_Rt & 63); + char Rt_width = 4; + res->fields[FIELD_imm2] = (instr & 0x30)>>4; + res->fields_mask[FIELD_imm2 >> 6] |= 1LL << (FIELD_imm2 & 63); + char imm2_width = 2; + res->fields[FIELD_Rm] = instr & 0xF; + res->fields_mask[FIELD_Rm >> 6] |= 1LL << (FIELD_Rm & 63); + char Rm_width = 4; + + static const instruction_format instr_formats[] = + { + { /* LDR<c> <Rt>,[<Rn>,<Rm>{,<shift>}] */ + "ldr", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rt,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_MEMORY_TWO_REG_SHIFT,FIELD_Rn,FIELD_Rm,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_LDR; + + /* pcode: if Rn == '1111' then SEE LDR (literal) */ + if((res->fields[FIELD_Rn]) == (0xF)) { + + return ldr_literal(req, res); + } + /* pcode: t = UInt(Rt) */ + res->fields[FIELD_t] = (res->fields[FIELD_Rt]); + res->fields_mask[FIELD_t >> 6] |= 1LL << (FIELD_t & 63); + /* pcode: n = UInt(Rn) */ + res->fields[FIELD_n] = (res->fields[FIELD_Rn]); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: m = UInt(Rm) */ + res->fields[FIELD_m] = (res->fields[FIELD_Rm]); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + /* pcode: index = TRUE */ + res->fields[FIELD_index] = 1; + res->fields_mask[FIELD_index >> 6] |= 1LL << (FIELD_index & 63); + /* pcode: add = TRUE */ + res->fields[FIELD_add] = 1; + res->fields_mask[FIELD_add >> 6] |= 1LL << (FIELD_add & 63); + /* pcode: wback = FALSE */ + res->fields[FIELD_wback] = 0; + res->fields_mask[FIELD_wback >> 6] |= 1LL << (FIELD_wback & 63); + /* pcode: (shift_t, shift_n) = (SRType_LSL, UInt(imm2)) */ + res->fields[FIELD_shift_t] = 0; + res->fields_mask[FIELD_shift_t >> 6] |= 1LL << (FIELD_shift_t & 63); + res->fields[FIELD_shift_n] = (res->fields[FIELD_imm2]); + res->fields_mask[FIELD_shift_n >> 6] |= 1LL << (FIELD_shift_n & 63); + /* pcode: if BadReg(m) then UNPREDICTABLE */ + if(BadReg(res->fields[FIELD_m])) { + res->flags |= FLAG_UNPREDICTABLE; + } + /* pcode: if t == 15 && InITBlock() && !LastInITBlock() then UNPREDICTABLE */ + if((((res->fields[FIELD_t]) == (15)) && (req->inIfThen == IFTHEN_YES)) && (!(req->inIfThenLast == IFTHENLAST_YES))) { + res->flags |= FLAG_UNPREDICTABLE; + } + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: C0F32469 +int ldrb_immediate(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + /* Encoding T1 */ + /* pattern="011,1,1,imm5.5,Rn.3,Rt.3" width=16 stringency=5 */ + { + uint16_t instr = req->instr_word16; + if(((instr & 0xF800)==0x7800)) { + res->instrSize = 16; + if(!(req->arch & ARCH_ARMv4T) && !(req->arch & ARCH_ARMv5T) && !(req->arch & ARCH_ARMv6) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_imm5] = (instr & 0x7C0)>>6; + res->fields_mask[FIELD_imm5 >> 6] |= 1LL << (FIELD_imm5 & 63); + char imm5_width = 5; + res->fields[FIELD_Rn] = (instr & 0x38)>>3; + res->fields_mask[FIELD_Rn >> 6] |= 1LL << (FIELD_Rn & 63); + char Rn_width = 3; + res->fields[FIELD_Rt] = instr & 0x7; + res->fields_mask[FIELD_Rt >> 6] |= 1LL << (FIELD_Rt & 63); + char Rt_width = 3; + + static const instruction_format instr_formats[] = + { + { /* LDRB<c> <Rt>,[<Rn>{,#<imm5>}] */ + "ldrb", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rt,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_MEMORY_ONE_REG_OPTIONAL_IMM,FIELD_Rn,FIELD_imm5,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_LDRB; + + /* pcode: t = UInt(Rt) */ + res->fields[FIELD_t] = (res->fields[FIELD_Rt]); + res->fields_mask[FIELD_t >> 6] |= 1LL << (FIELD_t & 63); + /* pcode: n = UInt(Rn) */ + res->fields[FIELD_n] = (res->fields[FIELD_Rn]); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: imm32 = ZeroExtend(imm5, 32) */ + res->fields[FIELD_imm32] = res->fields[FIELD_imm5]; + res->fields_mask[FIELD_imm32 >> 6] |= 1LL << (FIELD_imm32 & 63); + /* pcode: index = TRUE */ + res->fields[FIELD_index] = 1; + res->fields_mask[FIELD_index >> 6] |= 1LL << (FIELD_index & 63); + /* pcode: add = TRUE */ + res->fields[FIELD_add] = 1; + res->fields_mask[FIELD_add >> 6] |= 1LL << (FIELD_add & 63); + /* pcode: wback = FALSE */ + res->fields[FIELD_wback] = 0; + res->fields_mask[FIELD_wback >> 6] |= 1LL << (FIELD_wback & 63); + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* Encoding T2 */ + /* pattern="11111,00,0,1,00,1,Rn.4,Rt.4,imm12.12" width=32 stringency=14 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFFF00000)==0xF8900000)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ARMv6T2) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_Rn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Rn >> 6] |= 1LL << (FIELD_Rn & 63); + char Rn_width = 4; + res->fields[FIELD_Rt] = (instr & 0xF000)>>12; + res->fields_mask[FIELD_Rt >> 6] |= 1LL << (FIELD_Rt & 63); + char Rt_width = 4; + res->fields[FIELD_imm12] = instr & 0xFFF; + res->fields_mask[FIELD_imm12 >> 6] |= 1LL << (FIELD_imm12 & 63); + char imm12_width = 12; + + static const instruction_format instr_formats[] = + { + { /* LDRB<c> <Rt>,[<Rn>{,#<imm12>}] */ + "ldrb", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rt,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_MEMORY_ONE_REG_OPTIONAL_IMM,FIELD_Rn,FIELD_imm12,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_LDRB; + + /* pcode: if Rt == '1111' then SEE PLD */ + if((res->fields[FIELD_Rt]) == (0xF)) { + + return pld(req, res); + } + /* pcode: if Rn == '1111' then SEE LDRB (literal) */ + if((res->fields[FIELD_Rn]) == (0xF)) { + + return ldrb_literal(req, res); + } + /* pcode: t = UInt(Rt) */ + res->fields[FIELD_t] = (res->fields[FIELD_Rt]); + res->fields_mask[FIELD_t >> 6] |= 1LL << (FIELD_t & 63); + /* pcode: n = UInt(Rn) */ + res->fields[FIELD_n] = (res->fields[FIELD_Rn]); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: imm32 = ZeroExtend(imm12, 32) */ + res->fields[FIELD_imm32] = res->fields[FIELD_imm12]; + res->fields_mask[FIELD_imm32 >> 6] |= 1LL << (FIELD_imm32 & 63); + /* pcode: index = TRUE */ + res->fields[FIELD_index] = 1; + res->fields_mask[FIELD_index >> 6] |= 1LL << (FIELD_index & 63); + /* pcode: add = TRUE */ + res->fields[FIELD_add] = 1; + res->fields_mask[FIELD_add >> 6] |= 1LL << (FIELD_add & 63); + /* pcode: wback = FALSE */ + res->fields[FIELD_wback] = 0; + res->fields_mask[FIELD_wback >> 6] |= 1LL << (FIELD_wback & 63); + /* pcode: if t == 13 then UNPREDICTABLE */ + if((res->fields[FIELD_t]) == (13)) { + res->flags |= FLAG_UNPREDICTABLE; + } + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* Encoding T3 */ + /* pattern="11111,00,0,0,00,1,Rn.4,Rt.4,1,P.1,U.1,W.1,imm8.8" width=32 stringency=16 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFFF00800)==0xF8100800)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ARMv6T2) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_Rn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Rn >> 6] |= 1LL << (FIELD_Rn & 63); + char Rn_width = 4; + res->fields[FIELD_Rt] = (instr & 0xF000)>>12; + res->fields_mask[FIELD_Rt >> 6] |= 1LL << (FIELD_Rt & 63); + char Rt_width = 4; + res->fields[FIELD_P] = (instr & 0x400)>>10; + res->fields_mask[FIELD_P >> 6] |= 1LL << (FIELD_P & 63); + char P_width = 1; + res->fields[FIELD_U] = (instr & 0x200)>>9; + res->fields_mask[FIELD_U >> 6] |= 1LL << (FIELD_U & 63); + char U_width = 1; + res->fields[FIELD_W] = (instr & 0x100)>>8; + res->fields_mask[FIELD_W >> 6] |= 1LL << (FIELD_W & 63); + char W_width = 1; + res->fields[FIELD_imm8] = instr & 0xFF; + res->fields_mask[FIELD_imm8 >> 6] |= 1LL << (FIELD_imm8 & 63); + char imm8_width = 8; + + static const instruction_format instr_formats[] = + { + { /* LDRB<c> <Rt>,[<Rn>,#-<imm8>] */ + "ldrb", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rt,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_MEMORY_ONE_REG_NEG_IMM,FIELD_Rn,FIELD_imm8,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + { /* LDRB<c> <Rt>,[<Rn>,#<+/-><imm32>]! */ + "ldrb", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rt,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_MEMORY_ONE_REG_ADD_IMM,FIELD_Rn,FIELD_imm32,"","",WRITEBACK_YES}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + { /* LDRB<c> <Rt>,[<Rn>],#<+/-><imm32> */ + "ldrb", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rt,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_MEMORY_ONE_REG,FIELD_Rn,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_ADD_IMM,FIELD_imm32,FIELD_UNINIT,"#","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 3; + res->mnem = armv7::ARMV7_LDRB; + + /* pcode: if Rt == '1111' && P == '1' && U == '0' && W == '0' then SEE PLD */ + if(((((res->fields[FIELD_Rt]) == (0xF)) && ((res->fields[FIELD_P]) == (0x1))) && ((res->fields[FIELD_U]) == (0x0))) && ((res->fields[FIELD_W]) == (0x0))) { + + return pld(req, res); + } + /* pcode: if Rn == '1111' then SEE LDRB (literal) */ + if((res->fields[FIELD_Rn]) == (0xF)) { + + return ldrb_literal(req, res); + } + /* pcode: if P == '1' && U == '1' && W == '0' then SEE LDRBT */ + if((((res->fields[FIELD_P]) == (0x1)) && ((res->fields[FIELD_U]) == (0x1))) && ((res->fields[FIELD_W]) == (0x0))) { + + return ldrbt(req, res); + } + /* pcode: if P == '0' && W == '0' then UNDEFINED */ + if(((res->fields[FIELD_P]) == (0x0)) && ((res->fields[FIELD_W]) == (0x0))) { + res->status |= STATUS_UNDEFINED; + } + /* pcode: t = UInt(Rt) */ + res->fields[FIELD_t] = (res->fields[FIELD_Rt]); + res->fields_mask[FIELD_t >> 6] |= 1LL << (FIELD_t & 63); + /* pcode: n = UInt(Rn) */ + res->fields[FIELD_n] = (res->fields[FIELD_Rn]); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: imm32 = ZeroExtend(imm8, 32) */ + res->fields[FIELD_imm32] = res->fields[FIELD_imm8]; + res->fields_mask[FIELD_imm32 >> 6] |= 1LL << (FIELD_imm32 & 63); + /* pcode: index = (P == '1') */ + res->fields[FIELD_index] = ((res->fields[FIELD_P]) == (0x1)); + res->fields_mask[FIELD_index >> 6] |= 1LL << (FIELD_index & 63); + /* pcode: add = (U == '1') */ + res->fields[FIELD_add] = ((res->fields[FIELD_U]) == (0x1)); + res->fields_mask[FIELD_add >> 6] |= 1LL << (FIELD_add & 63); + /* pcode: wback = (W == '1') */ + res->fields[FIELD_wback] = ((res->fields[FIELD_W]) == (0x1)); + res->fields_mask[FIELD_wback >> 6] |= 1LL << (FIELD_wback & 63); + /* pcode: if BadReg(t) || (wback && n == t) then UNPREDICTABLE */ + if((BadReg(res->fields[FIELD_t])) || (((res->fields[FIELD_wback]) && ((res->fields[FIELD_n]) == (res->fields[FIELD_t]))))) { + res->flags |= FLAG_UNPREDICTABLE; + } + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: 7C0FECC2 +int ldrb_literal(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + /* Encoding T1 */ + /* pattern="11111,00,0,U.1,00,1,1111,Rt.4,imm12.12" width=32 stringency=18 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFF7F0000)==0xF81F0000)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ARMv6T2) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_U] = (instr & 0x800000)>>23; + res->fields_mask[FIELD_U >> 6] |= 1LL << (FIELD_U & 63); + char U_width = 1; + res->fields[FIELD_Rt] = (instr & 0xF000)>>12; + res->fields_mask[FIELD_Rt >> 6] |= 1LL << (FIELD_Rt & 63); + char Rt_width = 4; + res->fields[FIELD_imm12] = instr & 0xFFF; + res->fields_mask[FIELD_imm12 >> 6] |= 1LL << (FIELD_imm12 & 63); + char imm12_width = 12; + + static const instruction_format instr_formats[] = + { + { /* LDRB<c> <Rt>,<label> */ + "ldrb", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rt,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_LABEL,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_LDRB; + + /* pcode: if Rt == '1111' then SEE PLD */ + if((res->fields[FIELD_Rt]) == (0xF)) { + + return pld(req, res); + } + /* pcode: t = UInt(Rt) */ + res->fields[FIELD_t] = (res->fields[FIELD_Rt]); + res->fields_mask[FIELD_t >> 6] |= 1LL << (FIELD_t & 63); + /* pcode: imm32 = ZeroExtend(imm12, 32) */ + res->fields[FIELD_imm32] = res->fields[FIELD_imm12]; + res->fields_mask[FIELD_imm32 >> 6] |= 1LL << (FIELD_imm32 & 63); + /* pcode: add = (U == '1') */ + res->fields[FIELD_add] = ((res->fields[FIELD_U]) == (0x1)); + res->fields_mask[FIELD_add >> 6] |= 1LL << (FIELD_add & 63); + /* pcode: if t == 13 then UNPREDICTABLE */ + if((res->fields[FIELD_t]) == (13)) { + res->flags |= FLAG_UNPREDICTABLE; + } + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: FE535012 +int ldrb_register(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + /* Encoding T1 */ + /* pattern="0101,110,Rm.3,Rn.3,Rt.3" width=16 stringency=7 */ + { + uint16_t instr = req->instr_word16; + if(((instr & 0xFE00)==0x5C00)) { + res->instrSize = 16; + if(!(req->arch & ARCH_ARMv4T) && !(req->arch & ARCH_ARMv5T) && !(req->arch & ARCH_ARMv6) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_Rm] = (instr & 0x1C0)>>6; + res->fields_mask[FIELD_Rm >> 6] |= 1LL << (FIELD_Rm & 63); + char Rm_width = 3; + res->fields[FIELD_Rn] = (instr & 0x38)>>3; + res->fields_mask[FIELD_Rn >> 6] |= 1LL << (FIELD_Rn & 63); + char Rn_width = 3; + res->fields[FIELD_Rt] = instr & 0x7; + res->fields_mask[FIELD_Rt >> 6] |= 1LL << (FIELD_Rt & 63); + char Rt_width = 3; + + static const instruction_format instr_formats[] = + { + { /* LDRB<c> <Rt>,[<Rn>,<Rm>] */ + "ldrb", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rt,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_MEMORY_TWO_REG,FIELD_Rn,FIELD_Rm,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_LDRB; + + /* pcode: t = UInt(Rt) */ + res->fields[FIELD_t] = (res->fields[FIELD_Rt]); + res->fields_mask[FIELD_t >> 6] |= 1LL << (FIELD_t & 63); + /* pcode: n = UInt(Rn) */ + res->fields[FIELD_n] = (res->fields[FIELD_Rn]); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: m = UInt(Rm) */ + res->fields[FIELD_m] = (res->fields[FIELD_Rm]); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + /* pcode: index = TRUE */ + res->fields[FIELD_index] = 1; + res->fields_mask[FIELD_index >> 6] |= 1LL << (FIELD_index & 63); + /* pcode: add = TRUE */ + res->fields[FIELD_add] = 1; + res->fields_mask[FIELD_add >> 6] |= 1LL << (FIELD_add & 63); + /* pcode: wback = FALSE */ + res->fields[FIELD_wback] = 0; + res->fields_mask[FIELD_wback >> 6] |= 1LL << (FIELD_wback & 63); + /* pcode: (shift_t, shift_n) = (SRType_LSL, 0) */ + res->fields[FIELD_shift_t] = 0; + res->fields_mask[FIELD_shift_t >> 6] |= 1LL << (FIELD_shift_t & 63); + res->fields[FIELD_shift_n] = 0; + res->fields_mask[FIELD_shift_n >> 6] |= 1LL << (FIELD_shift_n & 63); + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* Encoding T2 */ + /* pattern="11111,00,0,0,00,1,Rn.4,Rt.4,0,00000,imm2.2,Rm.4" width=32 stringency=18 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFFF00FC0)==0xF8100000)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ARMv6T2) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_Rn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Rn >> 6] |= 1LL << (FIELD_Rn & 63); + char Rn_width = 4; + res->fields[FIELD_Rt] = (instr & 0xF000)>>12; + res->fields_mask[FIELD_Rt >> 6] |= 1LL << (FIELD_Rt & 63); + char Rt_width = 4; + res->fields[FIELD_imm2] = (instr & 0x30)>>4; + res->fields_mask[FIELD_imm2 >> 6] |= 1LL << (FIELD_imm2 & 63); + char imm2_width = 2; + res->fields[FIELD_Rm] = instr & 0xF; + res->fields_mask[FIELD_Rm >> 6] |= 1LL << (FIELD_Rm & 63); + char Rm_width = 4; + + static const instruction_format instr_formats[] = + { + { /* LDRB<c> <Rt>,[<Rn>,<Rm>{,<shift>}] */ + "ldrb", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rt,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_MEMORY_TWO_REG_SHIFT,FIELD_Rn,FIELD_Rm,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_LDRB; + + /* pcode: if Rt == '1111' then SEE PLD */ + if((res->fields[FIELD_Rt]) == (0xF)) { + + return pld(req, res); + } + /* pcode: if Rn == '1111' then SEE LDRB (literal) */ + if((res->fields[FIELD_Rn]) == (0xF)) { + + return ldrb_literal(req, res); + } + /* pcode: t = UInt(Rt) */ + res->fields[FIELD_t] = (res->fields[FIELD_Rt]); + res->fields_mask[FIELD_t >> 6] |= 1LL << (FIELD_t & 63); + /* pcode: n = UInt(Rn) */ + res->fields[FIELD_n] = (res->fields[FIELD_Rn]); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: m = UInt(Rm) */ + res->fields[FIELD_m] = (res->fields[FIELD_Rm]); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + /* pcode: index = TRUE */ + res->fields[FIELD_index] = 1; + res->fields_mask[FIELD_index >> 6] |= 1LL << (FIELD_index & 63); + /* pcode: add = TRUE */ + res->fields[FIELD_add] = 1; + res->fields_mask[FIELD_add >> 6] |= 1LL << (FIELD_add & 63); + /* pcode: wback = FALSE */ + res->fields[FIELD_wback] = 0; + res->fields_mask[FIELD_wback >> 6] |= 1LL << (FIELD_wback & 63); + /* pcode: (shift_t, shift_n) = (SRType_LSL, UInt(imm2)) */ + res->fields[FIELD_shift_t] = 0; + res->fields_mask[FIELD_shift_t >> 6] |= 1LL << (FIELD_shift_t & 63); + res->fields[FIELD_shift_n] = (res->fields[FIELD_imm2]); + res->fields_mask[FIELD_shift_n >> 6] |= 1LL << (FIELD_shift_n & 63); + /* pcode: if t == 13 || BadReg(m) then UNPREDICTABLE */ + if(((res->fields[FIELD_t]) == (13)) || (BadReg(res->fields[FIELD_m]))) { + res->flags |= FLAG_UNPREDICTABLE; + } + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: 52F17D32 +int ldrbt(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + /* Encoding T1 */ + /* pattern="11111,00,0,0,00,1,Rn.4,Rt.4,1,110,imm8.8" width=32 stringency=16 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFFF00F00)==0xF8100E00)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ARMv6T2) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_Rn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Rn >> 6] |= 1LL << (FIELD_Rn & 63); + char Rn_width = 4; + res->fields[FIELD_Rt] = (instr & 0xF000)>>12; + res->fields_mask[FIELD_Rt >> 6] |= 1LL << (FIELD_Rt & 63); + char Rt_width = 4; + res->fields[FIELD_imm8] = instr & 0xFF; + res->fields_mask[FIELD_imm8 >> 6] |= 1LL << (FIELD_imm8 & 63); + char imm8_width = 8; + + static const instruction_format instr_formats[] = + { + { /* LDRBT<c> <Rt>,[<Rn>,#<imm8>] */ + "ldrbt", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rt,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_MEMORY_ONE_REG_IMM,FIELD_Rn,FIELD_imm8,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_LDRBT; + + /* pcode: if Rn == '1111' then SEE LDRB (literal) */ + if((res->fields[FIELD_Rn]) == (0xF)) { + + return ldrb_literal(req, res); + } + /* pcode: t = UInt(Rt) */ + res->fields[FIELD_t] = (res->fields[FIELD_Rt]); + res->fields_mask[FIELD_t >> 6] |= 1LL << (FIELD_t & 63); + /* pcode: n = UInt(Rn) */ + res->fields[FIELD_n] = (res->fields[FIELD_Rn]); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: postindex = FALSE */ + res->fields[FIELD_postindex] = 0; + res->fields_mask[FIELD_postindex >> 6] |= 1LL << (FIELD_postindex & 63); + /* pcode: add = TRUE */ + res->fields[FIELD_add] = 1; + res->fields_mask[FIELD_add >> 6] |= 1LL << (FIELD_add & 63); + /* pcode: register_form = FALSE */ + res->fields[FIELD_register_form] = 0; + res->fields_mask[FIELD_register_form >> 6] |= 1LL << (FIELD_register_form & 63); + /* pcode: imm32 = ZeroExtend(imm8, 32) */ + res->fields[FIELD_imm32] = res->fields[FIELD_imm8]; + res->fields_mask[FIELD_imm32 >> 6] |= 1LL << (FIELD_imm32 & 63); + /* pcode: if BadReg(t) then UNPREDICTABLE */ + if(BadReg(res->fields[FIELD_t])) { + res->flags |= FLAG_UNPREDICTABLE; + } + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: AE1AB629 +int ldrd_immediate(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + /* Encoding T1 */ + /* pattern="11101,00,P.1,U.1,1,W.1,1,Rn.4,Rt.4,Rt2.4,imm8.8" width=32 stringency=12 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFE500000)==0xE8500000)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ARMv6T2) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_P] = (instr & 0x1000000)>>24; + res->fields_mask[FIELD_P >> 6] |= 1LL << (FIELD_P & 63); + char P_width = 1; + res->fields[FIELD_U] = (instr & 0x800000)>>23; + res->fields_mask[FIELD_U >> 6] |= 1LL << (FIELD_U & 63); + char U_width = 1; + res->fields[FIELD_W] = (instr & 0x200000)>>21; + res->fields_mask[FIELD_W >> 6] |= 1LL << (FIELD_W & 63); + char W_width = 1; + res->fields[FIELD_Rn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Rn >> 6] |= 1LL << (FIELD_Rn & 63); + char Rn_width = 4; + res->fields[FIELD_Rt] = (instr & 0xF000)>>12; + res->fields_mask[FIELD_Rt >> 6] |= 1LL << (FIELD_Rt & 63); + char Rt_width = 4; + res->fields[FIELD_Rt2] = (instr & 0xF00)>>8; + res->fields_mask[FIELD_Rt2 >> 6] |= 1LL << (FIELD_Rt2 & 63); + char Rt2_width = 4; + res->fields[FIELD_imm8] = instr & 0xFF; + res->fields_mask[FIELD_imm8 >> 6] |= 1LL << (FIELD_imm8 & 63); + char imm8_width = 8; + + static const instruction_format instr_formats[] = + { + { /* LDRD<c> <Rt>,<Rt2>,[<Rn>{,#<+/-><imm32>}] */ + "ldrd", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rt,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rt2,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_MEMORY_ONE_REG_OPTIONAL_ADD_IMM,FIELD_Rn,FIELD_imm32,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + { /* LDRD<c> <Rt>,<Rt2>,[<Rn>,#<+/-><imm32>]! */ + "ldrd", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rt,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rt2,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_MEMORY_ONE_REG_ADD_IMM,FIELD_Rn,FIELD_imm32,"","",WRITEBACK_YES}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + { /* LDRD<c> <Rt>,<Rt2>,[<Rn>],#<+/-><imm32> */ + "ldrd", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rt,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rt2,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_MEMORY_ONE_REG,FIELD_Rn,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_ADD_IMM,FIELD_imm32,FIELD_UNINIT,"#","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 4 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 3; + res->mnem = armv7::ARMV7_LDRD; + + /* pcode: if Rn == '1111' then SEE LDRD (literal) */ + if((res->fields[FIELD_Rn]) == (0xF)) { + + return ldrd_literal(req, res); + } + /* pcode: t = UInt(Rt) */ + res->fields[FIELD_t] = (res->fields[FIELD_Rt]); + res->fields_mask[FIELD_t >> 6] |= 1LL << (FIELD_t & 63); + /* pcode: t2 = UInt(Rt2) */ + res->fields[FIELD_t2] = (res->fields[FIELD_Rt2]); + res->fields_mask[FIELD_t2 >> 6] |= 1LL << (FIELD_t2 & 63); + /* pcode: n = UInt(Rn) */ + res->fields[FIELD_n] = (res->fields[FIELD_Rn]); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: imm32 = ZeroExtend(imm8:'00', 32) */ + res->fields[FIELD_imm32] = (res->fields[FIELD_imm8]<<2)|(0x0); + res->fields_mask[FIELD_imm32 >> 6] |= 1LL << (FIELD_imm32 & 63); + /* pcode: index = (P == '1') */ + res->fields[FIELD_index] = ((res->fields[FIELD_P]) == (0x1)); + res->fields_mask[FIELD_index >> 6] |= 1LL << (FIELD_index & 63); + /* pcode: add = (U == '1') */ + res->fields[FIELD_add] = ((res->fields[FIELD_U]) == (0x1)); + res->fields_mask[FIELD_add >> 6] |= 1LL << (FIELD_add & 63); + /* pcode: wback = (W == '1') */ + res->fields[FIELD_wback] = ((res->fields[FIELD_W]) == (0x1)); + res->fields_mask[FIELD_wback >> 6] |= 1LL << (FIELD_wback & 63); + /* pcode: if wback && (n == t || n == t2) then UNPREDICTABLE */ + if((res->fields[FIELD_wback]) && ((((res->fields[FIELD_n]) == (res->fields[FIELD_t])) || ((res->fields[FIELD_n]) == (res->fields[FIELD_t2]))))) { + res->flags |= FLAG_UNPREDICTABLE; + } + /* pcode: if BadReg(t) || BadReg(t2) || t == t2 then UNPREDICTABLE */ + if(((BadReg(res->fields[FIELD_t])) || (BadReg(res->fields[FIELD_t2]))) || ((res->fields[FIELD_t]) == (res->fields[FIELD_t2]))) { + res->flags |= FLAG_UNPREDICTABLE; + } + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: 5486FABA +int ldrd_literal(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + /* Encoding T1 */ + /* pattern="11101,00,P.1,U.1,1,(0),1,1111,Rt.4,Rt2.4,imm8.8" width=32 stringency=16 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFE5F0000)==0xE85F0000)) { + res->instrSize = 32; + if(!((instr & 0x200000)==0x0)) { + res->flags |= FLAG_UNPREDICTABLE; + } + if(!(req->arch & ARCH_ARMv6T2) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_P] = (instr & 0x1000000)>>24; + res->fields_mask[FIELD_P >> 6] |= 1LL << (FIELD_P & 63); + char P_width = 1; + res->fields[FIELD_U] = (instr & 0x800000)>>23; + res->fields_mask[FIELD_U >> 6] |= 1LL << (FIELD_U & 63); + char U_width = 1; + res->fields[FIELD_Rt] = (instr & 0xF000)>>12; + res->fields_mask[FIELD_Rt >> 6] |= 1LL << (FIELD_Rt & 63); + char Rt_width = 4; + res->fields[FIELD_Rt2] = (instr & 0xF00)>>8; + res->fields_mask[FIELD_Rt2 >> 6] |= 1LL << (FIELD_Rt2 & 63); + char Rt2_width = 4; + res->fields[FIELD_imm8] = instr & 0xFF; + res->fields_mask[FIELD_imm8 >> 6] |= 1LL << (FIELD_imm8 & 63); + char imm8_width = 8; + + static const instruction_format instr_formats[] = + { + { /* LDRD<c> <Rt>,<Rt2>,<label> */ + "ldrd", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rt,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rt2,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_LABEL,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_LDRD; + + /* pcode: t = UInt(Rt) */ + res->fields[FIELD_t] = (res->fields[FIELD_Rt]); + res->fields_mask[FIELD_t >> 6] |= 1LL << (FIELD_t & 63); + /* pcode: t2 = UInt(Rt2) */ + res->fields[FIELD_t2] = (res->fields[FIELD_Rt2]); + res->fields_mask[FIELD_t2 >> 6] |= 1LL << (FIELD_t2 & 63); + /* pcode: imm32 = ZeroExtend(imm8:'00', 32) */ + res->fields[FIELD_imm32] = (res->fields[FIELD_imm8]<<2)|(0x0); + res->fields_mask[FIELD_imm32 >> 6] |= 1LL << (FIELD_imm32 & 63); + /* pcode: add = (U == '1') */ + res->fields[FIELD_add] = ((res->fields[FIELD_U]) == (0x1)); + res->fields_mask[FIELD_add >> 6] |= 1LL << (FIELD_add & 63); + /* pcode: if BadReg(t) || BadReg(t2) || t == t2 then UNPREDICTABLE */ + if(((BadReg(res->fields[FIELD_t])) || (BadReg(res->fields[FIELD_t2]))) || ((res->fields[FIELD_t]) == (res->fields[FIELD_t2]))) { + res->flags |= FLAG_UNPREDICTABLE; + } + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: 246939D7 +int ldrex(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + /* Encoding T1 */ + /* pattern="11101,00,0,0,1,0,1,Rn.4,Rt.4,(1)(1)(1)(1),imm8.8" width=32 stringency=16 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFFF00000)==0xE8500000)) { + res->instrSize = 32; + if(!((instr & 0xF00)==0xF00)) { + res->flags |= FLAG_UNPREDICTABLE; + } + if(!(req->arch & ARCH_ARMv6T2) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_Rn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Rn >> 6] |= 1LL << (FIELD_Rn & 63); + char Rn_width = 4; + res->fields[FIELD_Rt] = (instr & 0xF000)>>12; + res->fields_mask[FIELD_Rt >> 6] |= 1LL << (FIELD_Rt & 63); + char Rt_width = 4; + res->fields[FIELD_imm8] = instr & 0xFF; + res->fields_mask[FIELD_imm8 >> 6] |= 1LL << (FIELD_imm8 & 63); + char imm8_width = 8; + + static const instruction_format instr_formats[] = + { + { /* LDREX<c> <Rt>,[<Rn>{,#<imm32>}] */ + "ldrex", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rt,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_MEMORY_ONE_REG_OPTIONAL_IMM,FIELD_Rn,FIELD_imm32,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_LDREX; + + /* pcode: t = UInt(Rt) */ + res->fields[FIELD_t] = (res->fields[FIELD_Rt]); + res->fields_mask[FIELD_t >> 6] |= 1LL << (FIELD_t & 63); + /* pcode: n = UInt(Rn) */ + res->fields[FIELD_n] = (res->fields[FIELD_Rn]); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: imm32 = ZeroExtend(imm8:'00', 32) */ + res->fields[FIELD_imm32] = (res->fields[FIELD_imm8]<<2)|(0x0); + res->fields_mask[FIELD_imm32 >> 6] |= 1LL << (FIELD_imm32 & 63); + /* pcode: if BadReg(t) || n == 15 then UNPREDICTABLE */ + if((BadReg(res->fields[FIELD_t])) || ((res->fields[FIELD_n]) == (15))) { + res->flags |= FLAG_UNPREDICTABLE; + } + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: 1B2141F5 +int ldrexb(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + /* Encoding T1 */ + /* pattern="11101,000110,1,Rn.4,Rt.4,(1)(1)(1)(1),0100,(1)(1)(1)(1)" width=32 stringency=24 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFFF000F0)==0xE8D00040)) { + res->instrSize = 32; + if(!((instr & 0xF0F)==0xF0F)) { + res->flags |= FLAG_UNPREDICTABLE; + } + if(!(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_Rn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Rn >> 6] |= 1LL << (FIELD_Rn & 63); + char Rn_width = 4; + res->fields[FIELD_Rt] = (instr & 0xF000)>>12; + res->fields_mask[FIELD_Rt >> 6] |= 1LL << (FIELD_Rt & 63); + char Rt_width = 4; + + static const instruction_format instr_formats[] = + { + { /* LDREXB<c> <Rt>,[<Rn>] */ + "ldrexb", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rt,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_MEMORY_ONE_REG,FIELD_Rn,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_LDREXB; + + /* pcode: t = UInt(Rt) */ + res->fields[FIELD_t] = (res->fields[FIELD_Rt]); + res->fields_mask[FIELD_t >> 6] |= 1LL << (FIELD_t & 63); + /* pcode: n = UInt(Rn) */ + res->fields[FIELD_n] = (res->fields[FIELD_Rn]); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: if BadReg(t) || n == 15 then UNPREDICTABLE */ + if((BadReg(res->fields[FIELD_t])) || ((res->fields[FIELD_n]) == (15))) { + res->flags |= FLAG_UNPREDICTABLE; + } + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: 9D4EE09B +int ldrexd(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + /* Encoding T1 */ + /* pattern="11101,000110,1,Rn.4,Rt.4,Rt2.4,0111,(1)(1)(1)(1)" width=32 stringency=20 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFFF000F0)==0xE8D00070)) { + res->instrSize = 32; + if(!((instr & 0xF)==0xF)) { + res->flags |= FLAG_UNPREDICTABLE; + } + if(!(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_Rn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Rn >> 6] |= 1LL << (FIELD_Rn & 63); + char Rn_width = 4; + res->fields[FIELD_Rt] = (instr & 0xF000)>>12; + res->fields_mask[FIELD_Rt >> 6] |= 1LL << (FIELD_Rt & 63); + char Rt_width = 4; + res->fields[FIELD_Rt2] = (instr & 0xF00)>>8; + res->fields_mask[FIELD_Rt2 >> 6] |= 1LL << (FIELD_Rt2 & 63); + char Rt2_width = 4; + + static const instruction_format instr_formats[] = + { + { /* LDREXD<c> <Rt>,<Rt2>,[<Rn>] */ + "ldrexd", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rt,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rt2,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_MEMORY_ONE_REG,FIELD_Rn,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_LDREXD; + + /* pcode: t = UInt(Rt) */ + res->fields[FIELD_t] = (res->fields[FIELD_Rt]); + res->fields_mask[FIELD_t >> 6] |= 1LL << (FIELD_t & 63); + /* pcode: t2 = UInt(Rt2) */ + res->fields[FIELD_t2] = (res->fields[FIELD_Rt2]); + res->fields_mask[FIELD_t2 >> 6] |= 1LL << (FIELD_t2 & 63); + /* pcode: n = UInt(Rn) */ + res->fields[FIELD_n] = (res->fields[FIELD_Rn]); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: if BadReg(t) || BadReg(t2) || t == t2 || n == 15 then UNPREDICTABLE */ + if((((BadReg(res->fields[FIELD_t])) || (BadReg(res->fields[FIELD_t2]))) || ((res->fields[FIELD_t]) == (res->fields[FIELD_t2]))) || ((res->fields[FIELD_n]) == (15))) { + res->flags |= FLAG_UNPREDICTABLE; + } + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: FA1403A4 +int ldrexh(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + /* Encoding T1 */ + /* pattern="11101,000110,1,Rn.4,Rt.4,(1)(1)(1)(1),0101,(1)(1)(1)(1)" width=32 stringency=24 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFFF000F0)==0xE8D00050)) { + res->instrSize = 32; + if(!((instr & 0xF0F)==0xF0F)) { + res->flags |= FLAG_UNPREDICTABLE; + } + if(!(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_Rn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Rn >> 6] |= 1LL << (FIELD_Rn & 63); + char Rn_width = 4; + res->fields[FIELD_Rt] = (instr & 0xF000)>>12; + res->fields_mask[FIELD_Rt >> 6] |= 1LL << (FIELD_Rt & 63); + char Rt_width = 4; + + static const instruction_format instr_formats[] = + { + { /* LDREXH<c> <Rt>,[<Rn>] */ + "ldrexh", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rt,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_MEMORY_ONE_REG,FIELD_Rn,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_LDREXH; + + /* pcode: t = UInt(Rt) */ + res->fields[FIELD_t] = (res->fields[FIELD_Rt]); + res->fields_mask[FIELD_t >> 6] |= 1LL << (FIELD_t & 63); + /* pcode: n = UInt(Rn) */ + res->fields[FIELD_n] = (res->fields[FIELD_Rn]); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: if BadReg(t) || n == 15 then UNPREDICTABLE */ + if((BadReg(res->fields[FIELD_t])) || ((res->fields[FIELD_n]) == (15))) { + res->flags |= FLAG_UNPREDICTABLE; + } + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: 5E9FDD13 +int ldrh_immediate(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + /* Encoding T1 */ + /* pattern="1000,1,imm5.5,Rn.3,Rt.3" width=16 stringency=5 */ + { + uint16_t instr = req->instr_word16; + if(((instr & 0xF800)==0x8800)) { + res->instrSize = 16; + if(!(req->arch & ARCH_ARMv4T) && !(req->arch & ARCH_ARMv5T) && !(req->arch & ARCH_ARMv6) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_imm5] = (instr & 0x7C0)>>6; + res->fields_mask[FIELD_imm5 >> 6] |= 1LL << (FIELD_imm5 & 63); + char imm5_width = 5; + res->fields[FIELD_Rn] = (instr & 0x38)>>3; + res->fields_mask[FIELD_Rn >> 6] |= 1LL << (FIELD_Rn & 63); + char Rn_width = 3; + res->fields[FIELD_Rt] = instr & 0x7; + res->fields_mask[FIELD_Rt >> 6] |= 1LL << (FIELD_Rt & 63); + char Rt_width = 3; + + static const instruction_format instr_formats[] = + { + { /* LDRH<c> <Rt>,[<Rn>{,#<imm32>}] */ + "ldrh", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rt,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_MEMORY_ONE_REG_OPTIONAL_IMM,FIELD_Rn,FIELD_imm32,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_LDRH; + + /* pcode: t = UInt(Rt) */ + res->fields[FIELD_t] = (res->fields[FIELD_Rt]); + res->fields_mask[FIELD_t >> 6] |= 1LL << (FIELD_t & 63); + /* pcode: n = UInt(Rn) */ + res->fields[FIELD_n] = (res->fields[FIELD_Rn]); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: imm32 = ZeroExtend(imm5:'0', 32) */ + res->fields[FIELD_imm32] = (res->fields[FIELD_imm5]<<1)|(0x0); + res->fields_mask[FIELD_imm32 >> 6] |= 1LL << (FIELD_imm32 & 63); + /* pcode: index = TRUE */ + res->fields[FIELD_index] = 1; + res->fields_mask[FIELD_index >> 6] |= 1LL << (FIELD_index & 63); + /* pcode: add = TRUE */ + res->fields[FIELD_add] = 1; + res->fields_mask[FIELD_add >> 6] |= 1LL << (FIELD_add & 63); + /* pcode: wback = FALSE */ + res->fields[FIELD_wback] = 0; + res->fields_mask[FIELD_wback >> 6] |= 1LL << (FIELD_wback & 63); + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* Encoding T2 */ + /* pattern="11111,00,0,1,01,1,Rn.4,Rt.4,imm12.12" width=32 stringency=14 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFFF00000)==0xF8B00000)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ARMv6T2) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_Rn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Rn >> 6] |= 1LL << (FIELD_Rn & 63); + char Rn_width = 4; + res->fields[FIELD_Rt] = (instr & 0xF000)>>12; + res->fields_mask[FIELD_Rt >> 6] |= 1LL << (FIELD_Rt & 63); + char Rt_width = 4; + res->fields[FIELD_imm12] = instr & 0xFFF; + res->fields_mask[FIELD_imm12 >> 6] |= 1LL << (FIELD_imm12 & 63); + char imm12_width = 12; + + static const instruction_format instr_formats[] = + { + { /* LDRH<c> <Rt>,[<Rn>{,#<imm32>}] */ + "ldrh", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rt,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_MEMORY_ONE_REG_OPTIONAL_IMM,FIELD_Rn,FIELD_imm32,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_LDRH; + + /* pcode: if Rt == '1111' then SEE "nop" */ + if((res->fields[FIELD_Rt]) == (0xF)) { + + return nop(req, res); + } + /* pcode: if Rn == '1111' then SEE LDRH (literal) */ + if((res->fields[FIELD_Rn]) == (0xF)) { + + return ldrh_literal(req, res); + } + /* pcode: t = UInt(Rt) */ + res->fields[FIELD_t] = (res->fields[FIELD_Rt]); + res->fields_mask[FIELD_t >> 6] |= 1LL << (FIELD_t & 63); + /* pcode: n = UInt(Rn) */ + res->fields[FIELD_n] = (res->fields[FIELD_Rn]); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: imm32 = ZeroExtend(imm12, 32) */ + res->fields[FIELD_imm32] = res->fields[FIELD_imm12]; + res->fields_mask[FIELD_imm32 >> 6] |= 1LL << (FIELD_imm32 & 63); + /* pcode: index = TRUE */ + res->fields[FIELD_index] = 1; + res->fields_mask[FIELD_index >> 6] |= 1LL << (FIELD_index & 63); + /* pcode: add = TRUE */ + res->fields[FIELD_add] = 1; + res->fields_mask[FIELD_add >> 6] |= 1LL << (FIELD_add & 63); + /* pcode: wback = FALSE */ + res->fields[FIELD_wback] = 0; + res->fields_mask[FIELD_wback >> 6] |= 1LL << (FIELD_wback & 63); + /* pcode: if t == 13 then UNPREDICTABLE */ + if((res->fields[FIELD_t]) == (13)) { + res->flags |= FLAG_UNPREDICTABLE; + } + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* Encoding T3 */ + /* pattern="11111,00,0,0,01,1,Rn.4,Rt.4,1,P.1,U.1,W.1,imm8.8" width=32 stringency=16 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFFF00800)==0xF8300800)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ARMv6T2) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_Rn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Rn >> 6] |= 1LL << (FIELD_Rn & 63); + char Rn_width = 4; + res->fields[FIELD_Rt] = (instr & 0xF000)>>12; + res->fields_mask[FIELD_Rt >> 6] |= 1LL << (FIELD_Rt & 63); + char Rt_width = 4; + res->fields[FIELD_P] = (instr & 0x400)>>10; + res->fields_mask[FIELD_P >> 6] |= 1LL << (FIELD_P & 63); + char P_width = 1; + res->fields[FIELD_U] = (instr & 0x200)>>9; + res->fields_mask[FIELD_U >> 6] |= 1LL << (FIELD_U & 63); + char U_width = 1; + res->fields[FIELD_W] = (instr & 0x100)>>8; + res->fields_mask[FIELD_W >> 6] |= 1LL << (FIELD_W & 63); + char W_width = 1; + res->fields[FIELD_imm8] = instr & 0xFF; + res->fields_mask[FIELD_imm8 >> 6] |= 1LL << (FIELD_imm8 & 63); + char imm8_width = 8; + + static const instruction_format instr_formats[] = + { + { /* LDRH<c> <Rt>,[<Rn>,#-<imm32>] */ + "ldrh", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rt,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_MEMORY_ONE_REG_NEG_IMM,FIELD_Rn,FIELD_imm32,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + { /* LDRH<c> <Rt>,[<Rn>,#<+/-><imm32>]! */ + "ldrh", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rt,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_MEMORY_ONE_REG_ADD_IMM,FIELD_Rn,FIELD_imm32,"","",WRITEBACK_YES}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + { /* LDRH<c> <Rt>,[<Rn>],#<+/-><imm32> */ + "ldrh", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rt,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_MEMORY_ONE_REG,FIELD_Rn,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_ADD_IMM,FIELD_imm32,FIELD_UNINIT,"#","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 3; + res->mnem = armv7::ARMV7_LDRH; + + /* pcode: if Rn == '1111' then SEE LDRH (literal) */ + if((res->fields[FIELD_Rn]) == (0xF)) { + + return ldrh_literal(req, res); + } + /* pcode: if Rt == '1111' && P == '1' && U == '0' && W == '0' then SEE "nop" */ + if(((((res->fields[FIELD_Rt]) == (0xF)) && ((res->fields[FIELD_P]) == (0x1))) && ((res->fields[FIELD_U]) == (0x0))) && ((res->fields[FIELD_W]) == (0x0))) { + + return nop(req, res); + } + /* pcode: if P == '1' && U == '1' && W == '0' then SEE LDRHT */ + if((((res->fields[FIELD_P]) == (0x1)) && ((res->fields[FIELD_U]) == (0x1))) && ((res->fields[FIELD_W]) == (0x0))) { + + return ldrht(req, res); + } + /* pcode: if P == '0' && W == '0' then UNDEFINED */ + if(((res->fields[FIELD_P]) == (0x0)) && ((res->fields[FIELD_W]) == (0x0))) { + res->status |= STATUS_UNDEFINED; + } + /* pcode: t = UInt(Rt) */ + res->fields[FIELD_t] = (res->fields[FIELD_Rt]); + res->fields_mask[FIELD_t >> 6] |= 1LL << (FIELD_t & 63); + /* pcode: n = UInt(Rn) */ + res->fields[FIELD_n] = (res->fields[FIELD_Rn]); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: imm32 = ZeroExtend(imm8, 32) */ + res->fields[FIELD_imm32] = res->fields[FIELD_imm8]; + res->fields_mask[FIELD_imm32 >> 6] |= 1LL << (FIELD_imm32 & 63); + /* pcode: index = (P == '1') */ + res->fields[FIELD_index] = ((res->fields[FIELD_P]) == (0x1)); + res->fields_mask[FIELD_index >> 6] |= 1LL << (FIELD_index & 63); + /* pcode: add = (U == '1') */ + res->fields[FIELD_add] = ((res->fields[FIELD_U]) == (0x1)); + res->fields_mask[FIELD_add >> 6] |= 1LL << (FIELD_add & 63); + /* pcode: wback = (W == '1') */ + res->fields[FIELD_wback] = ((res->fields[FIELD_W]) == (0x1)); + res->fields_mask[FIELD_wback >> 6] |= 1LL << (FIELD_wback & 63); + /* pcode: if BadReg(t) || (wback && n == t) then UNPREDICTABLE */ + if((BadReg(res->fields[FIELD_t])) || (((res->fields[FIELD_wback]) && ((res->fields[FIELD_n]) == (res->fields[FIELD_t]))))) { + res->flags |= FLAG_UNPREDICTABLE; + } + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: A1044287 +int ldrh_literal(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + /* Encoding T1 */ + /* pattern="11111,00,0,U.1,01,1,1111,Rt.4,imm12.12" width=32 stringency=18 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFF7F0000)==0xF83F0000)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ARMv6T2) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_U] = (instr & 0x800000)>>23; + res->fields_mask[FIELD_U >> 6] |= 1LL << (FIELD_U & 63); + char U_width = 1; + res->fields[FIELD_Rt] = (instr & 0xF000)>>12; + res->fields_mask[FIELD_Rt >> 6] |= 1LL << (FIELD_Rt & 63); + char Rt_width = 4; + res->fields[FIELD_imm12] = instr & 0xFFF; + res->fields_mask[FIELD_imm12 >> 6] |= 1LL << (FIELD_imm12 & 63); + char imm12_width = 12; + + static const instruction_format instr_formats[] = + { + { /* LDRH<c> <Rt>,<label> */ + "ldrh", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rt,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_LABEL,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_LDRH; + + /* pcode: if Rt == '1111' then SEE "nop" */ + if((res->fields[FIELD_Rt]) == (0xF)) { + + return nop(req, res); + } + /* pcode: t = UInt(Rt) */ + res->fields[FIELD_t] = (res->fields[FIELD_Rt]); + res->fields_mask[FIELD_t >> 6] |= 1LL << (FIELD_t & 63); + /* pcode: imm32 = ZeroExtend(imm12, 32) */ + res->fields[FIELD_imm32] = res->fields[FIELD_imm12]; + res->fields_mask[FIELD_imm32 >> 6] |= 1LL << (FIELD_imm32 & 63); + /* pcode: add = (U == '1') */ + res->fields[FIELD_add] = ((res->fields[FIELD_U]) == (0x1)); + res->fields_mask[FIELD_add >> 6] |= 1LL << (FIELD_add & 63); + /* pcode: if t == 13 then UNPREDICTABLE */ + if((res->fields[FIELD_t]) == (13)) { + res->flags |= FLAG_UNPREDICTABLE; + } + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: 212555C2 +int ldrh_register(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + /* Encoding T1 */ + /* pattern="0101,101,Rm.3,Rn.3,Rt.3" width=16 stringency=7 */ + { + uint16_t instr = req->instr_word16; + if(((instr & 0xFE00)==0x5A00)) { + res->instrSize = 16; + if(!(req->arch & ARCH_ARMv4T) && !(req->arch & ARCH_ARMv5T) && !(req->arch & ARCH_ARMv6) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_Rm] = (instr & 0x1C0)>>6; + res->fields_mask[FIELD_Rm >> 6] |= 1LL << (FIELD_Rm & 63); + char Rm_width = 3; + res->fields[FIELD_Rn] = (instr & 0x38)>>3; + res->fields_mask[FIELD_Rn >> 6] |= 1LL << (FIELD_Rn & 63); + char Rn_width = 3; + res->fields[FIELD_Rt] = instr & 0x7; + res->fields_mask[FIELD_Rt >> 6] |= 1LL << (FIELD_Rt & 63); + char Rt_width = 3; + + static const instruction_format instr_formats[] = + { + { /* LDRH<c> <Rt>,[<Rn>,<Rm>] */ + "ldrh", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rt,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_MEMORY_TWO_REG,FIELD_Rn,FIELD_Rm,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_LDRH; + + /* pcode: t = UInt(Rt) */ + res->fields[FIELD_t] = (res->fields[FIELD_Rt]); + res->fields_mask[FIELD_t >> 6] |= 1LL << (FIELD_t & 63); + /* pcode: n = UInt(Rn) */ + res->fields[FIELD_n] = (res->fields[FIELD_Rn]); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: m = UInt(Rm) */ + res->fields[FIELD_m] = (res->fields[FIELD_Rm]); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + /* pcode: index = TRUE */ + res->fields[FIELD_index] = 1; + res->fields_mask[FIELD_index >> 6] |= 1LL << (FIELD_index & 63); + /* pcode: add = TRUE */ + res->fields[FIELD_add] = 1; + res->fields_mask[FIELD_add >> 6] |= 1LL << (FIELD_add & 63); + /* pcode: wback = FALSE */ + res->fields[FIELD_wback] = 0; + res->fields_mask[FIELD_wback >> 6] |= 1LL << (FIELD_wback & 63); + /* pcode: (shift_t, shift_n) = (SRType_LSL, 0) */ + res->fields[FIELD_shift_t] = 0; + res->fields_mask[FIELD_shift_t >> 6] |= 1LL << (FIELD_shift_t & 63); + res->fields[FIELD_shift_n] = 0; + res->fields_mask[FIELD_shift_n >> 6] |= 1LL << (FIELD_shift_n & 63); + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* Encoding T2 */ + /* pattern="11111,00,0,0,01,1,Rn.4,Rt.4,0,00000,imm2.2,Rm.4" width=32 stringency=18 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFFF00FC0)==0xF8300000)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ARMv6T2) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_Rn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Rn >> 6] |= 1LL << (FIELD_Rn & 63); + char Rn_width = 4; + res->fields[FIELD_Rt] = (instr & 0xF000)>>12; + res->fields_mask[FIELD_Rt >> 6] |= 1LL << (FIELD_Rt & 63); + char Rt_width = 4; + res->fields[FIELD_imm2] = (instr & 0x30)>>4; + res->fields_mask[FIELD_imm2 >> 6] |= 1LL << (FIELD_imm2 & 63); + char imm2_width = 2; + res->fields[FIELD_Rm] = instr & 0xF; + res->fields_mask[FIELD_Rm >> 6] |= 1LL << (FIELD_Rm & 63); + char Rm_width = 4; + + static const instruction_format instr_formats[] = + { + { /* LDRH<c> <Rt>,[<Rn>,<Rm>{,<shift>}] */ + "ldrh", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rt,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_MEMORY_TWO_REG_SHIFT,FIELD_Rn,FIELD_Rm,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_LDRH; + + /* pcode: if Rn == '1111' then SEE LDRH (literal) */ + if((res->fields[FIELD_Rn]) == (0xF)) { + + return ldrh_literal(req, res); + } + /* pcode: if Rt == '1111' then SEE "nop" */ + if((res->fields[FIELD_Rt]) == (0xF)) { + + return nop(req, res); + } + /* pcode: t = UInt(Rt) */ + res->fields[FIELD_t] = (res->fields[FIELD_Rt]); + res->fields_mask[FIELD_t >> 6] |= 1LL << (FIELD_t & 63); + /* pcode: n = UInt(Rn) */ + res->fields[FIELD_n] = (res->fields[FIELD_Rn]); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: m = UInt(Rm) */ + res->fields[FIELD_m] = (res->fields[FIELD_Rm]); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + /* pcode: index = TRUE */ + res->fields[FIELD_index] = 1; + res->fields_mask[FIELD_index >> 6] |= 1LL << (FIELD_index & 63); + /* pcode: add = TRUE */ + res->fields[FIELD_add] = 1; + res->fields_mask[FIELD_add >> 6] |= 1LL << (FIELD_add & 63); + /* pcode: wback = FALSE */ + res->fields[FIELD_wback] = 0; + res->fields_mask[FIELD_wback >> 6] |= 1LL << (FIELD_wback & 63); + /* pcode: (shift_t, shift_n) = (SRType_LSL, UInt(imm2)) */ + res->fields[FIELD_shift_t] = 0; + res->fields_mask[FIELD_shift_t >> 6] |= 1LL << (FIELD_shift_t & 63); + res->fields[FIELD_shift_n] = (res->fields[FIELD_imm2]); + res->fields_mask[FIELD_shift_n >> 6] |= 1LL << (FIELD_shift_n & 63); + /* pcode: if t == 13 || BadReg(m) then UNPREDICTABLE */ + if(((res->fields[FIELD_t]) == (13)) || (BadReg(res->fields[FIELD_m]))) { + res->flags |= FLAG_UNPREDICTABLE; + } + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: DCD76FEF +int ldrht(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + /* Encoding T1 */ + /* pattern="11111,00,0,0,01,1,Rn.4,Rt.4,1,110,imm8.8" width=32 stringency=16 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFFF00F00)==0xF8300E00)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ARMv6T2) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_Rn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Rn >> 6] |= 1LL << (FIELD_Rn & 63); + char Rn_width = 4; + res->fields[FIELD_Rt] = (instr & 0xF000)>>12; + res->fields_mask[FIELD_Rt >> 6] |= 1LL << (FIELD_Rt & 63); + char Rt_width = 4; + res->fields[FIELD_imm8] = instr & 0xFF; + res->fields_mask[FIELD_imm8 >> 6] |= 1LL << (FIELD_imm8 & 63); + char imm8_width = 8; + + static const instruction_format instr_formats[] = + { + { /* LDRHT<c> <Rt>,[<Rn>{,#<+/-><imm32>}] */ + "ldrht", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rt,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_MEMORY_ONE_REG_OPTIONAL_ADD_IMM,FIELD_Rn,FIELD_imm32,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_LDRHT; + + /* pcode: if Rn == '1111' then SEE LDRH (literal) */ + if((res->fields[FIELD_Rn]) == (0xF)) { + + return ldrh_literal(req, res); + } + /* pcode: t = UInt(Rt) */ + res->fields[FIELD_t] = (res->fields[FIELD_Rt]); + res->fields_mask[FIELD_t >> 6] |= 1LL << (FIELD_t & 63); + /* pcode: n = UInt(Rn) */ + res->fields[FIELD_n] = (res->fields[FIELD_Rn]); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: postindex = FALSE */ + res->fields[FIELD_postindex] = 0; + res->fields_mask[FIELD_postindex >> 6] |= 1LL << (FIELD_postindex & 63); + /* pcode: add = TRUE */ + res->fields[FIELD_add] = 1; + res->fields_mask[FIELD_add >> 6] |= 1LL << (FIELD_add & 63); + /* pcode: register_form = FALSE */ + res->fields[FIELD_register_form] = 0; + res->fields_mask[FIELD_register_form >> 6] |= 1LL << (FIELD_register_form & 63); + /* pcode: imm32 = ZeroExtend(imm8, 32) */ + res->fields[FIELD_imm32] = res->fields[FIELD_imm8]; + res->fields_mask[FIELD_imm32 >> 6] |= 1LL << (FIELD_imm32 & 63); + /* pcode: if BadReg(t) then UNPREDICTABLE */ + if(BadReg(res->fields[FIELD_t])) { + res->flags |= FLAG_UNPREDICTABLE; + } + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: B514F014 +int ldrsb_immediate(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + /* Encoding T1 */ + /* pattern="11111,00,1,1,00,1,Rn.4,Rt.4,imm12.12" width=32 stringency=14 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFFF00000)==0xF9900000)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ARMv6T2) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_Rn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Rn >> 6] |= 1LL << (FIELD_Rn & 63); + char Rn_width = 4; + res->fields[FIELD_Rt] = (instr & 0xF000)>>12; + res->fields_mask[FIELD_Rt >> 6] |= 1LL << (FIELD_Rt & 63); + char Rt_width = 4; + res->fields[FIELD_imm12] = instr & 0xFFF; + res->fields_mask[FIELD_imm12 >> 6] |= 1LL << (FIELD_imm12 & 63); + char imm12_width = 12; + + static const instruction_format instr_formats[] = + { + { /* LDRSB<c> <Rt>,[<Rn>,#<imm12>] */ + "ldrsb", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rt,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_MEMORY_ONE_REG_IMM,FIELD_Rn,FIELD_imm12,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_LDRSB; + + /* pcode: if Rt == '1111' then SEE PLI (register) */ + if((res->fields[FIELD_Rt]) == (0xF)) { + + return pli_register(req, res); + } + /* pcode: if Rn == '1111' then SEE LDRSB (literal) */ + if((res->fields[FIELD_Rn]) == (0xF)) { + + return ldrsb_literal(req, res); + } + /* pcode: t = UInt(Rt) */ + res->fields[FIELD_t] = (res->fields[FIELD_Rt]); + res->fields_mask[FIELD_t >> 6] |= 1LL << (FIELD_t & 63); + /* pcode: n = UInt(Rn) */ + res->fields[FIELD_n] = (res->fields[FIELD_Rn]); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: imm32 = ZeroExtend(imm12, 32) */ + res->fields[FIELD_imm32] = res->fields[FIELD_imm12]; + res->fields_mask[FIELD_imm32 >> 6] |= 1LL << (FIELD_imm32 & 63); + /* pcode: index = TRUE */ + res->fields[FIELD_index] = 1; + res->fields_mask[FIELD_index >> 6] |= 1LL << (FIELD_index & 63); + /* pcode: add = TRUE */ + res->fields[FIELD_add] = 1; + res->fields_mask[FIELD_add >> 6] |= 1LL << (FIELD_add & 63); + /* pcode: wback = FALSE */ + res->fields[FIELD_wback] = 0; + res->fields_mask[FIELD_wback >> 6] |= 1LL << (FIELD_wback & 63); + /* pcode: if t == 13 then UNPREDICTABLE */ + if((res->fields[FIELD_t]) == (13)) { + res->flags |= FLAG_UNPREDICTABLE; + } + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* Encoding T2 */ + /* pattern="11111,00,1,0,00,1,Rn.4,Rt.4,1,P.1,U.1,W.1,imm8.8" width=32 stringency=16 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFFF00800)==0xF9100800)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ARMv6T2) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_Rn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Rn >> 6] |= 1LL << (FIELD_Rn & 63); + char Rn_width = 4; + res->fields[FIELD_Rt] = (instr & 0xF000)>>12; + res->fields_mask[FIELD_Rt >> 6] |= 1LL << (FIELD_Rt & 63); + char Rt_width = 4; + res->fields[FIELD_P] = (instr & 0x400)>>10; + res->fields_mask[FIELD_P >> 6] |= 1LL << (FIELD_P & 63); + char P_width = 1; + res->fields[FIELD_U] = (instr & 0x200)>>9; + res->fields_mask[FIELD_U >> 6] |= 1LL << (FIELD_U & 63); + char U_width = 1; + res->fields[FIELD_W] = (instr & 0x100)>>8; + res->fields_mask[FIELD_W >> 6] |= 1LL << (FIELD_W & 63); + char W_width = 1; + res->fields[FIELD_imm8] = instr & 0xFF; + res->fields_mask[FIELD_imm8 >> 6] |= 1LL << (FIELD_imm8 & 63); + char imm8_width = 8; + + static const instruction_format instr_formats[] = + { + { /* LDRSB<c> <Rt>,[<Rn>,#-<imm8>] */ + "ldrsb", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rt,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_MEMORY_ONE_REG_NEG_IMM,FIELD_Rn,FIELD_imm8,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + { /* LDRSB<c> <Rt>,[<Rn>,#<+/-><imm8>]! */ + "ldrsb", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rt,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_MEMORY_ONE_REG_ADD_IMM,FIELD_Rn,FIELD_imm8,"","",WRITEBACK_YES}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + { /* LDRSB<c> <Rt>,[<Rn>],#<+/-><imm8> */ + "ldrsb", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rt,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_MEMORY_ONE_REG,FIELD_Rn,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_ADD_IMM,FIELD_imm8,FIELD_UNINIT,"#","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 3; + res->mnem = armv7::ARMV7_LDRSB; + + /* pcode: if Rt == '1111' && P == '1' && U == '0' && W == '0' then SEE PLI (register) */ + if(((((res->fields[FIELD_Rt]) == (0xF)) && ((res->fields[FIELD_P]) == (0x1))) && ((res->fields[FIELD_U]) == (0x0))) && ((res->fields[FIELD_W]) == (0x0))) { + + return pli_register(req, res); + } + /* pcode: if Rn == '1111' then SEE LDRSB (literal) */ + if((res->fields[FIELD_Rn]) == (0xF)) { + + return ldrsb_literal(req, res); + } + /* pcode: if P == '1' && U == '1' && W == '0' then SEE LDRSBT */ + if((((res->fields[FIELD_P]) == (0x1)) && ((res->fields[FIELD_U]) == (0x1))) && ((res->fields[FIELD_W]) == (0x0))) { + + return ldrsbt(req, res); + } + /* pcode: if P == '0' && W == '0' then UNDEFINED */ + if(((res->fields[FIELD_P]) == (0x0)) && ((res->fields[FIELD_W]) == (0x0))) { + res->status |= STATUS_UNDEFINED; + } + /* pcode: t = UInt(Rt) */ + res->fields[FIELD_t] = (res->fields[FIELD_Rt]); + res->fields_mask[FIELD_t >> 6] |= 1LL << (FIELD_t & 63); + /* pcode: n = UInt(Rn) */ + res->fields[FIELD_n] = (res->fields[FIELD_Rn]); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: imm32 = ZeroExtend(imm8, 32) */ + res->fields[FIELD_imm32] = res->fields[FIELD_imm8]; + res->fields_mask[FIELD_imm32 >> 6] |= 1LL << (FIELD_imm32 & 63); + /* pcode: index = (P == '1') */ + res->fields[FIELD_index] = ((res->fields[FIELD_P]) == (0x1)); + res->fields_mask[FIELD_index >> 6] |= 1LL << (FIELD_index & 63); + /* pcode: add = (U == '1') */ + res->fields[FIELD_add] = ((res->fields[FIELD_U]) == (0x1)); + res->fields_mask[FIELD_add >> 6] |= 1LL << (FIELD_add & 63); + /* pcode: wback = (W == '1') */ + res->fields[FIELD_wback] = ((res->fields[FIELD_W]) == (0x1)); + res->fields_mask[FIELD_wback >> 6] |= 1LL << (FIELD_wback & 63); + /* pcode: if BadReg(t) || (wback && n == t) then UNPREDICTABLE */ + if((BadReg(res->fields[FIELD_t])) || (((res->fields[FIELD_wback]) && ((res->fields[FIELD_n]) == (res->fields[FIELD_t]))))) { + res->flags |= FLAG_UNPREDICTABLE; + } + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: AF051A91 +int ldrsb_literal(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + /* Encoding T1 */ + /* pattern="11111,00,1,U.1,00,1,1111,Rt.4,imm12.12" width=32 stringency=18 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFF7F0000)==0xF91F0000)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ARMv6T2) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_U] = (instr & 0x800000)>>23; + res->fields_mask[FIELD_U >> 6] |= 1LL << (FIELD_U & 63); + char U_width = 1; + res->fields[FIELD_Rt] = (instr & 0xF000)>>12; + res->fields_mask[FIELD_Rt >> 6] |= 1LL << (FIELD_Rt & 63); + char Rt_width = 4; + res->fields[FIELD_imm12] = instr & 0xFFF; + res->fields_mask[FIELD_imm12 >> 6] |= 1LL << (FIELD_imm12 & 63); + char imm12_width = 12; + + static const instruction_format instr_formats[] = + { + { /* LDRSB<c> <Rt>,<label> */ + "ldrsb", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rt,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_LABEL,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_LDRSB; + + /* pcode: if Rt == '1111' then SEE PLI (register) */ + if((res->fields[FIELD_Rt]) == (0xF)) { + + return pli_register(req, res); + } + /* pcode: t = UInt(Rt) */ + res->fields[FIELD_t] = (res->fields[FIELD_Rt]); + res->fields_mask[FIELD_t >> 6] |= 1LL << (FIELD_t & 63); + /* pcode: imm32 = ZeroExtend(imm12, 32) */ + res->fields[FIELD_imm32] = res->fields[FIELD_imm12]; + res->fields_mask[FIELD_imm32 >> 6] |= 1LL << (FIELD_imm32 & 63); + /* pcode: add = (U == '1') */ + res->fields[FIELD_add] = ((res->fields[FIELD_U]) == (0x1)); + res->fields_mask[FIELD_add >> 6] |= 1LL << (FIELD_add & 63); + /* pcode: if t == 13 then UNPREDICTABLE */ + if((res->fields[FIELD_t]) == (13)) { + res->flags |= FLAG_UNPREDICTABLE; + } + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: A129A7CE +int ldrsb_register(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + /* Encoding T1 */ + /* pattern="0101,011,Rm.3,Rn.3,Rt.3" width=16 stringency=7 */ + { + uint16_t instr = req->instr_word16; + if(((instr & 0xFE00)==0x5600)) { + res->instrSize = 16; + if(!(req->arch & ARCH_ARMv4T) && !(req->arch & ARCH_ARMv5T) && !(req->arch & ARCH_ARMv6) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_Rm] = (instr & 0x1C0)>>6; + res->fields_mask[FIELD_Rm >> 6] |= 1LL << (FIELD_Rm & 63); + char Rm_width = 3; + res->fields[FIELD_Rn] = (instr & 0x38)>>3; + res->fields_mask[FIELD_Rn >> 6] |= 1LL << (FIELD_Rn & 63); + char Rn_width = 3; + res->fields[FIELD_Rt] = instr & 0x7; + res->fields_mask[FIELD_Rt >> 6] |= 1LL << (FIELD_Rt & 63); + char Rt_width = 3; + + static const instruction_format instr_formats[] = + { + { /* LDRSB<c> <Rt>,[<Rn>,<Rm>] */ + "ldrsb", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rt,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_MEMORY_TWO_REG,FIELD_Rn,FIELD_Rm,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_LDRSB; + + /* pcode: t = UInt(Rt) */ + res->fields[FIELD_t] = (res->fields[FIELD_Rt]); + res->fields_mask[FIELD_t >> 6] |= 1LL << (FIELD_t & 63); + /* pcode: n = UInt(Rn) */ + res->fields[FIELD_n] = (res->fields[FIELD_Rn]); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: m = UInt(Rm) */ + res->fields[FIELD_m] = (res->fields[FIELD_Rm]); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + /* pcode: index = TRUE */ + res->fields[FIELD_index] = 1; + res->fields_mask[FIELD_index >> 6] |= 1LL << (FIELD_index & 63); + /* pcode: add = TRUE */ + res->fields[FIELD_add] = 1; + res->fields_mask[FIELD_add >> 6] |= 1LL << (FIELD_add & 63); + /* pcode: wback = FALSE */ + res->fields[FIELD_wback] = 0; + res->fields_mask[FIELD_wback >> 6] |= 1LL << (FIELD_wback & 63); + /* pcode: (shift_t, shift_n) = (SRType_LSL, 0) */ + res->fields[FIELD_shift_t] = 0; + res->fields_mask[FIELD_shift_t >> 6] |= 1LL << (FIELD_shift_t & 63); + res->fields[FIELD_shift_n] = 0; + res->fields_mask[FIELD_shift_n >> 6] |= 1LL << (FIELD_shift_n & 63); + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* Encoding T2 */ + /* pattern="11111,00,1,0,00,1,Rn.4,Rt.4,0,00000,imm2.2,Rm.4" width=32 stringency=18 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFFF00FC0)==0xF9100000)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ARMv6T2) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_Rn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Rn >> 6] |= 1LL << (FIELD_Rn & 63); + char Rn_width = 4; + res->fields[FIELD_Rt] = (instr & 0xF000)>>12; + res->fields_mask[FIELD_Rt >> 6] |= 1LL << (FIELD_Rt & 63); + char Rt_width = 4; + res->fields[FIELD_imm2] = (instr & 0x30)>>4; + res->fields_mask[FIELD_imm2 >> 6] |= 1LL << (FIELD_imm2 & 63); + char imm2_width = 2; + res->fields[FIELD_Rm] = instr & 0xF; + res->fields_mask[FIELD_Rm >> 6] |= 1LL << (FIELD_Rm & 63); + char Rm_width = 4; + + static const instruction_format instr_formats[] = + { + { /* LDRSB<c> <Rt>,[<Rn>,<Rm>{,<shift>}] */ + "ldrsb", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rt,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_MEMORY_TWO_REG_SHIFT,FIELD_Rn,FIELD_Rm,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_LDRSB; + + /* pcode: if Rt == '1111' then SEE PLI (register) */ + if((res->fields[FIELD_Rt]) == (0xF)) { + + return pli_register(req, res); + } + /* pcode: if Rn == '1111' then SEE LDRSB (literal) */ + if((res->fields[FIELD_Rn]) == (0xF)) { + + return ldrsb_literal(req, res); + } + /* pcode: t = UInt(Rt) */ + res->fields[FIELD_t] = (res->fields[FIELD_Rt]); + res->fields_mask[FIELD_t >> 6] |= 1LL << (FIELD_t & 63); + /* pcode: n = UInt(Rn) */ + res->fields[FIELD_n] = (res->fields[FIELD_Rn]); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: m = UInt(Rm) */ + res->fields[FIELD_m] = (res->fields[FIELD_Rm]); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + /* pcode: index = TRUE */ + res->fields[FIELD_index] = 1; + res->fields_mask[FIELD_index >> 6] |= 1LL << (FIELD_index & 63); + /* pcode: add = TRUE */ + res->fields[FIELD_add] = 1; + res->fields_mask[FIELD_add >> 6] |= 1LL << (FIELD_add & 63); + /* pcode: wback = FALSE */ + res->fields[FIELD_wback] = 0; + res->fields_mask[FIELD_wback >> 6] |= 1LL << (FIELD_wback & 63); + /* pcode: (shift_t, shift_n) = (SRType_LSL, UInt(imm2)) */ + res->fields[FIELD_shift_t] = 0; + res->fields_mask[FIELD_shift_t >> 6] |= 1LL << (FIELD_shift_t & 63); + res->fields[FIELD_shift_n] = (res->fields[FIELD_imm2]); + res->fields_mask[FIELD_shift_n >> 6] |= 1LL << (FIELD_shift_n & 63); + /* pcode: if t == 13 || BadReg(m) then UNPREDICTABLE */ + if(((res->fields[FIELD_t]) == (13)) || (BadReg(res->fields[FIELD_m]))) { + res->flags |= FLAG_UNPREDICTABLE; + } + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: B22840C1 +int ldrsbt(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + /* Encoding T1 */ + /* pattern="11111,00,1,0,00,1,Rn.4,Rt.4,1,110,imm8.8" width=32 stringency=16 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFFF00F00)==0xF9100E00)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ARMv6T2) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_Rn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Rn >> 6] |= 1LL << (FIELD_Rn & 63); + char Rn_width = 4; + res->fields[FIELD_Rt] = (instr & 0xF000)>>12; + res->fields_mask[FIELD_Rt >> 6] |= 1LL << (FIELD_Rt & 63); + char Rt_width = 4; + res->fields[FIELD_imm8] = instr & 0xFF; + res->fields_mask[FIELD_imm8 >> 6] |= 1LL << (FIELD_imm8 & 63); + char imm8_width = 8; + + static const instruction_format instr_formats[] = + { + { /* LDRSBT<c> <Rt>,[<Rn>,#<imm8>] */ + "ldrsbt", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rt,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_MEMORY_ONE_REG_IMM,FIELD_Rn,FIELD_imm8,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_LDRSBT; + + /* pcode: if Rn == '1111' then SEE LDRSB (literal) */ + if((res->fields[FIELD_Rn]) == (0xF)) { + + return ldrsb_literal(req, res); + } + /* pcode: t = UInt(Rt) */ + res->fields[FIELD_t] = (res->fields[FIELD_Rt]); + res->fields_mask[FIELD_t >> 6] |= 1LL << (FIELD_t & 63); + /* pcode: n = UInt(Rn) */ + res->fields[FIELD_n] = (res->fields[FIELD_Rn]); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: postindex = FALSE */ + res->fields[FIELD_postindex] = 0; + res->fields_mask[FIELD_postindex >> 6] |= 1LL << (FIELD_postindex & 63); + /* pcode: add = TRUE */ + res->fields[FIELD_add] = 1; + res->fields_mask[FIELD_add >> 6] |= 1LL << (FIELD_add & 63); + /* pcode: register_form = FALSE */ + res->fields[FIELD_register_form] = 0; + res->fields_mask[FIELD_register_form >> 6] |= 1LL << (FIELD_register_form & 63); + /* pcode: imm32 = ZeroExtend(imm8, 32) */ + res->fields[FIELD_imm32] = res->fields[FIELD_imm8]; + res->fields_mask[FIELD_imm32 >> 6] |= 1LL << (FIELD_imm32 & 63); + /* pcode: if BadReg(t) then UNPREDICTABLE */ + if(BadReg(res->fields[FIELD_t])) { + res->flags |= FLAG_UNPREDICTABLE; + } + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: 9E7B5117 +int ldrsh_immediate(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + /* Encoding T1 */ + /* pattern="11111,00,1,1,01,1,Rn.4,Rt.4,imm12.12" width=32 stringency=14 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFFF00000)==0xF9B00000)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ARMv6T2) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_Rn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Rn >> 6] |= 1LL << (FIELD_Rn & 63); + char Rn_width = 4; + res->fields[FIELD_Rt] = (instr & 0xF000)>>12; + res->fields_mask[FIELD_Rt >> 6] |= 1LL << (FIELD_Rt & 63); + char Rt_width = 4; + res->fields[FIELD_imm12] = instr & 0xFFF; + res->fields_mask[FIELD_imm12 >> 6] |= 1LL << (FIELD_imm12 & 63); + char imm12_width = 12; + + static const instruction_format instr_formats[] = + { + { /* LDRSH<c> <Rt>,[<Rn>,#<+/-><imm32>] */ + "ldrsh", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rt,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_MEMORY_ONE_REG_ADD_IMM,FIELD_Rn,FIELD_imm32,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_LDRSH; + + /* pcode: if Rn == '1111' then SEE LDRSH (literal) */ + if((res->fields[FIELD_Rn]) == (0xF)) { + + return ldrsh_literal(req, res); + } + /* pcode: if Rt == '1111' then SEE "nop" */ + if((res->fields[FIELD_Rt]) == (0xF)) { + + return nop(req, res); + } + /* pcode: t = UInt(Rt) */ + res->fields[FIELD_t] = (res->fields[FIELD_Rt]); + res->fields_mask[FIELD_t >> 6] |= 1LL << (FIELD_t & 63); + /* pcode: n = UInt(Rn) */ + res->fields[FIELD_n] = (res->fields[FIELD_Rn]); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: imm32 = ZeroExtend(imm12, 32) */ + res->fields[FIELD_imm32] = res->fields[FIELD_imm12]; + res->fields_mask[FIELD_imm32 >> 6] |= 1LL << (FIELD_imm32 & 63); + /* pcode: index = TRUE */ + res->fields[FIELD_index] = 1; + res->fields_mask[FIELD_index >> 6] |= 1LL << (FIELD_index & 63); + /* pcode: add = TRUE */ + res->fields[FIELD_add] = 1; + res->fields_mask[FIELD_add >> 6] |= 1LL << (FIELD_add & 63); + /* pcode: wback = FALSE */ + res->fields[FIELD_wback] = 0; + res->fields_mask[FIELD_wback >> 6] |= 1LL << (FIELD_wback & 63); + /* pcode: if t == 13 then UNPREDICTABLE */ + if((res->fields[FIELD_t]) == (13)) { + res->flags |= FLAG_UNPREDICTABLE; + } + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* Encoding T2 */ + /* pattern="11111,00,1,0,01,1,Rn.4,Rt.4,1,P.1,U.1,W.1,imm8.8" width=32 stringency=16 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFFF00800)==0xF9300800)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ARMv6T2) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_Rn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Rn >> 6] |= 1LL << (FIELD_Rn & 63); + char Rn_width = 4; + res->fields[FIELD_Rt] = (instr & 0xF000)>>12; + res->fields_mask[FIELD_Rt >> 6] |= 1LL << (FIELD_Rt & 63); + char Rt_width = 4; + res->fields[FIELD_P] = (instr & 0x400)>>10; + res->fields_mask[FIELD_P >> 6] |= 1LL << (FIELD_P & 63); + char P_width = 1; + res->fields[FIELD_U] = (instr & 0x200)>>9; + res->fields_mask[FIELD_U >> 6] |= 1LL << (FIELD_U & 63); + char U_width = 1; + res->fields[FIELD_W] = (instr & 0x100)>>8; + res->fields_mask[FIELD_W >> 6] |= 1LL << (FIELD_W & 63); + char W_width = 1; + res->fields[FIELD_imm8] = instr & 0xFF; + res->fields_mask[FIELD_imm8 >> 6] |= 1LL << (FIELD_imm8 & 63); + char imm8_width = 8; + + static const instruction_format instr_formats[] = + { + { /* LDRSH<c> <Rt>,[<Rn>,#<+/-><imm32>] */ + "ldrsh", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rt,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_MEMORY_ONE_REG_ADD_IMM,FIELD_Rn,FIELD_imm32,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + { /* LDRSH<c> <Rt>,[<Rn>,#<+/-><imm32>]! */ + "ldrsh", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rt,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_MEMORY_ONE_REG_ADD_IMM,FIELD_Rn,FIELD_imm32,"","",WRITEBACK_YES}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + { /* LDRSH<c> <Rt>,[<Rn>],#<+/-><imm32> */ + "ldrsh", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rt,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_MEMORY_ONE_REG,FIELD_Rn,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_ADD_IMM,FIELD_imm32,FIELD_UNINIT,"#","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 3; + res->mnem = armv7::ARMV7_LDRSH; + + /* pcode: if Rn == '1111' then SEE LDRSH (literal) */ + if((res->fields[FIELD_Rn]) == (0xF)) { + + return ldrsh_literal(req, res); + } + /* pcode: if Rt == '1111' && P == '1' && U == '0' && W == '0' then SEE "nop" */ + if(((((res->fields[FIELD_Rt]) == (0xF)) && ((res->fields[FIELD_P]) == (0x1))) && ((res->fields[FIELD_U]) == (0x0))) && ((res->fields[FIELD_W]) == (0x0))) { + + return nop(req, res); + } + /* pcode: if P == '1' && U == '1' && W == '0' then SEE LDRSHT */ + if((((res->fields[FIELD_P]) == (0x1)) && ((res->fields[FIELD_U]) == (0x1))) && ((res->fields[FIELD_W]) == (0x0))) { + + return ldrsht(req, res); + } + /* pcode: if P == '0' && W == '0' then UNDEFINED */ + if(((res->fields[FIELD_P]) == (0x0)) && ((res->fields[FIELD_W]) == (0x0))) { + res->status |= STATUS_UNDEFINED; + } + /* pcode: t = UInt(Rt) */ + res->fields[FIELD_t] = (res->fields[FIELD_Rt]); + res->fields_mask[FIELD_t >> 6] |= 1LL << (FIELD_t & 63); + /* pcode: n = UInt(Rn) */ + res->fields[FIELD_n] = (res->fields[FIELD_Rn]); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: imm32 = ZeroExtend(imm8, 32) */ + res->fields[FIELD_imm32] = res->fields[FIELD_imm8]; + res->fields_mask[FIELD_imm32 >> 6] |= 1LL << (FIELD_imm32 & 63); + /* pcode: index = (P == '1') */ + res->fields[FIELD_index] = ((res->fields[FIELD_P]) == (0x1)); + res->fields_mask[FIELD_index >> 6] |= 1LL << (FIELD_index & 63); + /* pcode: add = (U == '1') */ + res->fields[FIELD_add] = ((res->fields[FIELD_U]) == (0x1)); + res->fields_mask[FIELD_add >> 6] |= 1LL << (FIELD_add & 63); + /* pcode: wback = (W == '1') */ + res->fields[FIELD_wback] = ((res->fields[FIELD_W]) == (0x1)); + res->fields_mask[FIELD_wback >> 6] |= 1LL << (FIELD_wback & 63); + /* pcode: if BadReg(t) || (wback && n == t) then UNPREDICTABLE */ + if((BadReg(res->fields[FIELD_t])) || (((res->fields[FIELD_wback]) && ((res->fields[FIELD_n]) == (res->fields[FIELD_t]))))) { + res->flags |= FLAG_UNPREDICTABLE; + } + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: B4F6E5CF +int ldrsh_literal(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + /* Encoding T1 */ + /* pattern="11111,00,1,U.1,01,1,1111,Rt.4,imm12.12" width=32 stringency=18 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFF7F0000)==0xF93F0000)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ARMv6T2) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_U] = (instr & 0x800000)>>23; + res->fields_mask[FIELD_U >> 6] |= 1LL << (FIELD_U & 63); + char U_width = 1; + res->fields[FIELD_Rt] = (instr & 0xF000)>>12; + res->fields_mask[FIELD_Rt >> 6] |= 1LL << (FIELD_Rt & 63); + char Rt_width = 4; + res->fields[FIELD_imm12] = instr & 0xFFF; + res->fields_mask[FIELD_imm12 >> 6] |= 1LL << (FIELD_imm12 & 63); + char imm12_width = 12; + + static const instruction_format instr_formats[] = + { + { /* LDRSH<c> <Rt>,<label> */ + "ldrsh", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rt,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_LABEL,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_LDRSH; + + /* pcode: if Rt == '1111' then SEE "nop" */ + if((res->fields[FIELD_Rt]) == (0xF)) { + + return nop(req, res); + } + /* pcode: t = UInt(Rt) */ + res->fields[FIELD_t] = (res->fields[FIELD_Rt]); + res->fields_mask[FIELD_t >> 6] |= 1LL << (FIELD_t & 63); + /* pcode: imm32 = ZeroExtend(imm12, 32) */ + res->fields[FIELD_imm32] = res->fields[FIELD_imm12]; + res->fields_mask[FIELD_imm32 >> 6] |= 1LL << (FIELD_imm32 & 63); + /* pcode: add = (U == '1') */ + res->fields[FIELD_add] = ((res->fields[FIELD_U]) == (0x1)); + res->fields_mask[FIELD_add >> 6] |= 1LL << (FIELD_add & 63); + /* pcode: if t == 13 then UNPREDICTABLE */ + if((res->fields[FIELD_t]) == (13)) { + res->flags |= FLAG_UNPREDICTABLE; + } + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: E32D4F89 +int ldrsh_register(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + /* Encoding T1 */ + /* pattern="0101,111,Rm.3,Rn.3,Rt.3" width=16 stringency=7 */ + { + uint16_t instr = req->instr_word16; + if(((instr & 0xFE00)==0x5E00)) { + res->instrSize = 16; + if(!(req->arch & ARCH_ARMv4T) && !(req->arch & ARCH_ARMv5T) && !(req->arch & ARCH_ARMv6) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_Rm] = (instr & 0x1C0)>>6; + res->fields_mask[FIELD_Rm >> 6] |= 1LL << (FIELD_Rm & 63); + char Rm_width = 3; + res->fields[FIELD_Rn] = (instr & 0x38)>>3; + res->fields_mask[FIELD_Rn >> 6] |= 1LL << (FIELD_Rn & 63); + char Rn_width = 3; + res->fields[FIELD_Rt] = instr & 0x7; + res->fields_mask[FIELD_Rt >> 6] |= 1LL << (FIELD_Rt & 63); + char Rt_width = 3; + + static const instruction_format instr_formats[] = + { + { /* LDRSH<c> <Rt>,[<Rn>,<Rm>] */ + "ldrsh", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rt,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_MEMORY_TWO_REG,FIELD_Rn,FIELD_Rm,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_LDRSH; + + /* pcode: t = UInt(Rt) */ + res->fields[FIELD_t] = (res->fields[FIELD_Rt]); + res->fields_mask[FIELD_t >> 6] |= 1LL << (FIELD_t & 63); + /* pcode: n = UInt(Rn) */ + res->fields[FIELD_n] = (res->fields[FIELD_Rn]); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: m = UInt(Rm) */ + res->fields[FIELD_m] = (res->fields[FIELD_Rm]); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + /* pcode: index = TRUE */ + res->fields[FIELD_index] = 1; + res->fields_mask[FIELD_index >> 6] |= 1LL << (FIELD_index & 63); + /* pcode: add = TRUE */ + res->fields[FIELD_add] = 1; + res->fields_mask[FIELD_add >> 6] |= 1LL << (FIELD_add & 63); + /* pcode: wback = FALSE */ + res->fields[FIELD_wback] = 0; + res->fields_mask[FIELD_wback >> 6] |= 1LL << (FIELD_wback & 63); + /* pcode: (shift_t, shift_n) = (SRType_LSL, 0) */ + res->fields[FIELD_shift_t] = 0; + res->fields_mask[FIELD_shift_t >> 6] |= 1LL << (FIELD_shift_t & 63); + res->fields[FIELD_shift_n] = 0; + res->fields_mask[FIELD_shift_n >> 6] |= 1LL << (FIELD_shift_n & 63); + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* Encoding T2 */ + /* pattern="11111,00,1,0,01,1,Rn.4,Rt.4,0,00000,imm2.2,Rm.4" width=32 stringency=18 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFFF00FC0)==0xF9300000)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ARMv6T2) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_Rn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Rn >> 6] |= 1LL << (FIELD_Rn & 63); + char Rn_width = 4; + res->fields[FIELD_Rt] = (instr & 0xF000)>>12; + res->fields_mask[FIELD_Rt >> 6] |= 1LL << (FIELD_Rt & 63); + char Rt_width = 4; + res->fields[FIELD_imm2] = (instr & 0x30)>>4; + res->fields_mask[FIELD_imm2 >> 6] |= 1LL << (FIELD_imm2 & 63); + char imm2_width = 2; + res->fields[FIELD_Rm] = instr & 0xF; + res->fields_mask[FIELD_Rm >> 6] |= 1LL << (FIELD_Rm & 63); + char Rm_width = 4; + + static const instruction_format instr_formats[] = + { + { /* LDRSH<c> <Rt>,[<Rn>,<Rm>{,<shift>}] */ + "ldrsh", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rt,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_MEMORY_TWO_REG_SHIFT,FIELD_Rn,FIELD_Rm,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_LDRSH; + + /* pcode: if Rn == '1111' then SEE LDRSH (literal) */ + if((res->fields[FIELD_Rn]) == (0xF)) { + + return ldrsh_literal(req, res); + } + /* pcode: if Rt == '1111' then SEE "nop" */ + if((res->fields[FIELD_Rt]) == (0xF)) { + + return nop(req, res); + } + /* pcode: t = UInt(Rt) */ + res->fields[FIELD_t] = (res->fields[FIELD_Rt]); + res->fields_mask[FIELD_t >> 6] |= 1LL << (FIELD_t & 63); + /* pcode: n = UInt(Rn) */ + res->fields[FIELD_n] = (res->fields[FIELD_Rn]); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: m = UInt(Rm) */ + res->fields[FIELD_m] = (res->fields[FIELD_Rm]); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + /* pcode: index = TRUE */ + res->fields[FIELD_index] = 1; + res->fields_mask[FIELD_index >> 6] |= 1LL << (FIELD_index & 63); + /* pcode: add = TRUE */ + res->fields[FIELD_add] = 1; + res->fields_mask[FIELD_add >> 6] |= 1LL << (FIELD_add & 63); + /* pcode: wback = FALSE */ + res->fields[FIELD_wback] = 0; + res->fields_mask[FIELD_wback >> 6] |= 1LL << (FIELD_wback & 63); + /* pcode: (shift_t, shift_n) = (SRType_LSL, UInt(imm2)) */ + res->fields[FIELD_shift_t] = 0; + res->fields_mask[FIELD_shift_t >> 6] |= 1LL << (FIELD_shift_t & 63); + res->fields[FIELD_shift_n] = (res->fields[FIELD_imm2]); + res->fields_mask[FIELD_shift_n >> 6] |= 1LL << (FIELD_shift_n & 63); + /* pcode: if t == 13 || BadReg(m) then UNPREDICTABLE */ + if(((res->fields[FIELD_t]) == (13)) || (BadReg(res->fields[FIELD_m]))) { + res->flags |= FLAG_UNPREDICTABLE; + } + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: 471E8D6D +int ldrsht(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + /* Encoding T1 */ + /* pattern="11111,00,1,0,01,1,Rn.4,Rt.4,1,110,imm8.8" width=32 stringency=16 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFFF00F00)==0xF9300E00)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ARMv6T2) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_Rn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Rn >> 6] |= 1LL << (FIELD_Rn & 63); + char Rn_width = 4; + res->fields[FIELD_Rt] = (instr & 0xF000)>>12; + res->fields_mask[FIELD_Rt >> 6] |= 1LL << (FIELD_Rt & 63); + char Rt_width = 4; + res->fields[FIELD_imm8] = instr & 0xFF; + res->fields_mask[FIELD_imm8 >> 6] |= 1LL << (FIELD_imm8 & 63); + char imm8_width = 8; + + static const instruction_format instr_formats[] = + { + { /* LDRSHT<c> <Rt>,[<Rn>{,#<+/-><imm32>}] */ + "ldrsht", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rt,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_MEMORY_ONE_REG_OPTIONAL_ADD_IMM,FIELD_Rn,FIELD_imm32,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_LDRSHT; + + /* pcode: if Rn == '1111' then SEE LDRSH (literal) */ + if((res->fields[FIELD_Rn]) == (0xF)) { + + return ldrsh_literal(req, res); + } + /* pcode: t = UInt(Rt) */ + res->fields[FIELD_t] = (res->fields[FIELD_Rt]); + res->fields_mask[FIELD_t >> 6] |= 1LL << (FIELD_t & 63); + /* pcode: n = UInt(Rn) */ + res->fields[FIELD_n] = (res->fields[FIELD_Rn]); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: postindex = FALSE */ + res->fields[FIELD_postindex] = 0; + res->fields_mask[FIELD_postindex >> 6] |= 1LL << (FIELD_postindex & 63); + /* pcode: add = TRUE */ + res->fields[FIELD_add] = 1; + res->fields_mask[FIELD_add >> 6] |= 1LL << (FIELD_add & 63); + /* pcode: register_form = FALSE */ + res->fields[FIELD_register_form] = 0; + res->fields_mask[FIELD_register_form >> 6] |= 1LL << (FIELD_register_form & 63); + /* pcode: imm32 = ZeroExtend(imm8, 32) */ + res->fields[FIELD_imm32] = res->fields[FIELD_imm8]; + res->fields_mask[FIELD_imm32 >> 6] |= 1LL << (FIELD_imm32 & 63); + /* pcode: if BadReg(t) then UNPREDICTABLE */ + if(BadReg(res->fields[FIELD_t])) { + res->flags |= FLAG_UNPREDICTABLE; + } + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: 9B676357 +int ldrt(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + /* Encoding T1 */ + /* pattern="11111,00,0,0,10,1,Rn.4,Rt.4,1,110,imm8.8" width=32 stringency=16 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFFF00F00)==0xF8500E00)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ARMv6T2) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_Rn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Rn >> 6] |= 1LL << (FIELD_Rn & 63); + char Rn_width = 4; + res->fields[FIELD_Rt] = (instr & 0xF000)>>12; + res->fields_mask[FIELD_Rt >> 6] |= 1LL << (FIELD_Rt & 63); + char Rt_width = 4; + res->fields[FIELD_imm8] = instr & 0xFF; + res->fields_mask[FIELD_imm8 >> 6] |= 1LL << (FIELD_imm8 & 63); + char imm8_width = 8; + + static const instruction_format instr_formats[] = + { + { /* LDRT<c> <Rt>,[<Rn>{,#<+/-><imm32>}] */ + "ldrt", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rt,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_MEMORY_ONE_REG_OPTIONAL_ADD_IMM,FIELD_Rn,FIELD_imm32,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_LDRT; + + /* pcode: if Rn == '1111' then SEE LDR (literal) */ + if((res->fields[FIELD_Rn]) == (0xF)) { + + return ldr_literal(req, res); + } + /* pcode: t = UInt(Rt) */ + res->fields[FIELD_t] = (res->fields[FIELD_Rt]); + res->fields_mask[FIELD_t >> 6] |= 1LL << (FIELD_t & 63); + /* pcode: n = UInt(Rn) */ + res->fields[FIELD_n] = (res->fields[FIELD_Rn]); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: postindex = FALSE */ + res->fields[FIELD_postindex] = 0; + res->fields_mask[FIELD_postindex >> 6] |= 1LL << (FIELD_postindex & 63); + /* pcode: add = TRUE */ + res->fields[FIELD_add] = 1; + res->fields_mask[FIELD_add >> 6] |= 1LL << (FIELD_add & 63); + /* pcode: register_form = FALSE */ + res->fields[FIELD_register_form] = 0; + res->fields_mask[FIELD_register_form >> 6] |= 1LL << (FIELD_register_form & 63); + /* pcode: imm32 = ZeroExtend(imm8, 32) */ + res->fields[FIELD_imm32] = res->fields[FIELD_imm8]; + res->fields_mask[FIELD_imm32 >> 6] |= 1LL << (FIELD_imm32 & 63); + /* pcode: if BadReg(t) then UNPREDICTABLE */ + if(BadReg(res->fields[FIELD_t])) { + res->flags |= FLAG_UNPREDICTABLE; + } + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: 5587515E +int load_byte_mem_hint(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + uint32_t instr = req->instr_word32; + uint32_t op1 = (instr & 0x1800000)>>23; + uint32_t Rn = (instr & 0xF0000)>>16; + uint32_t Rt = (instr & 0xF000)>>12; + uint32_t op2 = (instr & 0xFC0)>>6; + if(((op1 & 0x3)==0x0) && ((op2 & 0x3F)==0x0) && !((Rn & 0xF)==0xF) && !((Rt & 0xF)==0xF)) return ldrb_register(req, res); + if(((op1 & 0x3)==0x2) && ((op2 & 0x3F)==0x0) && !((Rn & 0xF)==0xF) && !((Rt & 0xF)==0xF)) return ldrsb_register(req, res); + if(((op1 & 0x3)==0x0) && ((op2 & 0x3F)==0x0) && !((Rn & 0xF)==0xF) && ((Rt & 0xF)==0xF)) return pld_pldw_register(req, res); + if(((op1 & 0x3)==0x2) && ((op2 & 0x3F)==0x0) && !((Rn & 0xF)==0xF) && ((Rt & 0xF)==0xF)) return pli_register(req, res); + if(((op1 & 0x3)==0x0) && ((op2 & 0x3C)==0x30) && !((Rn & 0xF)==0xF) && !((Rt & 0xF)==0xF)) return ldrb_immediate(req, res); + if(((op1 & 0x3)==0x0) && ((op2 & 0x3C)==0x38) && !((Rn & 0xF)==0xF) && !((Rt & 0xF)==0xF)) return ldrbt(req, res); + if(((op1 & 0x3)==0x2) && ((op2 & 0x3C)==0x30) && !((Rn & 0xF)==0xF) && !((Rt & 0xF)==0xF)) return ldrsb_immediate(req, res); + if(((op1 & 0x3)==0x2) && ((op2 & 0x3C)==0x38) && !((Rn & 0xF)==0xF) && !((Rt & 0xF)==0xF)) return ldrsbt(req, res); + if(((op1 & 0x3)==0x0) && ((op2 & 0x3C)==0x30) && !((Rn & 0xF)==0xF) && ((Rt & 0xF)==0xF)) return pld_pldw_immediate(req, res); + if(((op1 & 0x3)==0x0) && ((op2 & 0x3C)==0x38) && !((Rn & 0xF)==0xF) && ((Rt & 0xF)==0xF)) return unpredictable(req, res); + if(((op1 & 0x3)==0x2) && ((op2 & 0x3C)==0x30) && !((Rn & 0xF)==0xF) && ((Rt & 0xF)==0xF)) return pli_immediate_literal(req, res); + if(((op1 & 0x3)==0x2) && ((op2 & 0x3C)==0x38) && !((Rn & 0xF)==0xF) && ((Rt & 0xF)==0xF)) return unpredictable(req, res); + if(((op1 & 0x3)==0x0) && ((op2 & 0x24)==0x24) && !((Rn & 0xF)==0xF) && !((Rt & 0xF)==0xF)) return ldrb_immediate(req, res); + if(((op1 & 0x3)==0x2) && ((op2 & 0x24)==0x24) && !((Rn & 0xF)==0xF) && !((Rt & 0xF)==0xF)) return ldrsb_immediate(req, res); + if(((op1 & 0x3)==0x0) && ((op2 & 0x24)==0x24) && !((Rn & 0xF)==0xF) && ((Rt & 0xF)==0xF)) return unpredictable(req, res); + if(((op1 & 0x3)==0x2) && ((op2 & 0x24)==0x24) && !((Rn & 0xF)==0xF) && ((Rt & 0xF)==0xF)) return unpredictable(req, res); + if(((op1 & 0x3)==0x1) && !((Rn & 0xF)==0xF) && !((Rt & 0xF)==0xF) && 1) return ldrb_immediate(req, res); + if(((op1 & 0x3)==0x3) && !((Rn & 0xF)==0xF) && !((Rt & 0xF)==0xF) && 1) return ldrsb_immediate(req, res); + if(((op1 & 0x3)==0x1) && !((Rn & 0xF)==0xF) && ((Rt & 0xF)==0xF) && 1) return pld_pldw_immediate(req, res); + if(((op1 & 0x3)==0x3) && !((Rn & 0xF)==0xF) && ((Rt & 0xF)==0xF) && 1) return pli_immediate_literal(req, res); + if(((op1 & 0x2)==0x0) && ((Rn & 0xF)==0xF) && !((Rt & 0xF)==0xF) && 1) return ldrb_literal(req, res); + if(((op1 & 0x2)==0x2) && ((Rn & 0xF)==0xF) && !((Rt & 0xF)==0xF) && 1) return ldrsb_literal(req, res); + if(((op1 & 0x2)==0x0) && ((Rn & 0xF)==0xF) && ((Rt & 0xF)==0xF) && 1) return pld_literal(req, res); + if(((op1 & 0x2)==0x2) && ((Rn & 0xF)==0xF) && ((Rt & 0xF)==0xF) && 1) return pli_immediate_literal(req, res); + return undefined(req, res); +} + +// gen_crc: E480991D +int load_halfword_mem_hint(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + uint32_t instr = req->instr_word32; + uint32_t op1 = (instr & 0x1800000)>>23; + uint32_t Rn = (instr & 0xF0000)>>16; + uint32_t Rt = (instr & 0xF000)>>12; + uint32_t op2 = (instr & 0xFC0)>>6; + if(((op1 & 0x3)==0x0) && ((op2 & 0x3F)==0x0) && !((Rn & 0xF)==0xF) && !((Rt & 0xF)==0xF)) return ldrh_register(req, res); + if(((op1 & 0x3)==0x2) && ((op2 & 0x3F)==0x0) && !((Rn & 0xF)==0xF) && !((Rt & 0xF)==0xF)) return ldrsh_register(req, res); + if(((op1 & 0x3)==0x0) && ((op2 & 0x3F)==0x0) && !((Rn & 0xF)==0xF) && ((Rt & 0xF)==0xF)) return pld_pldw_register(req, res); + if(((op1 & 0x3)==0x2) && ((op2 & 0x3F)==0x0) && !((Rn & 0xF)==0xF) && ((Rt & 0xF)==0xF)) return nop(req, res); + if(((op1 & 0x3)==0x0) && ((op2 & 0x3C)==0x30) && !((Rn & 0xF)==0xF) && !((Rt & 0xF)==0xF)) return ldrh_immediate(req, res); + if(((op1 & 0x3)==0x0) && ((op2 & 0x3C)==0x38) && !((Rn & 0xF)==0xF) && !((Rt & 0xF)==0xF)) return ldrht(req, res); + if(((op1 & 0x3)==0x2) && ((op2 & 0x3C)==0x30) && !((Rn & 0xF)==0xF) && !((Rt & 0xF)==0xF)) return ldrsh_immediate(req, res); + if(((op1 & 0x3)==0x2) && ((op2 & 0x3C)==0x38) && !((Rn & 0xF)==0xF) && !((Rt & 0xF)==0xF)) return ldrsht(req, res); + if(((op1 & 0x3)==0x0) && ((op2 & 0x3C)==0x30) && !((Rn & 0xF)==0xF) && ((Rt & 0xF)==0xF)) return pld_pldw_immediate(req, res); + if(((op1 & 0x3)==0x0) && ((op2 & 0x3C)==0x38) && !((Rn & 0xF)==0xF) && ((Rt & 0xF)==0xF)) return unpredictable(req, res); + if(((op1 & 0x3)==0x2) && ((op2 & 0x3C)==0x30) && !((Rn & 0xF)==0xF) && ((Rt & 0xF)==0xF)) return nop(req, res); + if(((op1 & 0x3)==0x2) && ((op2 & 0x3C)==0x38) && !((Rn & 0xF)==0xF) && ((Rt & 0xF)==0xF)) return unpredictable(req, res); + if(((op1 & 0x3)==0x0) && ((op2 & 0x24)==0x24) && !((Rn & 0xF)==0xF) && !((Rt & 0xF)==0xF)) return ldrh_immediate(req, res); + if(((op1 & 0x3)==0x2) && ((op2 & 0x24)==0x24) && !((Rn & 0xF)==0xF) && !((Rt & 0xF)==0xF)) return ldrsh_immediate(req, res); + if(((op1 & 0x3)==0x0) && ((op2 & 0x24)==0x24) && !((Rn & 0xF)==0xF) && ((Rt & 0xF)==0xF)) return unpredictable(req, res); + if(((op1 & 0x3)==0x2) && ((op2 & 0x24)==0x24) && !((Rn & 0xF)==0xF) && ((Rt & 0xF)==0xF)) return unpredictable(req, res); + if(((op1 & 0x3)==0x1) && !((Rn & 0xF)==0xF) && !((Rt & 0xF)==0xF) && 1) return ldrh_immediate(req, res); + if(((op1 & 0x3)==0x3) && !((Rn & 0xF)==0xF) && !((Rt & 0xF)==0xF) && 1) return ldrsh_immediate(req, res); + if(((op1 & 0x3)==0x1) && !((Rn & 0xF)==0xF) && ((Rt & 0xF)==0xF) && 1) return pld_pldw_immediate(req, res); + if(((op1 & 0x3)==0x3) && !((Rn & 0xF)==0xF) && ((Rt & 0xF)==0xF) && 1) return nop(req, res); + if(((op1 & 0x2)==0x0) && ((Rn & 0xF)==0xF) && !((Rt & 0xF)==0xF) && 1) return ldrh_literal(req, res); + if(((op1 & 0x2)==0x2) && ((Rn & 0xF)==0xF) && !((Rt & 0xF)==0xF) && 1) return ldrsh_literal(req, res); + if(((op1 & 0x2)==0x0) && ((Rn & 0xF)==0xF) && ((Rt & 0xF)==0xF) && 1) return unpredictable(req, res); + if(((op1 & 0x2)==0x2) && ((Rn & 0xF)==0xF) && ((Rt & 0xF)==0xF) && 1) return nop(req, res); + return undefined(req, res); +} + +// gen_crc: 5A6DC66A +int load_lit_pool(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + /* Encoding T1 */ + /* pattern="01001,Rt.3,imm8.8" width=16 stringency=5 */ + { + uint16_t instr = req->instr_word16; + if(((instr & 0xF800)==0x4800)) { + res->instrSize = 16; + if(!(req->arch & ARCH_ARMv4T) && !(req->arch & ARCH_ARMv5T) && !(req->arch & ARCH_ARMv6) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_Rt] = (instr & 0x700)>>8; + res->fields_mask[FIELD_Rt >> 6] |= 1LL << (FIELD_Rt & 63); + char Rt_width = 3; + res->fields[FIELD_imm8] = instr & 0xFF; + res->fields_mask[FIELD_imm8 >> 6] |= 1LL << (FIELD_imm8 & 63); + char imm8_width = 8; + + static const instruction_format instr_formats[] = + { + { /* LDR<c> <Rt>,<label> */ + "ldr", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rt,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_LABEL,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_LDR; + + /* pcode: t = UInt(Rt) */ + res->fields[FIELD_t] = (res->fields[FIELD_Rt]); + res->fields_mask[FIELD_t >> 6] |= 1LL << (FIELD_t & 63); + /* pcode: imm32 = ZeroExtend(imm8:'00', 32) */ + res->fields[FIELD_imm32] = (res->fields[FIELD_imm8]<<2)|(0x0); + res->fields_mask[FIELD_imm32 >> 6] |= 1LL << (FIELD_imm32 & 63); + /* pcode: add = TRUE */ + res->fields[FIELD_add] = 1; + res->fields_mask[FIELD_add >> 6] |= 1LL << (FIELD_add & 63); + /* pcode: Rt = UInt(Rt) */ + res->fields[FIELD_Rt] = (res->fields[FIELD_Rt]); + res->fields_mask[FIELD_Rt >> 6] |= 1LL << (FIELD_Rt & 63); + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* Encoding T2 */ + /* pattern="11111,00,0,U.1,10,1,1111,Rt.4,imm12.12" width=32 stringency=18 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFF7F0000)==0xF85F0000)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ARMv6T2) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_U] = (instr & 0x800000)>>23; + res->fields_mask[FIELD_U >> 6] |= 1LL << (FIELD_U & 63); + char U_width = 1; + res->fields[FIELD_Rt] = (instr & 0xF000)>>12; + res->fields_mask[FIELD_Rt >> 6] |= 1LL << (FIELD_Rt & 63); + char Rt_width = 4; + res->fields[FIELD_imm12] = instr & 0xFFF; + res->fields_mask[FIELD_imm12 >> 6] |= 1LL << (FIELD_imm12 & 63); + char imm12_width = 12; + + static const instruction_format instr_formats[] = + { + { /* LDR<c> <Rt>,<label> */ + "ldr", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rt,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_LABEL,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_LDR; + + /* pcode: t = UInt(Rt) */ + res->fields[FIELD_t] = (res->fields[FIELD_Rt]); + res->fields_mask[FIELD_t >> 6] |= 1LL << (FIELD_t & 63); + /* pcode: imm32 = ZeroExtend(imm12, 32) */ + res->fields[FIELD_imm32] = res->fields[FIELD_imm12]; + res->fields_mask[FIELD_imm32 >> 6] |= 1LL << (FIELD_imm32 & 63); + /* pcode: add = (U == '1') */ + res->fields[FIELD_add] = ((res->fields[FIELD_U]) == (0x1)); + res->fields_mask[FIELD_add >> 6] |= 1LL << (FIELD_add & 63); + /* pcode: if t == 15 && InITBlock() && !LastInITBlock() then UNPREDICTABLE */ + if((((res->fields[FIELD_t]) == (15)) && (req->inIfThen == IFTHEN_YES)) && (!(req->inIfThenLast == IFTHENLAST_YES))) { + res->flags |= FLAG_UNPREDICTABLE; + } + /* pcode: Rt = UInt(Rt) */ + res->fields[FIELD_Rt] = (res->fields[FIELD_Rt]); + res->fields_mask[FIELD_Rt >> 6] |= 1LL << (FIELD_Rt & 63); + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: 216593B4 +int load_store_dual_exclusive_table_branch(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + uint32_t instr = req->instr_word32; + uint32_t op1 = (instr & 0x1800000)>>23; + uint32_t op2 = (instr & 0x300000)>>20; + uint32_t Rn = (instr & 0xF0000)>>16; + uint32_t op3 = (instr & 0xF0)>>4; + if(((op1 & 0x3)==0x1) && ((op2 & 0x3)==0x0) && ((op3 & 0xF)==0x4) && 1) return strexb(req, res); + if(((op1 & 0x3)==0x1) && ((op2 & 0x3)==0x0) && ((op3 & 0xF)==0x5) && 1) return strexh(req, res); + if(((op1 & 0x3)==0x1) && ((op2 & 0x3)==0x0) && ((op3 & 0xF)==0x7) && 1) return strexd(req, res); + if(((op1 & 0x3)==0x1) && ((op2 & 0x3)==0x1) && ((op3 & 0xF)==0x0) && 1) return tbb_tbh(req, res); + if(((op1 & 0x3)==0x1) && ((op2 & 0x3)==0x1) && ((op3 & 0xF)==0x1) && 1) return tbb_tbh(req, res); + if(((op1 & 0x3)==0x1) && ((op2 & 0x3)==0x1) && ((op3 & 0xF)==0x4) && 1) return ldrexb(req, res); + if(((op1 & 0x3)==0x1) && ((op2 & 0x3)==0x1) && ((op3 & 0xF)==0x5) && 1) return ldrexh(req, res); + if(((op1 & 0x3)==0x1) && ((op2 & 0x3)==0x1) && ((op3 & 0xF)==0x7) && 1) return ldrexd(req, res); + if(((op1 & 0x3)==0x1) && ((op2 & 0x3)==0x0) && ((op3 & 0xF)==0x8) && 1) return stlb(req, res); + if(((op1 & 0x3)==0x1) && ((op2 & 0x3)==0x0) && ((op3 & 0xF)==0x9) && 1) return stlh(req, res); + if(((op1 & 0x3)==0x1) && ((op2 & 0x3)==0x0) && ((op3 & 0xF)==0xA) && 1) return stl(req, res); + if(((op1 & 0x3)==0x1) && ((op2 & 0x3)==0x0) && ((op3 & 0xF)==0xC) && 1) return stlexb(req, res); + if(((op1 & 0x3)==0x1) && ((op2 & 0x3)==0x0) && ((op3 & 0xF)==0xD) && 1) return stlexh(req, res); + if(((op1 & 0x3)==0x1) && ((op2 & 0x3)==0x0) && ((op3 & 0xF)==0xE) && 1) return stlex(req, res); + if(((op1 & 0x3)==0x1) && ((op2 & 0x3)==0x1) && ((op3 & 0xF)==0x8) && 1) return ldab(req, res); + if(((op1 & 0x3)==0x1) && ((op2 & 0x3)==0x1) && ((op3 & 0xF)==0x9) && 1) return ldah(req, res); + if(((op1 & 0x3)==0x1) && ((op2 & 0x3)==0x1) && ((op3 & 0xF)==0xA) && 1) return lda(req, res); + if(((op1 & 0x3)==0x1) && ((op2 & 0x3)==0x1) && ((op3 & 0xF)==0xC) && 1) return ldaexb(req, res); + if(((op1 & 0x3)==0x1) && ((op2 & 0x3)==0x1) && ((op3 & 0xF)==0xD) && 1) return ldaexh(req, res); + if(((op1 & 0x3)==0x1) && ((op2 & 0x3)==0x1) && ((op3 & 0xF)==0xE) && 1) return ldaex(req, res); + if(((op1 & 0x2)==0x0) && ((op2 & 0x3)==0x3) && !((Rn & 0xF)==0xF) && 1) return ldrd_immediate(req, res); + if(((op1 & 0x2)==0x0) && ((op2 & 0x3)==0x3) && ((Rn & 0xF)==0xF) && 1) return ldrd_literal(req, res); + if(((op1 & 0x2)==0x2) && ((op2 & 0x1)==0x1) && !((Rn & 0xF)==0xF) && 1) return ldrd_immediate(req, res); + if(((op1 & 0x2)==0x2) && ((op2 & 0x1)==0x1) && ((Rn & 0xF)==0xF) && 1) return ldrd_literal(req, res); + if(((op1 & 0x3)==0x0) && ((op2 & 0x3)==0x0) && 1) return strex(req, res); + if(((op1 & 0x3)==0x0) && ((op2 & 0x3)==0x1) && 1) return ldrex(req, res); + if(((op1 & 0x2)==0x0) && ((op2 & 0x3)==0x2) && 1) return strd_immediate(req, res); + if(((op1 & 0x2)==0x2) && ((op2 & 0x1)==0x0) && 1) return strd_immediate(req, res); + return undefined(req, res); +} + +// gen_crc: 715F9E4E +int load_store_multiple(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + uint32_t instr = req->instr_word32; + uint32_t op = (instr & 0x1800000)>>23; + uint32_t W = (instr & 0x200000)>>21; + uint32_t L = (instr & 0x100000)>>20; + uint32_t Rn = (instr & 0xF0000)>>16; + if(((op & 0x3)==0x1) && ((L & 0x1)==0x1) && ((W & 0x1)==0x1) && !((Rn & 0xF)==0xD)) return ldm(req, res); + if(((op & 0x3)==0x1) && ((L & 0x1)==0x1) && ((W & 0x1)==0x1) && ((Rn & 0xF)==0xD)) return pop(req, res); + if(((op & 0x3)==0x2) && ((L & 0x1)==0x0) && ((W & 0x1)==0x1) && ((Rn & 0xF)==0xD)) return push(req, res); + if(((op & 0x3)==0x1) && ((L & 0x1)==0x1) && ((W & 0x1)==0x0) && 1) return ldm(req, res); + if(((op & 0x3)==0x0) && ((L & 0x1)==0x0) && 1) return srs(req, res); + if(((op & 0x3)==0x0) && ((L & 0x1)==0x1) && 1) return rfe(req, res); + if(((op & 0x3)==0x1) && ((L & 0x1)==0x0) && 1) return stm(req, res); + if(((op & 0x3)==0x2) && ((L & 0x1)==0x0) && 1) return stmdb(req, res); + if(((op & 0x3)==0x2) && ((L & 0x1)==0x1) && 1) return ldmdb(req, res); + if(((op & 0x3)==0x3) && ((L & 0x1)==0x0) && 1) return srs(req, res); + if(((op & 0x3)==0x3) && ((L & 0x1)==0x1) && 1) return rfe(req, res); + return undefined(req, res); +} + +// gen_crc: 96C7DBD3 +int load_store_single_data(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + uint16_t instr = req->instr_word16; + uint16_t opA = (instr & 0xF000)>>12; + uint16_t opB = (instr & 0xE00)>>9; + if(((opA & 0xF)==0x5) && ((opB & 0x7)==0x0)) return str_register(req, res); + if(((opA & 0xF)==0x5) && ((opB & 0x7)==0x1)) return strh_register(req, res); + if(((opA & 0xF)==0x5) && ((opB & 0x7)==0x2)) return strb_register(req, res); + if(((opA & 0xF)==0x5) && ((opB & 0x7)==0x3)) return ldrsb_register(req, res); + if(((opA & 0xF)==0x5) && ((opB & 0x7)==0x4)) return ldr_register(req, res); + if(((opA & 0xF)==0x5) && ((opB & 0x7)==0x5)) return ldrh_register(req, res); + if(((opA & 0xF)==0x5) && ((opB & 0x7)==0x6)) return ldrb_register(req, res); + if(((opA & 0xF)==0x5) && ((opB & 0x7)==0x7)) return ldrsh_register(req, res); + if(((opA & 0xF)==0x6) && ((opB & 0x4)==0x0)) return str_immediate(req, res); + if(((opA & 0xF)==0x6) && ((opB & 0x4)==0x4)) return ldr_immediate(req, res); + if(((opA & 0xF)==0x7) && ((opB & 0x4)==0x0)) return strb_immediate(req, res); + if(((opA & 0xF)==0x7) && ((opB & 0x4)==0x4)) return ldrb_immediate(req, res); + if(((opA & 0xF)==0x8) && ((opB & 0x4)==0x0)) return strh_immediate(req, res); + if(((opA & 0xF)==0x8) && ((opB & 0x4)==0x4)) return ldrh_immediate(req, res); + if(((opA & 0xF)==0x9) && ((opB & 0x4)==0x0)) return str_immediate(req, res); + if(((opA & 0xF)==0x9) && ((opB & 0x4)==0x4)) return ldr_immediate(req, res); + return undefined(req, res); +} + +// gen_crc: BAE6B3FD +int load_word(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + uint32_t instr = req->instr_word32; + uint32_t op1 = (instr & 0x1800000)>>23; + uint32_t Rn = (instr & 0xF0000)>>16; + uint32_t op2 = (instr & 0xFC0)>>6; + if(((op1 & 0x3)==0x0) && ((op2 & 0x3F)==0x0) && !((Rn & 0xF)==0xF)) return ldr_register(req, res); + if(((op1 & 0x3)==0x0) && ((op2 & 0x3C)==0x30) && !((Rn & 0xF)==0xF)) return ldr_immediate(req, res); + if(((op1 & 0x3)==0x0) && ((op2 & 0x3C)==0x38) && !((Rn & 0xF)==0xF)) return ldrt(req, res); + if(((op1 & 0x3)==0x0) && ((op2 & 0x24)==0x24) && !((Rn & 0xF)==0xF)) return ldr_immediate(req, res); + if(((op1 & 0x3)==0x1) && !((Rn & 0xF)==0xF) && 1) return ldr_immediate(req, res); + if(((op1 & 0x2)==0x0) && ((Rn & 0xF)==0xF) && 1) return ldr_literal(req, res); + return undefined(req, res); +} + +// gen_crc: A7915A16 +int long_mul_accumulate_divide(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + uint32_t instr = req->instr_word32; + uint32_t op1 = (instr & 0x700000)>>20; + uint32_t op2 = (instr & 0xF0)>>4; + if(((op1 & 0x7)==0x0) && ((op2 & 0xF)==0x0)) return smull(req, res); + if(((op1 & 0x7)==0x1) && ((op2 & 0xF)==0xF)) return sdiv(req, res); + if(((op1 & 0x7)==0x2) && ((op2 & 0xF)==0x0)) return umull(req, res); + if(((op1 & 0x7)==0x3) && ((op2 & 0xF)==0xF)) return udiv(req, res); + if(((op1 & 0x7)==0x4) && ((op2 & 0xF)==0x0)) return smlal(req, res); + if(((op1 & 0x7)==0x6) && ((op2 & 0xF)==0x0)) return umlal(req, res); + if(((op1 & 0x7)==0x6) && ((op2 & 0xF)==0x6)) return umaal(req, res); + if(((op1 & 0x7)==0x4) && ((op2 & 0xE)==0xC)) return smlald(req, res); + if(((op1 & 0x7)==0x5) && ((op2 & 0xE)==0xC)) return smlsld(req, res); + if(((op1 & 0x7)==0x4) && ((op2 & 0xC)==0x8)) return smlalbb_smlalbt_smlaltb_smlaltt(req, res); + return undefined(req, res); +} + +// gen_crc: 6B64A6FA +int lsl_immediate(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + /* Encoding T1 */ + /* pattern="000,00,imm5.5,Rm.3,Rd.3" width=16 stringency=5 */ + { + uint16_t instr = req->instr_word16; + if(((instr & 0xF800)==0x0)) { + res->instrSize = 16; + if(!(req->arch & ARCH_ARMv4T) && !(req->arch & ARCH_ARMv5T) && !(req->arch & ARCH_ARMv6) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_imm5] = (instr & 0x7C0)>>6; + res->fields_mask[FIELD_imm5 >> 6] |= 1LL << (FIELD_imm5 & 63); + char imm5_width = 5; + res->fields[FIELD_Rm] = (instr & 0x38)>>3; + res->fields_mask[FIELD_Rm >> 6] |= 1LL << (FIELD_Rm & 63); + char Rm_width = 3; + res->fields[FIELD_Rd] = instr & 0x7; + res->fields_mask[FIELD_Rd >> 6] |= 1LL << (FIELD_Rd & 63); + char Rd_width = 3; + + static const instruction_format instr_formats[] = + { + { /* LSLS <Rd>,<Rm>,#<shift_n> */ + "lsls", /* .operation (const char *) */ + 0, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rd,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rm,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_IMM,FIELD_shift_n,FIELD_UNINIT,"#","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + { /* LSL<c> <Rd>,<Rm>,#<shift_n> */ + "lsl", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rd,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rm,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_IMM,FIELD_shift_n,FIELD_UNINIT,"#","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 2; + res->mnem = armv7::ARMV7_LSLS; + + /* pcode: if imm5 == '00000' then SEE MOV (register) */ + if((res->fields[FIELD_imm5]) == (0x0)) { + + return mov_register(req, res); + } + /* pcode: d = UInt(Rd) */ + res->fields[FIELD_d] = (res->fields[FIELD_Rd]); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: m = UInt(Rm) */ + res->fields[FIELD_m] = (res->fields[FIELD_Rm]); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + /* pcode: setflags = !InITBlock() */ + res->fields[FIELD_setflags] = !(req->inIfThen == IFTHEN_YES); + res->fields_mask[FIELD_setflags >> 6] |= 1LL << (FIELD_setflags & 63); + /* pcode: (-, shift_n) = DecodeImmShift('00', imm5) */ + res->fields[FIELD_shift_n] = DecodeImmShift_shift_n(0x0, res->fields[FIELD_imm5]); + res->fields_mask[FIELD_shift_n >> 6] |= 1LL << (FIELD_shift_n & 63); + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* Encoding T2 */ + /* pattern="11101,01,0010,S.1,1111,(0),imm3.3,Rd.4,imm2.2,00,Rm.4" width=32 stringency=19 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFFEF0030)==0xEA4F0000)) { + res->instrSize = 32; + if(!((instr & 0x8000)==0x0)) { + res->flags |= FLAG_UNPREDICTABLE; + } + if(!(req->arch & ARCH_ARMv6T2) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_S] = (instr & 0x100000)>>20; + res->fields_mask[FIELD_S >> 6] |= 1LL << (FIELD_S & 63); + char S_width = 1; + res->fields[FIELD_imm3] = (instr & 0x7000)>>12; + res->fields_mask[FIELD_imm3 >> 6] |= 1LL << (FIELD_imm3 & 63); + char imm3_width = 3; + res->fields[FIELD_Rd] = (instr & 0xF00)>>8; + res->fields_mask[FIELD_Rd >> 6] |= 1LL << (FIELD_Rd & 63); + char Rd_width = 4; + res->fields[FIELD_imm2] = (instr & 0xC0)>>6; + res->fields_mask[FIELD_imm2 >> 6] |= 1LL << (FIELD_imm2 & 63); + char imm2_width = 2; + res->fields[FIELD_Rm] = instr & 0xF; + res->fields_mask[FIELD_Rm >> 6] |= 1LL << (FIELD_Rm & 63); + char Rm_width = 4; + + static const instruction_format instr_formats[] = + { + { /* LSL{S}<c> <Rd>,<Rm>,#<shift_n> */ + "lsl", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_OPTIONAL_STATUS, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rd,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rm,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_IMM,FIELD_shift_n,FIELD_UNINIT,"#","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_LSL; + + /* pcode: if (imm3:imm2) == '00000' then SEE MOV (register) */ + if((((res->fields[FIELD_imm3]<<2)|(res->fields[FIELD_imm2]))) == (0x0)) { + + return mov_register(req, res); + } + /* pcode: d = UInt(Rd) */ + res->fields[FIELD_d] = (res->fields[FIELD_Rd]); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: m = UInt(Rm) */ + res->fields[FIELD_m] = (res->fields[FIELD_Rm]); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + /* pcode: setflags = (S == '1') */ + res->fields[FIELD_setflags] = ((res->fields[FIELD_S]) == (0x1)); + res->fields_mask[FIELD_setflags >> 6] |= 1LL << (FIELD_setflags & 63); + /* pcode: (-, shift_n) = DecodeImmShift('00', imm3:imm2) */ + res->fields[FIELD_shift_n] = DecodeImmShift_shift_n(0x0, (res->fields[FIELD_imm3]<<2)|(res->fields[FIELD_imm2])); + res->fields_mask[FIELD_shift_n >> 6] |= 1LL << (FIELD_shift_n & 63); + /* pcode: if BadReg(d) || BadReg(m) then UNPREDICTABLE */ + if((BadReg(res->fields[FIELD_d])) || (BadReg(res->fields[FIELD_m]))) { + res->flags |= FLAG_UNPREDICTABLE; + } + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: D844B10D +int lsl_register(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + /* Encoding T1 */ + /* pattern="010000,0010,Rm.3,Rdn.3" width=16 stringency=10 */ + { + uint16_t instr = req->instr_word16; + if(((instr & 0xFFC0)==0x4080)) { + res->instrSize = 16; + if(!(req->arch & ARCH_ARMv4T) && !(req->arch & ARCH_ARMv5T) && !(req->arch & ARCH_ARMv6) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_Rm] = (instr & 0x38)>>3; + res->fields_mask[FIELD_Rm >> 6] |= 1LL << (FIELD_Rm & 63); + char Rm_width = 3; + res->fields[FIELD_Rdn] = instr & 0x7; + res->fields_mask[FIELD_Rdn >> 6] |= 1LL << (FIELD_Rdn & 63); + char Rdn_width = 3; + + static const instruction_format instr_formats[] = + { + { /* LSLS <Rdn>,<Rm> */ + "lsls", /* .operation (const char *) */ + 0, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rdn,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rm,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + { /* LSL<c> <Rdn>,<Rm> */ + "lsl", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rdn,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rm,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 2; + res->mnem = armv7::ARMV7_LSLS; + + /* pcode: d = UInt(Rdn) */ + res->fields[FIELD_d] = (res->fields[FIELD_Rdn]); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: n = UInt(Rdn) */ + res->fields[FIELD_n] = (res->fields[FIELD_Rdn]); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: m = UInt(Rm) */ + res->fields[FIELD_m] = (res->fields[FIELD_Rm]); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + /* pcode: setflags = !InITBlock() */ + res->fields[FIELD_setflags] = !(req->inIfThen == IFTHEN_YES); + res->fields_mask[FIELD_setflags >> 6] |= 1LL << (FIELD_setflags & 63); + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* Encoding T2 */ + /* pattern="11111,010,0,00,S.1,Rn.4,1111,Rd.4,0,000,Rm.4" width=32 stringency=20 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFFE0F0F0)==0xFA00F000)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ARMv6T2) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_S] = (instr & 0x100000)>>20; + res->fields_mask[FIELD_S >> 6] |= 1LL << (FIELD_S & 63); + char S_width = 1; + res->fields[FIELD_Rn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Rn >> 6] |= 1LL << (FIELD_Rn & 63); + char Rn_width = 4; + res->fields[FIELD_Rd] = (instr & 0xF00)>>8; + res->fields_mask[FIELD_Rd >> 6] |= 1LL << (FIELD_Rd & 63); + char Rd_width = 4; + res->fields[FIELD_Rm] = instr & 0xF; + res->fields_mask[FIELD_Rm >> 6] |= 1LL << (FIELD_Rm & 63); + char Rm_width = 4; + + static const instruction_format instr_formats[] = + { + { /* LSL{S}<c> <Rd>,<Rn>,<Rm> */ + "lsl", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_OPTIONAL_STATUS, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rd,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rn,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rm,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_LSL; + + /* pcode: d = UInt(Rd) */ + res->fields[FIELD_d] = (res->fields[FIELD_Rd]); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: n = UInt(Rn) */ + res->fields[FIELD_n] = (res->fields[FIELD_Rn]); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: m = UInt(Rm) */ + res->fields[FIELD_m] = (res->fields[FIELD_Rm]); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + /* pcode: setflags = (S == '1') */ + res->fields[FIELD_setflags] = ((res->fields[FIELD_S]) == (0x1)); + res->fields_mask[FIELD_setflags >> 6] |= 1LL << (FIELD_setflags & 63); + /* pcode: if BadReg(d) || BadReg(n) || BadReg(m) then UNPREDICTABLE */ + if(((BadReg(res->fields[FIELD_d])) || (BadReg(res->fields[FIELD_n]))) || (BadReg(res->fields[FIELD_m]))) { + res->flags |= FLAG_UNPREDICTABLE; + } + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: 52E99BFA +int lsr_immediate(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + /* Encoding T1 */ + /* pattern="000,01,imm5.5,Rm.3,Rd.3" width=16 stringency=5 */ + { + uint16_t instr = req->instr_word16; + if(((instr & 0xF800)==0x800)) { + res->instrSize = 16; + if(!(req->arch & ARCH_ARMv4T) && !(req->arch & ARCH_ARMv5T) && !(req->arch & ARCH_ARMv6) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_imm5] = (instr & 0x7C0)>>6; + res->fields_mask[FIELD_imm5 >> 6] |= 1LL << (FIELD_imm5 & 63); + char imm5_width = 5; + res->fields[FIELD_Rm] = (instr & 0x38)>>3; + res->fields_mask[FIELD_Rm >> 6] |= 1LL << (FIELD_Rm & 63); + char Rm_width = 3; + res->fields[FIELD_Rd] = instr & 0x7; + res->fields_mask[FIELD_Rd >> 6] |= 1LL << (FIELD_Rd & 63); + char Rd_width = 3; + + static const instruction_format instr_formats[] = + { + { /* LSRS <Rd>,<Rm>,#<shift_n> */ + "lsrs", /* .operation (const char *) */ + 0, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rd,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rm,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_IMM,FIELD_shift_n,FIELD_UNINIT,"#","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + { /* LSR<c> <Rd>,<Rm>,#<shift_n> */ + "lsr", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rd,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rm,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_IMM,FIELD_shift_n,FIELD_UNINIT,"#","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 2; + res->mnem = armv7::ARMV7_LSRS; + + /* pcode: d = UInt(Rd) */ + res->fields[FIELD_d] = (res->fields[FIELD_Rd]); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: m = UInt(Rm) */ + res->fields[FIELD_m] = (res->fields[FIELD_Rm]); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + /* pcode: setflags = !InITBlock() */ + res->fields[FIELD_setflags] = !(req->inIfThen == IFTHEN_YES); + res->fields_mask[FIELD_setflags >> 6] |= 1LL << (FIELD_setflags & 63); + /* pcode: (-, shift_n) = DecodeImmShift('01', imm5) */ + res->fields[FIELD_shift_n] = DecodeImmShift_shift_n(0x1, res->fields[FIELD_imm5]); + res->fields_mask[FIELD_shift_n >> 6] |= 1LL << (FIELD_shift_n & 63); + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* Encoding T2 */ + /* pattern="11101,01,0010,S.1,1111,(0),imm3.3,Rd.4,imm2.2,01,Rm.4" width=32 stringency=19 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFFEF0030)==0xEA4F0010)) { + res->instrSize = 32; + if(!((instr & 0x8000)==0x0)) { + res->flags |= FLAG_UNPREDICTABLE; + } + if(!(req->arch & ARCH_ARMv6T2) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_S] = (instr & 0x100000)>>20; + res->fields_mask[FIELD_S >> 6] |= 1LL << (FIELD_S & 63); + char S_width = 1; + res->fields[FIELD_imm3] = (instr & 0x7000)>>12; + res->fields_mask[FIELD_imm3 >> 6] |= 1LL << (FIELD_imm3 & 63); + char imm3_width = 3; + res->fields[FIELD_Rd] = (instr & 0xF00)>>8; + res->fields_mask[FIELD_Rd >> 6] |= 1LL << (FIELD_Rd & 63); + char Rd_width = 4; + res->fields[FIELD_imm2] = (instr & 0xC0)>>6; + res->fields_mask[FIELD_imm2 >> 6] |= 1LL << (FIELD_imm2 & 63); + char imm2_width = 2; + res->fields[FIELD_Rm] = instr & 0xF; + res->fields_mask[FIELD_Rm >> 6] |= 1LL << (FIELD_Rm & 63); + char Rm_width = 4; + + static const instruction_format instr_formats[] = + { + { /* LSR{S}<c> <Rd>,<Rm>,#<shift_n> */ + "lsr", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_OPTIONAL_STATUS, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rd,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rm,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_IMM,FIELD_shift_n,FIELD_UNINIT,"#","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_LSR; + + /* pcode: d = UInt(Rd) */ + res->fields[FIELD_d] = (res->fields[FIELD_Rd]); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: m = UInt(Rm) */ + res->fields[FIELD_m] = (res->fields[FIELD_Rm]); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + /* pcode: setflags = (S == '1') */ + res->fields[FIELD_setflags] = ((res->fields[FIELD_S]) == (0x1)); + res->fields_mask[FIELD_setflags >> 6] |= 1LL << (FIELD_setflags & 63); + /* pcode: (-, shift_n) = DecodeImmShift('01', imm3:imm2) */ + res->fields[FIELD_shift_n] = DecodeImmShift_shift_n(0x1, (res->fields[FIELD_imm3]<<2)|(res->fields[FIELD_imm2])); + res->fields_mask[FIELD_shift_n >> 6] |= 1LL << (FIELD_shift_n & 63); + /* pcode: if BadReg(d) || BadReg(m) then UNPREDICTABLE */ + if((BadReg(res->fields[FIELD_d])) || (BadReg(res->fields[FIELD_m]))) { + res->flags |= FLAG_UNPREDICTABLE; + } + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: 1FF2706A +int lsr_register(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + /* Encoding T1 */ + /* pattern="010000,0011,Rm.3,Rdn.3" width=16 stringency=10 */ + { + uint16_t instr = req->instr_word16; + if(((instr & 0xFFC0)==0x40C0)) { + res->instrSize = 16; + if(!(req->arch & ARCH_ARMv4T) && !(req->arch & ARCH_ARMv5T) && !(req->arch & ARCH_ARMv6) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_Rm] = (instr & 0x38)>>3; + res->fields_mask[FIELD_Rm >> 6] |= 1LL << (FIELD_Rm & 63); + char Rm_width = 3; + res->fields[FIELD_Rdn] = instr & 0x7; + res->fields_mask[FIELD_Rdn >> 6] |= 1LL << (FIELD_Rdn & 63); + char Rdn_width = 3; + + static const instruction_format instr_formats[] = + { + { /* LSRS <Rdn>,<Rm> */ + "lsrs", /* .operation (const char *) */ + 0, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rdn,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rm,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + { /* LSR<c> <Rdn>,<Rm> */ + "lsr", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rdn,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rm,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 2; + res->mnem = armv7::ARMV7_LSRS; + + /* pcode: d = UInt(Rdn) */ + res->fields[FIELD_d] = (res->fields[FIELD_Rdn]); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: n = UInt(Rdn) */ + res->fields[FIELD_n] = (res->fields[FIELD_Rdn]); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: m = UInt(Rm) */ + res->fields[FIELD_m] = (res->fields[FIELD_Rm]); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + /* pcode: setflags = !InITBlock() */ + res->fields[FIELD_setflags] = !(req->inIfThen == IFTHEN_YES); + res->fields_mask[FIELD_setflags >> 6] |= 1LL << (FIELD_setflags & 63); + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* Encoding T2 */ + /* pattern="11111,010,0,01,S.1,Rn.4,1111,Rd.4,0,000,Rm.4" width=32 stringency=20 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFFE0F0F0)==0xFA20F000)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ARMv6T2) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_S] = (instr & 0x100000)>>20; + res->fields_mask[FIELD_S >> 6] |= 1LL << (FIELD_S & 63); + char S_width = 1; + res->fields[FIELD_Rn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Rn >> 6] |= 1LL << (FIELD_Rn & 63); + char Rn_width = 4; + res->fields[FIELD_Rd] = (instr & 0xF00)>>8; + res->fields_mask[FIELD_Rd >> 6] |= 1LL << (FIELD_Rd & 63); + char Rd_width = 4; + res->fields[FIELD_Rm] = instr & 0xF; + res->fields_mask[FIELD_Rm >> 6] |= 1LL << (FIELD_Rm & 63); + char Rm_width = 4; + + static const instruction_format instr_formats[] = + { + { /* LSR{S}<c> <Rd>,<Rn>,<Rm> */ + "lsr", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_OPTIONAL_STATUS, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rd,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rn,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rm,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_LSR; + + /* pcode: d = UInt(Rd) */ + res->fields[FIELD_d] = (res->fields[FIELD_Rd]); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: n = UInt(Rn) */ + res->fields[FIELD_n] = (res->fields[FIELD_Rn]); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: m = UInt(Rm) */ + res->fields[FIELD_m] = (res->fields[FIELD_Rm]); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + /* pcode: setflags = (S == '1') */ + res->fields[FIELD_setflags] = ((res->fields[FIELD_S]) == (0x1)); + res->fields_mask[FIELD_setflags >> 6] |= 1LL << (FIELD_setflags & 63); + /* pcode: if BadReg(d) || BadReg(n) || BadReg(m) then UNPREDICTABLE */ + if(((BadReg(res->fields[FIELD_d])) || (BadReg(res->fields[FIELD_n]))) || (BadReg(res->fields[FIELD_m]))) { + res->flags |= FLAG_UNPREDICTABLE; + } + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: 8F57422A +int mcr_mcr2(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + /* Encoding T1 */ + /* pattern="1110,1110,opc1.3,0,CRn.4,Rt.4,coproc.4,opc2.3,1,CRm.4" width=32 stringency=11 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFF100010)==0xEE000010)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ARMv6T2) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_opc1] = (instr & 0xE00000)>>21; + res->fields_mask[FIELD_opc1 >> 6] |= 1LL << (FIELD_opc1 & 63); + char opc1_width = 3; + res->fields[FIELD_CRn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_CRn >> 6] |= 1LL << (FIELD_CRn & 63); + char CRn_width = 4; + res->fields[FIELD_Rt] = (instr & 0xF000)>>12; + res->fields_mask[FIELD_Rt >> 6] |= 1LL << (FIELD_Rt & 63); + char Rt_width = 4; + res->fields[FIELD_coproc] = (instr & 0xF00)>>8; + res->fields_mask[FIELD_coproc >> 6] |= 1LL << (FIELD_coproc & 63); + char coproc_width = 4; + res->fields[FIELD_opc2] = (instr & 0xE0)>>5; + res->fields_mask[FIELD_opc2 >> 6] |= 1LL << (FIELD_opc2 & 63); + char opc2_width = 3; + res->fields[FIELD_CRm] = instr & 0xF; + res->fields_mask[FIELD_CRm >> 6] |= 1LL << (FIELD_CRm & 63); + char CRm_width = 4; + + static const instruction_format instr_formats[] = + { + { /* MCR<c> <coproc>,#<opc1>,<Rt>,<CRn>,<CRm>,#<opc2> */ + "mcr", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_COPROC,FIELD_coproc,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_IMM,FIELD_opc1,FIELD_UNINIT,"#","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rt,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_COPROC_REG,FIELD_CRn,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_COPROC_REG,FIELD_CRm,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_IMM,FIELD_opc2,FIELD_UNINIT,"#","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 6 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_MCR; + + /* pcode: if (coproc == '1010') || (coproc == '1011') then SEE "nop" */ + if((((res->fields[FIELD_coproc]) == (0xA))) || (((res->fields[FIELD_coproc]) == (0xB)))) { + + return nop(req, res); + } + /* pcode: t = UInt(Rt) */ + res->fields[FIELD_t] = (res->fields[FIELD_Rt]); + res->fields_mask[FIELD_t >> 6] |= 1LL << (FIELD_t & 63); + /* pcode: cp = UInt(coproc) */ + res->fields[FIELD_cp] = (res->fields[FIELD_coproc]); + res->fields_mask[FIELD_cp >> 6] |= 1LL << (FIELD_cp & 63); + /* pcode: if t == 15 || (t == 13 && (CurrentInstrSet() != InstrSet_ARM)) then UNPREDICTABLE */ + if(((res->fields[FIELD_t]) == (15)) || ((((res->fields[FIELD_t]) == (13)) && (((req->instrSet) != (res->fields[FIELD_InstrSet_ARM])))))) { + res->flags |= FLAG_UNPREDICTABLE; + } + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* Encoding T2 */ + /* pattern="1111,1110,opc1.3,0,CRn.4,Rt.4,coproc.4,opc2.3,1,CRm.4" width=32 stringency=11 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFF100010)==0xFE000010)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ARMv6T2) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_opc1] = (instr & 0xE00000)>>21; + res->fields_mask[FIELD_opc1 >> 6] |= 1LL << (FIELD_opc1 & 63); + char opc1_width = 3; + res->fields[FIELD_CRn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_CRn >> 6] |= 1LL << (FIELD_CRn & 63); + char CRn_width = 4; + res->fields[FIELD_Rt] = (instr & 0xF000)>>12; + res->fields_mask[FIELD_Rt >> 6] |= 1LL << (FIELD_Rt & 63); + char Rt_width = 4; + res->fields[FIELD_coproc] = (instr & 0xF00)>>8; + res->fields_mask[FIELD_coproc >> 6] |= 1LL << (FIELD_coproc & 63); + char coproc_width = 4; + res->fields[FIELD_opc2] = (instr & 0xE0)>>5; + res->fields_mask[FIELD_opc2 >> 6] |= 1LL << (FIELD_opc2 & 63); + char opc2_width = 3; + res->fields[FIELD_CRm] = instr & 0xF; + res->fields_mask[FIELD_CRm >> 6] |= 1LL << (FIELD_CRm & 63); + char CRm_width = 4; + + static const instruction_format instr_formats[] = + { + { /* MCR2<c> <coproc>,#<opc1>,<Rt>,<CRn>,<CRm>,#<opc2> */ + "mcr2", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_COPROC,FIELD_coproc,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_IMM,FIELD_opc1,FIELD_UNINIT,"#","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rt,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_COPROC_REG,FIELD_CRn,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_COPROC_REG,FIELD_CRm,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_IMM,FIELD_opc2,FIELD_UNINIT,"#","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 6 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_MCR2; + + /* pcode: t = UInt(Rt) */ + res->fields[FIELD_t] = (res->fields[FIELD_Rt]); + res->fields_mask[FIELD_t >> 6] |= 1LL << (FIELD_t & 63); + /* pcode: cp = UInt(coproc) */ + res->fields[FIELD_cp] = (res->fields[FIELD_coproc]); + res->fields_mask[FIELD_cp >> 6] |= 1LL << (FIELD_cp & 63); + /* pcode: if t == 15 || (t == 13 && (CurrentInstrSet() != InstrSet_ARM)) then UNPREDICTABLE */ + if(((res->fields[FIELD_t]) == (15)) || ((((res->fields[FIELD_t]) == (13)) && (((req->instrSet) != (res->fields[FIELD_InstrSet_ARM])))))) { + res->flags |= FLAG_UNPREDICTABLE; + } + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: F5217F3F +int mcrr_mcrr2(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + /* Encoding T1 */ + /* pattern="1110,110,0,0,1,0,0,Rt2.4,Rt.4,coproc.4,opc1.4,CRm.4" width=32 stringency=13 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFFF00000)==0xEC400000)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ARMv6T2) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_Rt2] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Rt2 >> 6] |= 1LL << (FIELD_Rt2 & 63); + char Rt2_width = 4; + res->fields[FIELD_Rt] = (instr & 0xF000)>>12; + res->fields_mask[FIELD_Rt >> 6] |= 1LL << (FIELD_Rt & 63); + char Rt_width = 4; + res->fields[FIELD_coproc] = (instr & 0xF00)>>8; + res->fields_mask[FIELD_coproc >> 6] |= 1LL << (FIELD_coproc & 63); + char coproc_width = 4; + res->fields[FIELD_opc1] = (instr & 0xF0)>>4; + res->fields_mask[FIELD_opc1 >> 6] |= 1LL << (FIELD_opc1 & 63); + char opc1_width = 4; + res->fields[FIELD_CRm] = instr & 0xF; + res->fields_mask[FIELD_CRm >> 6] |= 1LL << (FIELD_CRm & 63); + char CRm_width = 4; + + static const instruction_format instr_formats[] = + { + { /* MCRR<c> <coproc>,#<opc1>,<Rt>,<Rt2>,<CRm> */ + "mcrr", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_COPROC,FIELD_coproc,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_IMM,FIELD_opc1,FIELD_UNINIT,"#","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rt,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rt2,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_COPROC_REG,FIELD_CRm,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 5 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_MCRR; + + /* pcode: if coproc == '1010' || coproc == '1011' then SEE "nop" */ + if(((res->fields[FIELD_coproc]) == (0xA)) || ((res->fields[FIELD_coproc]) == (0xB))) { + + return nop(req, res); + } + /* pcode: t = UInt(Rt) */ + res->fields[FIELD_t] = (res->fields[FIELD_Rt]); + res->fields_mask[FIELD_t >> 6] |= 1LL << (FIELD_t & 63); + /* pcode: t2 = UInt(Rt2) */ + res->fields[FIELD_t2] = (res->fields[FIELD_Rt2]); + res->fields_mask[FIELD_t2 >> 6] |= 1LL << (FIELD_t2 & 63); + /* pcode: cp = UInt(coproc) */ + res->fields[FIELD_cp] = (res->fields[FIELD_coproc]); + res->fields_mask[FIELD_cp >> 6] |= 1LL << (FIELD_cp & 63); + /* pcode: if t == 15 || t2 == 15 then UNPREDICTABLE */ + if(((res->fields[FIELD_t]) == (15)) || ((res->fields[FIELD_t2]) == (15))) { + res->flags |= FLAG_UNPREDICTABLE; + } + /* pcode: if (t == 13 || t2 == 13) && (CurrentInstrSet() != InstrSet_ARM) then UNPREDICTABLE */ + if(((((res->fields[FIELD_t]) == (13)) || ((res->fields[FIELD_t2]) == (13)))) && (((req->instrSet) != (res->fields[FIELD_InstrSet_ARM])))) { + res->flags |= FLAG_UNPREDICTABLE; + } + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* Encoding T2 */ + /* pattern="1111,110,0,0,1,0,0,Rt2.4,Rt.4,coproc.4,opc1.4,CRm.4" width=32 stringency=13 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFFF00000)==0xFC400000)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ARMv6T2) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_Rt2] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Rt2 >> 6] |= 1LL << (FIELD_Rt2 & 63); + char Rt2_width = 4; + res->fields[FIELD_Rt] = (instr & 0xF000)>>12; + res->fields_mask[FIELD_Rt >> 6] |= 1LL << (FIELD_Rt & 63); + char Rt_width = 4; + res->fields[FIELD_coproc] = (instr & 0xF00)>>8; + res->fields_mask[FIELD_coproc >> 6] |= 1LL << (FIELD_coproc & 63); + char coproc_width = 4; + res->fields[FIELD_opc1] = (instr & 0xF0)>>4; + res->fields_mask[FIELD_opc1 >> 6] |= 1LL << (FIELD_opc1 & 63); + char opc1_width = 4; + res->fields[FIELD_CRm] = instr & 0xF; + res->fields_mask[FIELD_CRm >> 6] |= 1LL << (FIELD_CRm & 63); + char CRm_width = 4; + + static const instruction_format instr_formats[] = + { + { /* MCRR2<c> <coproc>,#<opc1>,<Rt>,<Rt2>,<CRm> */ + "mcrr2", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_COPROC,FIELD_coproc,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_IMM,FIELD_opc1,FIELD_UNINIT,"#","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rt,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rt2,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_COPROC_REG,FIELD_CRm,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 5 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_MCRR2; + + /* pcode: t = UInt(Rt) */ + res->fields[FIELD_t] = (res->fields[FIELD_Rt]); + res->fields_mask[FIELD_t >> 6] |= 1LL << (FIELD_t & 63); + /* pcode: t2 = UInt(Rt2) */ + res->fields[FIELD_t2] = (res->fields[FIELD_Rt2]); + res->fields_mask[FIELD_t2 >> 6] |= 1LL << (FIELD_t2 & 63); + /* pcode: cp = UInt(coproc) */ + res->fields[FIELD_cp] = (res->fields[FIELD_coproc]); + res->fields_mask[FIELD_cp >> 6] |= 1LL << (FIELD_cp & 63); + /* pcode: if t == 15 || t2 == 15 then UNPREDICTABLE */ + if(((res->fields[FIELD_t]) == (15)) || ((res->fields[FIELD_t2]) == (15))) { + res->flags |= FLAG_UNPREDICTABLE; + } + /* pcode: if (t == 13 || t2 == 13) && (CurrentInstrSet() != InstrSet_ARM) then UNPREDICTABLE */ + if(((((res->fields[FIELD_t]) == (13)) || ((res->fields[FIELD_t2]) == (13)))) && (((req->instrSet) != (res->fields[FIELD_InstrSet_ARM])))) { + res->flags |= FLAG_UNPREDICTABLE; + } + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: 9ADBDA54 +int misc(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + uint16_t instr = req->instr_word16; + uint16_t opcode = (instr & 0xFE0)>>5; + if(((opcode & 0x7F)==0x32)) return setend(req, res); + if(((opcode & 0x7F)==0x33)) return cps(req, res); + if(((opcode & 0x7E)==0x10)) return sxth(req, res); + if(((opcode & 0x7E)==0x12)) return sxtb(req, res); + if(((opcode & 0x7E)==0x14)) return uxth(req, res); + if(((opcode & 0x7E)==0x16)) return uxtb(req, res); + if(((opcode & 0x7E)==0x50)) return rev(req, res); + if(((opcode & 0x7E)==0x52)) return rev16(req, res); + if(((opcode & 0x7E)==0x56)) return revsh(req, res); + if(((opcode & 0x7C)==0x0)) return add_sp_plus_immediate(req, res); + if(((opcode & 0x7C)==0x4)) return sub_sp_minus_immediate(req, res); + if(((opcode & 0x78)==0x8)) return cbnz_cbz(req, res); + if(((opcode & 0x78)==0x18)) return cbnz_cbz(req, res); + if(((opcode & 0x78)==0x48)) return cbnz_cbz(req, res); + if(((opcode & 0x78)==0x58)) return cbnz_cbz(req, res); + if(((opcode & 0x78)==0x70)) return bkpt(req, res); + if(((opcode & 0x78)==0x78)) return if_then_hints(req, res); + if(((opcode & 0x70)==0x20)) return push(req, res); + if(((opcode & 0x70)==0x60)) return pop(req, res); + return undefined(req, res); +} + +// gen_crc: EEEED2D1 +int misc_control(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + uint32_t instr = req->instr_word32; + uint32_t op = (instr & 0xF0)>>4; + if(((op & 0xF)==0x0)) return enterx_leavex(req, res); + if(((op & 0xF)==0x1)) return enterx_leavex(req, res); + if(((op & 0xF)==0x2)) return clrex(req, res); + if(((op & 0xF)==0x4)) return dsb(req, res); + if(((op & 0xF)==0x5)) return dmb(req, res); + if(((op & 0xF)==0x6)) return isb(req, res); + return undefined(req, res); +} + +// gen_crc: 436428C6 +int misc_operations(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + uint32_t instr = req->instr_word32; + uint32_t op1 = (instr & 0x300000)>>20; + uint32_t op2 = (instr & 0x30)>>4; + if(((op1 & 0x3)==0x0) && ((op2 & 0x3)==0x0)) return qadd(req, res); + if(((op1 & 0x3)==0x0) && ((op2 & 0x3)==0x1)) return qdadd(req, res); + if(((op1 & 0x3)==0x0) && ((op2 & 0x3)==0x2)) return qsub(req, res); + if(((op1 & 0x3)==0x0) && ((op2 & 0x3)==0x3)) return qdsub(req, res); + if(((op1 & 0x3)==0x1) && ((op2 & 0x3)==0x0)) return rev(req, res); + if(((op1 & 0x3)==0x1) && ((op2 & 0x3)==0x1)) return rev16(req, res); + if(((op1 & 0x3)==0x1) && ((op2 & 0x3)==0x2)) return rbit(req, res); + if(((op1 & 0x3)==0x1) && ((op2 & 0x3)==0x3)) return revsh(req, res); + if(((op1 & 0x3)==0x2) && ((op2 & 0x3)==0x0)) return sel(req, res); + if(((op1 & 0x3)==0x3) && ((op2 & 0x3)==0x0)) return clz(req, res); + return undefined(req, res); +} + +// gen_crc: A585F9B8 +int mla(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + /* Encoding T1 */ + /* pattern="11111,0110,000,Rn.4,Ra.4,Rd.4,0000,Rm.4" width=32 stringency=16 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFFF000F0)==0xFB000000)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ARMv6T2) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_Rn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Rn >> 6] |= 1LL << (FIELD_Rn & 63); + char Rn_width = 4; + res->fields[FIELD_Ra] = (instr & 0xF000)>>12; + res->fields_mask[FIELD_Ra >> 6] |= 1LL << (FIELD_Ra & 63); + char Ra_width = 4; + res->fields[FIELD_Rd] = (instr & 0xF00)>>8; + res->fields_mask[FIELD_Rd >> 6] |= 1LL << (FIELD_Rd & 63); + char Rd_width = 4; + res->fields[FIELD_Rm] = instr & 0xF; + res->fields_mask[FIELD_Rm >> 6] |= 1LL << (FIELD_Rm & 63); + char Rm_width = 4; + + static const instruction_format instr_formats[] = + { + { /* MLA<c> <Rd>,<Rn>,<Rm>,<Ra> */ + "mla", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rd,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rn,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rm,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Ra,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 4 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_MLA; + + /* pcode: if Ra == '1111' then SEE MUL */ + if((res->fields[FIELD_Ra]) == (0xF)) { + + return mul(req, res); + } + /* pcode: d = UInt(Rd) */ + res->fields[FIELD_d] = (res->fields[FIELD_Rd]); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: n = UInt(Rn) */ + res->fields[FIELD_n] = (res->fields[FIELD_Rn]); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: m = UInt(Rm) */ + res->fields[FIELD_m] = (res->fields[FIELD_Rm]); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + /* pcode: a= UInt(Ra) */ + res->fields[FIELD_a] = (res->fields[FIELD_Ra]); + res->fields_mask[FIELD_a >> 6] |= 1LL << (FIELD_a & 63); + /* pcode: setflags = FALSE */ + res->fields[FIELD_setflags] = 0; + res->fields_mask[FIELD_setflags >> 6] |= 1LL << (FIELD_setflags & 63); + /* pcode: if BadReg(d) || BadReg(n) || BadReg(m) || a == 13 then UNPREDICTABLE */ + if((((BadReg(res->fields[FIELD_d])) || (BadReg(res->fields[FIELD_n]))) || (BadReg(res->fields[FIELD_m]))) || ((res->fields[FIELD_a]) == (13))) { + res->flags |= FLAG_UNPREDICTABLE; + } + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: 828C8FC8 +int mls(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + /* Encoding T1 */ + /* pattern="11111,0110,000,Rn.4,Ra.4,Rd.4,0001,Rm.4" width=32 stringency=16 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFFF000F0)==0xFB000010)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ARMv6T2) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_Rn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Rn >> 6] |= 1LL << (FIELD_Rn & 63); + char Rn_width = 4; + res->fields[FIELD_Ra] = (instr & 0xF000)>>12; + res->fields_mask[FIELD_Ra >> 6] |= 1LL << (FIELD_Ra & 63); + char Ra_width = 4; + res->fields[FIELD_Rd] = (instr & 0xF00)>>8; + res->fields_mask[FIELD_Rd >> 6] |= 1LL << (FIELD_Rd & 63); + char Rd_width = 4; + res->fields[FIELD_Rm] = instr & 0xF; + res->fields_mask[FIELD_Rm >> 6] |= 1LL << (FIELD_Rm & 63); + char Rm_width = 4; + + static const instruction_format instr_formats[] = + { + { /* MLS<c> <Rd>,<Rn>,<Rm>,<Ra> */ + "mls", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rd,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rn,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rm,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Ra,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 4 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_MLS; + + /* pcode: d = UInt(Rd) */ + res->fields[FIELD_d] = (res->fields[FIELD_Rd]); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: n = UInt(Rn) */ + res->fields[FIELD_n] = (res->fields[FIELD_Rn]); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: m = UInt(Rm) */ + res->fields[FIELD_m] = (res->fields[FIELD_Rm]); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + /* pcode: a = UInt(Ra) */ + res->fields[FIELD_a] = (res->fields[FIELD_Ra]); + res->fields_mask[FIELD_a >> 6] |= 1LL << (FIELD_a & 63); + /* pcode: if BadReg(d) || BadReg(n) || BadReg(m) || BadReg(a) then UNPREDICTABLE */ + if((((BadReg(res->fields[FIELD_d])) || (BadReg(res->fields[FIELD_n]))) || (BadReg(res->fields[FIELD_m]))) || (BadReg(res->fields[FIELD_a]))) { + res->flags |= FLAG_UNPREDICTABLE; + } + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: 8BCFFC12 +int mov_immediate(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + /* Encoding T1 */ + /* pattern="001,00,Rd.3,imm8.8" width=16 stringency=5 */ + { + uint16_t instr = req->instr_word16; + if(((instr & 0xF800)==0x2000)) { + res->instrSize = 16; + if(!(req->arch & ARCH_ARMv4T) && !(req->arch & ARCH_ARMv5T) && !(req->arch & ARCH_ARMv6) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_Rd] = (instr & 0x700)>>8; + res->fields_mask[FIELD_Rd >> 6] |= 1LL << (FIELD_Rd & 63); + char Rd_width = 3; + res->fields[FIELD_imm8] = instr & 0xFF; + res->fields_mask[FIELD_imm8 >> 6] |= 1LL << (FIELD_imm8 & 63); + char imm8_width = 8; + + static const instruction_format instr_formats[] = + { + { /* MOVS <Rd>,#<imm8> */ + "movs", /* .operation (const char *) */ + 0, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rd,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_IMM,FIELD_imm8,FIELD_UNINIT,"#","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + { /* MOV<c> <Rd>,#<imm8> */ + "mov", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rd,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_IMM,FIELD_imm8,FIELD_UNINIT,"#","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 2; + res->mnem = armv7::ARMV7_MOVS; + + /* pcode: d = UInt(Rd) */ + res->fields[FIELD_d] = (res->fields[FIELD_Rd]); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: setflags = !InITBlock() */ + res->fields[FIELD_setflags] = !(req->inIfThen == IFTHEN_YES); + res->fields_mask[FIELD_setflags >> 6] |= 1LL << (FIELD_setflags & 63); + /* pcode: imm32 = ZeroExtend(imm8, 32) */ + res->fields[FIELD_imm32] = res->fields[FIELD_imm8]; + res->fields_mask[FIELD_imm32 >> 6] |= 1LL << (FIELD_imm32 & 63); + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* Encoding T2 */ + /* pattern="11110,i.1,0,0010,S.1,1111,0,imm3.3,Rd.4,imm8.8" width=32 stringency=17 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFBEF8000)==0xF04F0000)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ARMv6T2) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_i] = (instr & 0x4000000)>>26; + res->fields_mask[FIELD_i >> 6] |= 1LL << (FIELD_i & 63); + char i_width = 1; + res->fields[FIELD_S] = (instr & 0x100000)>>20; + res->fields_mask[FIELD_S >> 6] |= 1LL << (FIELD_S & 63); + char S_width = 1; + res->fields[FIELD_imm3] = (instr & 0x7000)>>12; + res->fields_mask[FIELD_imm3 >> 6] |= 1LL << (FIELD_imm3 & 63); + char imm3_width = 3; + res->fields[FIELD_Rd] = (instr & 0xF00)>>8; + res->fields_mask[FIELD_Rd >> 6] |= 1LL << (FIELD_Rd & 63); + char Rd_width = 4; + res->fields[FIELD_imm8] = instr & 0xFF; + res->fields_mask[FIELD_imm8 >> 6] |= 1LL << (FIELD_imm8 & 63); + char imm8_width = 8; + + static const instruction_format instr_formats[] = + { + { /* MOV{S}<c> <Rd>,#<imm32> */ + "mov", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_OPTIONAL_STATUS, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rd,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_IMM,FIELD_imm32,FIELD_UNINIT,"#","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_MOV; + + /* pcode: d = UInt(Rd) */ + res->fields[FIELD_d] = (res->fields[FIELD_Rd]); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: setflags = (S == '1') */ + res->fields[FIELD_setflags] = ((res->fields[FIELD_S]) == (0x1)); + res->fields_mask[FIELD_setflags >> 6] |= 1LL << (FIELD_setflags & 63); + /* pcode: (imm32, carry) = ThumbExpandImm_C(i:imm3:imm8, APSR.C) */ + res->fields[FIELD_imm32] = ThumbExpandImm_C_imm32((res->fields[FIELD_i]<<(8+3))|(res->fields[FIELD_imm3]<<8)|(res->fields[FIELD_imm8]), res->fields[FIELD_APSR_C]); + res->fields_mask[FIELD_imm32 >> 6] |= 1LL << (FIELD_imm32 & 63); + res->fields[FIELD_carry] = ThumbExpandImm_C_cout((res->fields[FIELD_i]<<(8+3))|(res->fields[FIELD_imm3]<<8)|(res->fields[FIELD_imm8]), res->fields[FIELD_APSR_C]); + res->fields_mask[FIELD_carry >> 6] |= 1LL << (FIELD_carry & 63); + /* TODO: handle ThumbExpandImm_C's possible setting of UNPREDICTABLE */ while(0); + /* pcode: if BadReg(d) then UNPREDICTABLE */ + if(BadReg(res->fields[FIELD_d])) { + res->flags |= FLAG_UNPREDICTABLE; + } + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* Encoding T3 */ + /* pattern="11110,i.1,10,0,1,0,0,imm4.4,0,imm3.3,Rd.4,imm8.8" width=32 stringency=13 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFBF08000)==0xF2400000)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ARMv6T2) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_i] = (instr & 0x4000000)>>26; + res->fields_mask[FIELD_i >> 6] |= 1LL << (FIELD_i & 63); + char i_width = 1; + res->fields[FIELD_imm4] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_imm4 >> 6] |= 1LL << (FIELD_imm4 & 63); + char imm4_width = 4; + res->fields[FIELD_imm3] = (instr & 0x7000)>>12; + res->fields_mask[FIELD_imm3 >> 6] |= 1LL << (FIELD_imm3 & 63); + char imm3_width = 3; + res->fields[FIELD_Rd] = (instr & 0xF00)>>8; + res->fields_mask[FIELD_Rd >> 6] |= 1LL << (FIELD_Rd & 63); + char Rd_width = 4; + res->fields[FIELD_imm8] = instr & 0xFF; + res->fields_mask[FIELD_imm8 >> 6] |= 1LL << (FIELD_imm8 & 63); + char imm8_width = 8; + + static const instruction_format instr_formats[] = + { + { /* MOVW<c> <Rd>,#<imm32> */ + "movw", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rd,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_IMM,FIELD_imm32,FIELD_UNINIT,"#","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_MOVW; + + /* pcode: d = UInt(Rd) */ + res->fields[FIELD_d] = (res->fields[FIELD_Rd]); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: setflags = FALSE */ + res->fields[FIELD_setflags] = 0; + res->fields_mask[FIELD_setflags >> 6] |= 1LL << (FIELD_setflags & 63); + /* pcode: imm32 = ZeroExtend(imm4:i:imm3:imm8, 32) */ + res->fields[FIELD_imm32] = (res->fields[FIELD_imm4]<<(8+3+i_width))|(res->fields[FIELD_i]<<(8+3))|(res->fields[FIELD_imm3]<<8)|(res->fields[FIELD_imm8]); + res->fields_mask[FIELD_imm32 >> 6] |= 1LL << (FIELD_imm32 & 63); + /* pcode: if BadReg(d) then UNPREDICTABLE */ + if(BadReg(res->fields[FIELD_d])) { + res->flags |= FLAG_UNPREDICTABLE; + } + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: 23BAE2F6 +int mov_register(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + /* Encoding T1 */ + /* pattern="010001,10,D.1,Rm.4,Rd.3" width=16 stringency=9 */ + { + uint16_t instr = req->instr_word16; + if(((instr & 0xFF00)==0x4600)) { + res->instrSize = 16; + if(!(req->arch & ARCH_ARMv6) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_D] = (instr & 0x80)>>7; + res->fields_mask[FIELD_D >> 6] |= 1LL << (FIELD_D & 63); + char D_width = 1; + res->fields[FIELD_Rm] = (instr & 0x78)>>3; + res->fields_mask[FIELD_Rm >> 6] |= 1LL << (FIELD_Rm & 63); + char Rm_width = 4; + res->fields[FIELD_Rd] = instr & 0x7; + res->fields_mask[FIELD_Rd >> 6] |= 1LL << (FIELD_Rd & 63); + char Rd_width = 3; + + static const instruction_format instr_formats[] = + { + { /* MOV<c> <Rd>,<Rm> */ + "mov", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rd,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rm,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_MOV; + + /* pcode: d = UInt(D:Rd) */ + res->fields[FIELD_d] = ((res->fields[FIELD_D]<<Rd_width)|(res->fields[FIELD_Rd])); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: m = UInt(Rm) */ + res->fields[FIELD_m] = (res->fields[FIELD_Rm]); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + /* pcode: setflags = FALSE */ + res->fields[FIELD_setflags] = 0; + res->fields_mask[FIELD_setflags >> 6] |= 1LL << (FIELD_setflags & 63); + /* pcode: if d == 15 && InITBlock() && !LastInITBlock() then UNPREDICTABLE */ + if((((res->fields[FIELD_d]) == (15)) && (req->inIfThen == IFTHEN_YES)) && (!(req->inIfThenLast == IFTHENLAST_YES))) { + res->flags |= FLAG_UNPREDICTABLE; + } + /* pcode: Rd = UInt(D:Rd) */ + res->fields[FIELD_Rd] = ((res->fields[FIELD_D]<<Rd_width)|(res->fields[FIELD_Rd])); + res->fields_mask[FIELD_Rd >> 6] |= 1LL << (FIELD_Rd & 63); + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* Encoding T2 */ + /* pattern="000,00,00000,Rm.3,Rd.3" width=16 stringency=10 */ + { + uint16_t instr = req->instr_word16; + if(((instr & 0xFFC0)==0x0)) { + res->instrSize = 16; + if(!(req->arch & ARCH_ARMv4T) && !(req->arch & ARCH_ARMv5T) && !(req->arch & ARCH_ARMv6) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_Rm] = (instr & 0x38)>>3; + res->fields_mask[FIELD_Rm >> 6] |= 1LL << (FIELD_Rm & 63); + char Rm_width = 3; + res->fields[FIELD_Rd] = instr & 0x7; + res->fields_mask[FIELD_Rd >> 6] |= 1LL << (FIELD_Rd & 63); + char Rd_width = 3; + + static const instruction_format instr_formats[] = + { + { /* MOVS <Rd>,<Rm> */ + "movs", /* .operation (const char *) */ + 0, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rd,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rm,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_MOVS; + + /* pcode: d = UInt(Rd) */ + res->fields[FIELD_d] = (res->fields[FIELD_Rd]); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: m = UInt(Rm) */ + res->fields[FIELD_m] = (res->fields[FIELD_Rm]); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + /* pcode: setflags = TRUE */ + res->fields[FIELD_setflags] = 1; + res->fields_mask[FIELD_setflags >> 6] |= 1LL << (FIELD_setflags & 63); + /* pcode: if InITBlock() then UNPREDICTABLE */ + if(req->inIfThen == IFTHEN_YES) { + res->flags |= FLAG_UNPREDICTABLE; + } + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* Encoding T3 */ + /* pattern="11101,01,0010,S.1,1111,(0),000,Rd.4,0000,Rm.4" width=32 stringency=24 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFFEF70F0)==0xEA4F0000)) { + res->instrSize = 32; + if(!((instr & 0x8000)==0x0)) { + res->flags |= FLAG_UNPREDICTABLE; + } + if(!(req->arch & ARCH_ARMv6T2) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_S] = (instr & 0x100000)>>20; + res->fields_mask[FIELD_S >> 6] |= 1LL << (FIELD_S & 63); + char S_width = 1; + res->fields[FIELD_Rd] = (instr & 0xF00)>>8; + res->fields_mask[FIELD_Rd >> 6] |= 1LL << (FIELD_Rd & 63); + char Rd_width = 4; + res->fields[FIELD_Rm] = instr & 0xF; + res->fields_mask[FIELD_Rm >> 6] |= 1LL << (FIELD_Rm & 63); + char Rm_width = 4; + + static const instruction_format instr_formats[] = + { + { /* MOV{S}<c> <Rd>,<Rm> */ + "mov", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_OPTIONAL_STATUS, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rd,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rm,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_MOV; + + /* pcode: d = UInt(Rd) */ + res->fields[FIELD_d] = (res->fields[FIELD_Rd]); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: m = UInt(Rm) */ + res->fields[FIELD_m] = (res->fields[FIELD_Rm]); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + /* pcode: setflags = (S == '1') */ + res->fields[FIELD_setflags] = ((res->fields[FIELD_S]) == (0x1)); + res->fields_mask[FIELD_setflags >> 6] |= 1LL << (FIELD_setflags & 63); + /* pcode: if (d == 13 || BadReg(m)) && setflags then UNPREDICTABLE */ + if(((((res->fields[FIELD_d]) == (13)) || (BadReg(res->fields[FIELD_m])))) && (res->fields[FIELD_setflags])) { + res->flags |= FLAG_UNPREDICTABLE; + } + /* pcode: if (d == 13 && BadReg(m)) || d == 15 then UNPREDICTABLE */ + if(((((res->fields[FIELD_d]) == (13)) && (BadReg(res->fields[FIELD_m])))) || ((res->fields[FIELD_d]) == (15))) { + res->flags |= FLAG_UNPREDICTABLE; + } + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: 3C009A86 +int movt(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + /* Encoding T1 */ + /* pattern="11110,i.1,10,1,1,0,0,imm4.4,0,imm3.3,Rd.4,imm8.8" width=32 stringency=13 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFBF08000)==0xF2C00000)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ARMv6T2) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_i] = (instr & 0x4000000)>>26; + res->fields_mask[FIELD_i >> 6] |= 1LL << (FIELD_i & 63); + char i_width = 1; + res->fields[FIELD_imm4] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_imm4 >> 6] |= 1LL << (FIELD_imm4 & 63); + char imm4_width = 4; + res->fields[FIELD_imm3] = (instr & 0x7000)>>12; + res->fields_mask[FIELD_imm3 >> 6] |= 1LL << (FIELD_imm3 & 63); + char imm3_width = 3; + res->fields[FIELD_Rd] = (instr & 0xF00)>>8; + res->fields_mask[FIELD_Rd >> 6] |= 1LL << (FIELD_Rd & 63); + char Rd_width = 4; + res->fields[FIELD_imm8] = instr & 0xFF; + res->fields_mask[FIELD_imm8 >> 6] |= 1LL << (FIELD_imm8 & 63); + char imm8_width = 8; + + static const instruction_format instr_formats[] = + { + { /* MOVT<c> <Rd>,#<imm16> */ + "movt", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rd,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_IMM,FIELD_imm16,FIELD_UNINIT,"#","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_MOVT; + + /* pcode: d = UInt(Rd) */ + res->fields[FIELD_d] = (res->fields[FIELD_Rd]); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: imm16 = imm4:i:imm3:imm8 */ + res->fields[FIELD_imm16] = (res->fields[FIELD_imm4]<<(8+3+i_width))|(res->fields[FIELD_i]<<(8+3))|(res->fields[FIELD_imm3]<<8)|(res->fields[FIELD_imm8]); + res->fields_mask[FIELD_imm16 >> 6] |= 1LL << (FIELD_imm16 & 63); + /* pcode: if BadReg(d) then UNPREDICTABLE */ + if(BadReg(res->fields[FIELD_d])) { + res->flags |= FLAG_UNPREDICTABLE; + } + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: B85821E1 +int mrc_mrc2(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + /* Encoding T1 */ + /* pattern="1110,1110,opc1.3,1,CRn.4,Rt_mrc.4,coproc.4,opc2.3,1,CRm.4" width=32 stringency=11 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFF100010)==0xEE100010)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ARMv6T2) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_opc1] = (instr & 0xE00000)>>21; + res->fields_mask[FIELD_opc1 >> 6] |= 1LL << (FIELD_opc1 & 63); + char opc1_width = 3; + res->fields[FIELD_CRn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_CRn >> 6] |= 1LL << (FIELD_CRn & 63); + char CRn_width = 4; + res->fields[FIELD_Rt_mrc] = (instr & 0xF000)>>12; + res->fields_mask[FIELD_Rt_mrc >> 6] |= 1LL << (FIELD_Rt_mrc & 63); + char Rt_mrc_width = 4; + res->fields[FIELD_coproc] = (instr & 0xF00)>>8; + res->fields_mask[FIELD_coproc >> 6] |= 1LL << (FIELD_coproc & 63); + char coproc_width = 4; + res->fields[FIELD_opc2] = (instr & 0xE0)>>5; + res->fields_mask[FIELD_opc2 >> 6] |= 1LL << (FIELD_opc2 & 63); + char opc2_width = 3; + res->fields[FIELD_CRm] = instr & 0xF; + res->fields_mask[FIELD_CRm >> 6] |= 1LL << (FIELD_CRm & 63); + char CRm_width = 4; + + static const instruction_format instr_formats[] = + { + { /* MRC<c> <coproc>,#<opc1>,<Rt_mrc>,<CRn>,<CRm>,#<opc2> */ + "mrc", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_COPROC,FIELD_coproc,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_IMM,FIELD_opc1,FIELD_UNINIT,"#","",WRITEBACK_NO}, + {OPERAND_FORMAT_RT_MRC,FIELD_Rt_mrc,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_COPROC_REG,FIELD_CRn,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_COPROC_REG,FIELD_CRm,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_IMM,FIELD_opc2,FIELD_UNINIT,"#","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 6 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_MRC; + + /* pcode: if (coproc == '1010') || (coproc == '1011') then SEE "nop" */ + if((((res->fields[FIELD_coproc]) == (0xA))) || (((res->fields[FIELD_coproc]) == (0xB)))) { + + return nop(req, res); + } + /* pcode: t = UInt(Rt_mrc) */ + res->fields[FIELD_t] = (res->fields[FIELD_Rt_mrc]); + res->fields_mask[FIELD_t >> 6] |= 1LL << (FIELD_t & 63); + /* pcode: cp = UInt(coproc) */ + res->fields[FIELD_cp] = (res->fields[FIELD_coproc]); + res->fields_mask[FIELD_cp >> 6] |= 1LL << (FIELD_cp & 63); + /* pcode: if t == 13 && (CurrentInstrSet() != InstrSet_ARM) then UNPREDICTABLE */ + if(((res->fields[FIELD_t]) == (13)) && (((req->instrSet) != (res->fields[FIELD_InstrSet_ARM])))) { + res->flags |= FLAG_UNPREDICTABLE; + } + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* Encoding T2 */ + /* pattern="1111,1110,opc1.3,1,CRn.4,Rt_mrc.4,coproc.4,opc2.3,1,CRm.4" width=32 stringency=11 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFF100010)==0xFE100010)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ARMv6T2) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_opc1] = (instr & 0xE00000)>>21; + res->fields_mask[FIELD_opc1 >> 6] |= 1LL << (FIELD_opc1 & 63); + char opc1_width = 3; + res->fields[FIELD_CRn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_CRn >> 6] |= 1LL << (FIELD_CRn & 63); + char CRn_width = 4; + res->fields[FIELD_Rt_mrc] = (instr & 0xF000)>>12; + res->fields_mask[FIELD_Rt_mrc >> 6] |= 1LL << (FIELD_Rt_mrc & 63); + char Rt_mrc_width = 4; + res->fields[FIELD_coproc] = (instr & 0xF00)>>8; + res->fields_mask[FIELD_coproc >> 6] |= 1LL << (FIELD_coproc & 63); + char coproc_width = 4; + res->fields[FIELD_opc2] = (instr & 0xE0)>>5; + res->fields_mask[FIELD_opc2 >> 6] |= 1LL << (FIELD_opc2 & 63); + char opc2_width = 3; + res->fields[FIELD_CRm] = instr & 0xF; + res->fields_mask[FIELD_CRm >> 6] |= 1LL << (FIELD_CRm & 63); + char CRm_width = 4; + + static const instruction_format instr_formats[] = + { + { /* MRC2<c> <coproc>,#<opc1>,<Rt_mrc>,<CRn>,<CRm>,#<opc2> */ + "mrc2", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_COPROC,FIELD_coproc,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_IMM,FIELD_opc1,FIELD_UNINIT,"#","",WRITEBACK_NO}, + {OPERAND_FORMAT_RT_MRC,FIELD_Rt_mrc,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_COPROC_REG,FIELD_CRn,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_COPROC_REG,FIELD_CRm,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_IMM,FIELD_opc2,FIELD_UNINIT,"#","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 6 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_MRC2; + + /* pcode: t = UInt(Rt_mrc) */ + res->fields[FIELD_t] = (res->fields[FIELD_Rt_mrc]); + res->fields_mask[FIELD_t >> 6] |= 1LL << (FIELD_t & 63); + /* pcode: cp = UInt(coproc) */ + res->fields[FIELD_cp] = (res->fields[FIELD_coproc]); + res->fields_mask[FIELD_cp >> 6] |= 1LL << (FIELD_cp & 63); + /* pcode: if t == 13 && (CurrentInstrSet() != InstrSet_ARM) then UNPREDICTABLE */ + if(((res->fields[FIELD_t]) == (13)) && (((req->instrSet) != (res->fields[FIELD_InstrSet_ARM])))) { + res->flags |= FLAG_UNPREDICTABLE; + } + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: 98847182 +int mrrc_mrrc2(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + /* Encoding T1 */ + /* pattern="1110,110,0,0,1,0,1,Rt2.4,Rt.4,coproc.4,opc1.4,CRm.4" width=32 stringency=13 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFFF00000)==0xEC500000)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ARMv6T2) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_Rt2] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Rt2 >> 6] |= 1LL << (FIELD_Rt2 & 63); + char Rt2_width = 4; + res->fields[FIELD_Rt] = (instr & 0xF000)>>12; + res->fields_mask[FIELD_Rt >> 6] |= 1LL << (FIELD_Rt & 63); + char Rt_width = 4; + res->fields[FIELD_coproc] = (instr & 0xF00)>>8; + res->fields_mask[FIELD_coproc >> 6] |= 1LL << (FIELD_coproc & 63); + char coproc_width = 4; + res->fields[FIELD_opc1] = (instr & 0xF0)>>4; + res->fields_mask[FIELD_opc1 >> 6] |= 1LL << (FIELD_opc1 & 63); + char opc1_width = 4; + res->fields[FIELD_CRm] = instr & 0xF; + res->fields_mask[FIELD_CRm >> 6] |= 1LL << (FIELD_CRm & 63); + char CRm_width = 4; + + static const instruction_format instr_formats[] = + { + { /* MRRC<c> <coproc>,#<opc1>,<Rt>,<Rt2>,<CRm> */ + "mrrc", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_COPROC,FIELD_coproc,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_IMM,FIELD_opc1,FIELD_UNINIT,"#","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rt,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rt2,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_COPROC_REG,FIELD_CRm,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 5 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_MRRC; + + /* pcode: if coproc == '1010' || coproc == '1011' then SEE "nop" */ + if(((res->fields[FIELD_coproc]) == (0xA)) || ((res->fields[FIELD_coproc]) == (0xB))) { + + return nop(req, res); + } + /* pcode: t = UInt(Rt) */ + res->fields[FIELD_t] = (res->fields[FIELD_Rt]); + res->fields_mask[FIELD_t >> 6] |= 1LL << (FIELD_t & 63); + /* pcode: t2 = UInt(Rt2) */ + res->fields[FIELD_t2] = (res->fields[FIELD_Rt2]); + res->fields_mask[FIELD_t2 >> 6] |= 1LL << (FIELD_t2 & 63); + /* pcode: cp = UInt(coproc) */ + res->fields[FIELD_cp] = (res->fields[FIELD_coproc]); + res->fields_mask[FIELD_cp >> 6] |= 1LL << (FIELD_cp & 63); + /* pcode: if t == 15 || t2 == 15 || t == t2 then UNPREDICTABLE */ + if((((res->fields[FIELD_t]) == (15)) || ((res->fields[FIELD_t2]) == (15))) || ((res->fields[FIELD_t]) == (res->fields[FIELD_t2]))) { + res->flags |= FLAG_UNPREDICTABLE; + } + /* pcode: if (t == 13 || t2 == 13) && (CurrentInstrSet() != InstrSet_ARM) then UNPREDICTABLE */ + if(((((res->fields[FIELD_t]) == (13)) || ((res->fields[FIELD_t2]) == (13)))) && (((req->instrSet) != (res->fields[FIELD_InstrSet_ARM])))) { + res->flags |= FLAG_UNPREDICTABLE; + } + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* Encoding T2 */ + /* pattern="1111,110,0,0,1,0,1,Rt2.4,Rt.4,coproc.4,opc1.4,CRm.4" width=32 stringency=13 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFFF00000)==0xFC500000)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ARMv6T2) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_Rt2] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Rt2 >> 6] |= 1LL << (FIELD_Rt2 & 63); + char Rt2_width = 4; + res->fields[FIELD_Rt] = (instr & 0xF000)>>12; + res->fields_mask[FIELD_Rt >> 6] |= 1LL << (FIELD_Rt & 63); + char Rt_width = 4; + res->fields[FIELD_coproc] = (instr & 0xF00)>>8; + res->fields_mask[FIELD_coproc >> 6] |= 1LL << (FIELD_coproc & 63); + char coproc_width = 4; + res->fields[FIELD_opc1] = (instr & 0xF0)>>4; + res->fields_mask[FIELD_opc1 >> 6] |= 1LL << (FIELD_opc1 & 63); + char opc1_width = 4; + res->fields[FIELD_CRm] = instr & 0xF; + res->fields_mask[FIELD_CRm >> 6] |= 1LL << (FIELD_CRm & 63); + char CRm_width = 4; + + static const instruction_format instr_formats[] = + { + { /* MRRC2<c> <coproc>,#<opc1>,<Rt>,<Rt2>,<CRm> */ + "mrrc2", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_COPROC,FIELD_coproc,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_IMM,FIELD_opc1,FIELD_UNINIT,"#","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rt,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rt2,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_COPROC_REG,FIELD_CRm,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 5 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_MRRC2; + + /* pcode: t = UInt(Rt) */ + res->fields[FIELD_t] = (res->fields[FIELD_Rt]); + res->fields_mask[FIELD_t >> 6] |= 1LL << (FIELD_t & 63); + /* pcode: t2 = UInt(Rt2) */ + res->fields[FIELD_t2] = (res->fields[FIELD_Rt2]); + res->fields_mask[FIELD_t2 >> 6] |= 1LL << (FIELD_t2 & 63); + /* pcode: cp = UInt(coproc) */ + res->fields[FIELD_cp] = (res->fields[FIELD_coproc]); + res->fields_mask[FIELD_cp >> 6] |= 1LL << (FIELD_cp & 63); + /* pcode: if t == 15 || t2 == 15 || t == t2 then UNPREDICTABLE */ + if((((res->fields[FIELD_t]) == (15)) || ((res->fields[FIELD_t2]) == (15))) || ((res->fields[FIELD_t]) == (res->fields[FIELD_t2]))) { + res->flags |= FLAG_UNPREDICTABLE; + } + /* pcode: if (t == 13 || t2 == 13) && (CurrentInstrSet() != InstrSet_ARM) then UNPREDICTABLE */ + if(((((res->fields[FIELD_t]) == (13)) || ((res->fields[FIELD_t2]) == (13)))) && (((req->instrSet) != (res->fields[FIELD_InstrSet_ARM])))) { + res->flags |= FLAG_UNPREDICTABLE; + } + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: A720271F +int mrs(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + /* Encoding T1 */ + /* pattern="11110,0,1111,1,R.1,(1)(1)(1)(1),10,(0),0,Rd.4,SYSm.8" width=32 stringency=20 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFFE0D000)==0xF3E08000)) { + res->instrSize = 32; + if(!((instr & 0xF2000)==0xF0000)) { + res->flags |= FLAG_UNPREDICTABLE; + } + if(!(req->arch & ARCH_ARMv6T2) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_R] = (instr & 0x100000)>>20; + res->fields_mask[FIELD_R >> 6] |= 1LL << (FIELD_R & 63); + char R_width = 1; + res->fields[FIELD_Rd] = (instr & 0xF00)>>8; + res->fields_mask[FIELD_Rd >> 6] |= 1LL << (FIELD_Rd & 63); + char Rd_width = 4; + res->fields[FIELD_SYSm] = instr & 0xFF; + res->fields_mask[FIELD_SYSm >> 6] |= 1LL << (FIELD_SYSm & 63); + char SYSm_width = 8; + + static const instruction_format instr_formats[] = + { + { /* MRS<c> <Rd>,<spec_reg> */ + "mrs", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rd,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_SPEC_REG,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_MRS; + + /* pcode: d = UInt(Rd) */ + res->fields[FIELD_d] = (res->fields[FIELD_Rd]); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: read_spsr = (R == '1') */ + res->fields[FIELD_read_spsr] = ((res->fields[FIELD_R]) == (0x1)); + res->fields_mask[FIELD_read_spsr >> 6] |= 1LL << (FIELD_read_spsr & 63); + /* pcode: if BadReg(d) then UNPREDICTABLE */ + if(BadReg(res->fields[FIELD_d])) { + res->flags |= FLAG_UNPREDICTABLE; + } + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: 7885C1A4 +int msr_reg_app(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + /* Encoding T1 */ + /* pattern="11110,0,1110,0,0,Rn.4,10,(0),0,mask.2,00,SYSm.8" width=32 stringency=18 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFFF0D300)==0xF3808000)) { + res->instrSize = 32; + if(!((instr & 0x2000)==0x0)) { + res->flags |= FLAG_UNPREDICTABLE; + } + if(!(req->arch & ARCH_ARMv6T2) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_Rn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Rn >> 6] |= 1LL << (FIELD_Rn & 63); + char Rn_width = 4; + res->fields[FIELD_mask] = (instr & 0xC00)>>10; + res->fields_mask[FIELD_mask >> 6] |= 1LL << (FIELD_mask & 63); + char mask_width = 2; + res->fields[FIELD_SYSm] = instr & 0xFF; + res->fields_mask[FIELD_SYSm >> 6] |= 1LL << (FIELD_SYSm & 63); + char SYSm_width = 8; + + static const instruction_format instr_formats[] = + { + { /* MSR<c> <spec_reg>,<Rn> */ + "msr", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_SPEC_REG,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rn,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_MSR; + + /* pcode: n = UInt(Rn) */ + res->fields[FIELD_n] = (res->fields[FIELD_Rn]); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: write_nzcvq = (mask<1> == '1') */ + res->fields[FIELD_write_nzcvq] = ((((res->fields[FIELD_mask] >> 1) & 1)) == (0x1)); + res->fields_mask[FIELD_write_nzcvq >> 6] |= 1LL << (FIELD_write_nzcvq & 63); + /* pcode: write_g = (mask<0> == '1') */ + res->fields[FIELD_write_g] = (((res->fields[FIELD_mask] & 1)) == (0x1)); + res->fields_mask[FIELD_write_g >> 6] |= 1LL << (FIELD_write_g & 63); + /* pcode: if mask==0 then UNPREDICTABLE */ + if((res->fields[FIELD_mask]) == (0)) { + res->flags |= FLAG_UNPREDICTABLE; + } + /* pcode: if n == 15 then UNPREDICTABLE */ + if((res->fields[FIELD_n]) == (15)) { + res->flags |= FLAG_UNPREDICTABLE; + } + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: 90DA8A57 +int msr_reg_sys(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + /* Encoding T1 */ + /* pattern="11110,0,1110,0,R.1,Rn.4,10,(0),0,mask.4,SYSm.8" width=32 stringency=16 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFFE0D000)==0xF3808000)) { + res->instrSize = 32; + if(!((instr & 0x2000)==0x0)) { + res->flags |= FLAG_UNPREDICTABLE; + } + if(!(req->arch & ARCH_ARMv6T2) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_R] = (instr & 0x100000)>>20; + res->fields_mask[FIELD_R >> 6] |= 1LL << (FIELD_R & 63); + char R_width = 1; + res->fields[FIELD_Rn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Rn >> 6] |= 1LL << (FIELD_Rn & 63); + char Rn_width = 4; + res->fields[FIELD_mask] = (instr & 0xF00)>>8; + res->fields_mask[FIELD_mask >> 6] |= 1LL << (FIELD_mask & 63); + char mask_width = 4; + res->fields[FIELD_SYSm] = instr & 0xFF; + res->fields_mask[FIELD_SYSm >> 6] |= 1LL << (FIELD_SYSm & 63); + char SYSm_width = 8; + + static const instruction_format instr_formats[] = + { + { /* MSR<c> <spec_reg>,<Rn> */ + "msr", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_SPEC_REG,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rn,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_MSR; + + /* pcode: n = UInt(Rn) */ + res->fields[FIELD_n] = (res->fields[FIELD_Rn]); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: write_spsr = (R == '1') */ + res->fields[FIELD_write_spsr] = ((res->fields[FIELD_R]) == (0x1)); + res->fields_mask[FIELD_write_spsr >> 6] |= 1LL << (FIELD_write_spsr & 63); + /* pcode: if mask == '0000' then UNPREDICTABLE */ + if((res->fields[FIELD_mask]) == (0x0)) { + res->flags |= FLAG_UNPREDICTABLE; + } + /* pcode: if BadReg(n) then UNPREDICTABLE */ + if(BadReg(res->fields[FIELD_n])) { + res->flags |= FLAG_UNPREDICTABLE; + } + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: 0FD149DC +int mul(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + /* Encoding T1 */ + /* pattern="010000,1101,Rn.3,Rdm.3" width=16 stringency=10 */ + { + uint16_t instr = req->instr_word16; + if(((instr & 0xFFC0)==0x4340)) { + res->instrSize = 16; + if(!(req->arch & ARCH_ARMv4T) && !(req->arch & ARCH_ARMv5T) && !(req->arch & ARCH_ARMv6) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_Rn] = (instr & 0x38)>>3; + res->fields_mask[FIELD_Rn >> 6] |= 1LL << (FIELD_Rn & 63); + char Rn_width = 3; + res->fields[FIELD_Rdm] = instr & 0x7; + res->fields_mask[FIELD_Rdm >> 6] |= 1LL << (FIELD_Rdm & 63); + char Rdm_width = 3; + + static const instruction_format instr_formats[] = + { + { /* MULS <Rdm>,<Rn>,<Rdm> */ + "muls", /* .operation (const char *) */ + 0, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rdm,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rn,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rdm,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_MULS; + + /* pcode: d = UInt(Rdm) */ + res->fields[FIELD_d] = (res->fields[FIELD_Rdm]); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: n = UInt(Rn) */ + res->fields[FIELD_n] = (res->fields[FIELD_Rn]); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: m = UInt(Rdm) */ + res->fields[FIELD_m] = (res->fields[FIELD_Rdm]); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + /* pcode: setflags = !InITBlock() */ + res->fields[FIELD_setflags] = !(req->inIfThen == IFTHEN_YES); + res->fields_mask[FIELD_setflags >> 6] |= 1LL << (FIELD_setflags & 63); + /* pcode: if ArchVersion() < 6 && d == n then UNPREDICTABLE */ + if(((req->arch) < (6)) && ((res->fields[FIELD_d]) == (res->fields[FIELD_n]))) { + res->flags |= FLAG_UNPREDICTABLE; + } + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* Encoding T2 */ + /* pattern="11111,0110,000,Rn.4,1111,Rd.4,0000,Rm.4" width=32 stringency=20 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFFF0F0F0)==0xFB00F000)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ARMv6T2) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_Rn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Rn >> 6] |= 1LL << (FIELD_Rn & 63); + char Rn_width = 4; + res->fields[FIELD_Rd] = (instr & 0xF00)>>8; + res->fields_mask[FIELD_Rd >> 6] |= 1LL << (FIELD_Rd & 63); + char Rd_width = 4; + res->fields[FIELD_Rm] = instr & 0xF; + res->fields_mask[FIELD_Rm >> 6] |= 1LL << (FIELD_Rm & 63); + char Rm_width = 4; + + static const instruction_format instr_formats[] = + { + { /* MUL<c> <Rd>,<Rn>,<Rm> */ + "mul", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rd,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rn,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rm,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_MUL; + + /* pcode: d = UInt(Rd) */ + res->fields[FIELD_d] = (res->fields[FIELD_Rd]); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: n = UInt(Rn) */ + res->fields[FIELD_n] = (res->fields[FIELD_Rn]); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: m = UInt(Rm) */ + res->fields[FIELD_m] = (res->fields[FIELD_Rm]); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + /* pcode: setflags = FALSE */ + res->fields[FIELD_setflags] = 0; + res->fields_mask[FIELD_setflags >> 6] |= 1LL << (FIELD_setflags & 63); + /* pcode: if BadReg(d) || BadReg(n) || BadReg(m) then UNPREDICTABLE */ + if(((BadReg(res->fields[FIELD_d])) || (BadReg(res->fields[FIELD_n]))) || (BadReg(res->fields[FIELD_m]))) { + res->flags |= FLAG_UNPREDICTABLE; + } + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: FF0AA264 +int mul_accumulate_absolute_difference(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + uint32_t instr = req->instr_word32; + uint32_t op1 = (instr & 0x700000)>>20; + uint32_t Ra = (instr & 0xF000)>>12; + uint32_t op2 = (instr & 0x30)>>4; + if(((op1 & 0x7)==0x0) && ((op2 & 0x3)==0x0) && !((Ra & 0xF)==0xF)) return mla(req, res); + if(((op1 & 0x7)==0x0) && ((op2 & 0x3)==0x0) && ((Ra & 0xF)==0xF)) return mul(req, res); + if(((op1 & 0x7)==0x7) && ((op2 & 0x3)==0x0) && ((Ra & 0xF)==0xF)) return usad8(req, res); + if(((op1 & 0x7)==0x7) && ((op2 & 0x3)==0x0) && !((Ra & 0xF)==0xF)) return usada8(req, res); + if(((op1 & 0x7)==0x2) && ((op2 & 0x2)==0x0) && !((Ra & 0xF)==0xF)) return smlad(req, res); + if(((op1 & 0x7)==0x2) && ((op2 & 0x2)==0x0) && ((Ra & 0xF)==0xF)) return smuad(req, res); + if(((op1 & 0x7)==0x3) && ((op2 & 0x2)==0x0) && !((Ra & 0xF)==0xF)) return smlawb_smlawt(req, res); + if(((op1 & 0x7)==0x3) && ((op2 & 0x2)==0x0) && ((Ra & 0xF)==0xF)) return smulwb_smulwt(req, res); + if(((op1 & 0x7)==0x4) && ((op2 & 0x2)==0x0) && !((Ra & 0xF)==0xF)) return smlsd(req, res); + if(((op1 & 0x7)==0x4) && ((op2 & 0x2)==0x0) && ((Ra & 0xF)==0xF)) return smusd(req, res); + if(((op1 & 0x7)==0x5) && ((op2 & 0x2)==0x0) && !((Ra & 0xF)==0xF)) return smmla(req, res); + if(((op1 & 0x7)==0x5) && ((op2 & 0x2)==0x0) && ((Ra & 0xF)==0xF)) return smmul(req, res); + if(((op1 & 0x7)==0x1) && !((Ra & 0xF)==0xF) && 1) return smlabb_smlabt_smlatb_smlatt(req, res); + if(((op1 & 0x7)==0x1) && ((Ra & 0xF)==0xF) && 1) return smulbb_smulbt_smultb_smultt(req, res); + if(((op1 & 0x7)==0x0) && ((op2 & 0x3)==0x1) && 1) return mls(req, res); + if(((op1 & 0x7)==0x6) && ((op2 & 0x2)==0x0) && 1) return smmls(req, res); + return undefined(req, res); +} + +// gen_crc: 978EADD6 +int mul_register(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + /* Encoding T1 */ + /* pattern="010000,1101,Rn.3,Rdm.3" width=16 stringency=10 */ + { + uint16_t instr = req->instr_word16; + if(((instr & 0xFFC0)==0x4340)) { + res->instrSize = 16; + if(!(req->arch & ARCH_ARMv4T) && !(req->arch & ARCH_ARMv5T) && !(req->arch & ARCH_ARMv6) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_Rn] = (instr & 0x38)>>3; + res->fields_mask[FIELD_Rn >> 6] |= 1LL << (FIELD_Rn & 63); + char Rn_width = 3; + res->fields[FIELD_Rdm] = instr & 0x7; + res->fields_mask[FIELD_Rdm >> 6] |= 1LL << (FIELD_Rdm & 63); + char Rdm_width = 3; + + static const instruction_format instr_formats[] = + { + { /* MULS <Rdm>,<Rn>,<Rdm> */ + "muls", /* .operation (const char *) */ + 0, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rdm,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rn,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rdm,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + { /* MUL<c> <Rdm>,<Rn>,<Rdm> */ + "mul", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rdm,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rn,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rdm,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 2; + res->mnem = armv7::ARMV7_MULS; + + /* pcode: d = UInt(Rdm) */ + res->fields[FIELD_d] = (res->fields[FIELD_Rdm]); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: n = UInt(Rn) */ + res->fields[FIELD_n] = (res->fields[FIELD_Rn]); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: m = UInt(Rdm) */ + res->fields[FIELD_m] = (res->fields[FIELD_Rdm]); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + /* pcode: setflags = !InITBlock() */ + res->fields[FIELD_setflags] = !(req->inIfThen == IFTHEN_YES); + res->fields_mask[FIELD_setflags >> 6] |= 1LL << (FIELD_setflags & 63); + /* pcode: if ArchVersion() < 6 && d == n then UNPREDICTABLE */ + if(((req->arch) < (6)) && ((res->fields[FIELD_d]) == (res->fields[FIELD_n]))) { + res->flags |= FLAG_UNPREDICTABLE; + } + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* Encoding T2 */ + /* pattern="11111,0110,000,Rn.4,1111,Rd.4,0000,Rm.4" width=32 stringency=20 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFFF0F0F0)==0xFB00F000)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ARMv6T2) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_Rn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Rn >> 6] |= 1LL << (FIELD_Rn & 63); + char Rn_width = 4; + res->fields[FIELD_Rd] = (instr & 0xF00)>>8; + res->fields_mask[FIELD_Rd >> 6] |= 1LL << (FIELD_Rd & 63); + char Rd_width = 4; + res->fields[FIELD_Rm] = instr & 0xF; + res->fields_mask[FIELD_Rm >> 6] |= 1LL << (FIELD_Rm & 63); + char Rm_width = 4; + + static const instruction_format instr_formats[] = + { + { /* MUL<c> <Rd>,<Rn>,<Rm> */ + "mul", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rd,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rn,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rm,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_MUL; + + /* pcode: d = UInt(Rd) */ + res->fields[FIELD_d] = (res->fields[FIELD_Rd]); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: n = UInt(Rn) */ + res->fields[FIELD_n] = (res->fields[FIELD_Rn]); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: m = UInt(Rm) */ + res->fields[FIELD_m] = (res->fields[FIELD_Rm]); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + /* pcode: setflags = FALSE */ + res->fields[FIELD_setflags] = 0; + res->fields_mask[FIELD_setflags >> 6] |= 1LL << (FIELD_setflags & 63); + /* pcode: if BadReg(d) || BadReg(n) || BadReg(m) then UNPREDICTABLE */ + if(((BadReg(res->fields[FIELD_d])) || (BadReg(res->fields[FIELD_n]))) || (BadReg(res->fields[FIELD_m]))) { + res->flags |= FLAG_UNPREDICTABLE; + } + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: 99D02C58 +int mvn_immediate(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + /* Encoding T1 */ + /* pattern="11110,i.1,0,0011,S.1,1111,0,imm3.3,Rd.4,imm8.8" width=32 stringency=17 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFBEF8000)==0xF06F0000)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ARMv6T2) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_i] = (instr & 0x4000000)>>26; + res->fields_mask[FIELD_i >> 6] |= 1LL << (FIELD_i & 63); + char i_width = 1; + res->fields[FIELD_S] = (instr & 0x100000)>>20; + res->fields_mask[FIELD_S >> 6] |= 1LL << (FIELD_S & 63); + char S_width = 1; + res->fields[FIELD_imm3] = (instr & 0x7000)>>12; + res->fields_mask[FIELD_imm3 >> 6] |= 1LL << (FIELD_imm3 & 63); + char imm3_width = 3; + res->fields[FIELD_Rd] = (instr & 0xF00)>>8; + res->fields_mask[FIELD_Rd >> 6] |= 1LL << (FIELD_Rd & 63); + char Rd_width = 4; + res->fields[FIELD_imm8] = instr & 0xFF; + res->fields_mask[FIELD_imm8 >> 6] |= 1LL << (FIELD_imm8 & 63); + char imm8_width = 8; + + static const instruction_format instr_formats[] = + { + { /* MVN{S}<c> <Rd>,#<imm32> */ + "mvn", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_OPTIONAL_STATUS, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rd,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_IMM,FIELD_imm32,FIELD_UNINIT,"#","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_MVN; + + /* pcode: d = UInt(Rd) */ + res->fields[FIELD_d] = (res->fields[FIELD_Rd]); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: setflags = (S == '1') */ + res->fields[FIELD_setflags] = ((res->fields[FIELD_S]) == (0x1)); + res->fields_mask[FIELD_setflags >> 6] |= 1LL << (FIELD_setflags & 63); + /* pcode: (imm32, carry) = ThumbExpandImm_C(i:imm3:imm8, APSR.C) */ + res->fields[FIELD_imm32] = ThumbExpandImm_C_imm32((res->fields[FIELD_i]<<(8+3))|(res->fields[FIELD_imm3]<<8)|(res->fields[FIELD_imm8]), res->fields[FIELD_APSR_C]); + res->fields_mask[FIELD_imm32 >> 6] |= 1LL << (FIELD_imm32 & 63); + res->fields[FIELD_carry] = ThumbExpandImm_C_cout((res->fields[FIELD_i]<<(8+3))|(res->fields[FIELD_imm3]<<8)|(res->fields[FIELD_imm8]), res->fields[FIELD_APSR_C]); + res->fields_mask[FIELD_carry >> 6] |= 1LL << (FIELD_carry & 63); + /* TODO: handle ThumbExpandImm_C's possible setting of UNPREDICTABLE */ while(0); + /* pcode: if BadReg(d) then UNPREDICTABLE */ + if(BadReg(res->fields[FIELD_d])) { + res->flags |= FLAG_UNPREDICTABLE; + } + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: EEB75FAA +int mvn_register(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + /* Encoding T1 */ + /* pattern="010000,1111,Rm.3,Rd.3" width=16 stringency=10 */ + { + uint16_t instr = req->instr_word16; + if(((instr & 0xFFC0)==0x43C0)) { + res->instrSize = 16; + if(!(req->arch & ARCH_ARMv4T) && !(req->arch & ARCH_ARMv5T) && !(req->arch & ARCH_ARMv6) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_Rm] = (instr & 0x38)>>3; + res->fields_mask[FIELD_Rm >> 6] |= 1LL << (FIELD_Rm & 63); + char Rm_width = 3; + res->fields[FIELD_Rd] = instr & 0x7; + res->fields_mask[FIELD_Rd >> 6] |= 1LL << (FIELD_Rd & 63); + char Rd_width = 3; + + static const instruction_format instr_formats[] = + { + { /* MVNS <Rd>,<Rm> */ + "mvns", /* .operation (const char *) */ + 0, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rd,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rm,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + { /* MVN<c> <Rd>,<Rm> */ + "mvn", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rd,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rm,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 2; + res->mnem = armv7::ARMV7_MVNS; + + /* pcode: d = UInt(Rd) */ + res->fields[FIELD_d] = (res->fields[FIELD_Rd]); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: m = UInt(Rm) */ + res->fields[FIELD_m] = (res->fields[FIELD_Rm]); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + /* pcode: setflags = !InITBlock() */ + res->fields[FIELD_setflags] = !(req->inIfThen == IFTHEN_YES); + res->fields_mask[FIELD_setflags >> 6] |= 1LL << (FIELD_setflags & 63); + /* pcode: (shift_t, shift_n) = (SRType_LSL, 0) */ + res->fields[FIELD_shift_t] = 0; + res->fields_mask[FIELD_shift_t >> 6] |= 1LL << (FIELD_shift_t & 63); + res->fields[FIELD_shift_n] = 0; + res->fields_mask[FIELD_shift_n >> 6] |= 1LL << (FIELD_shift_n & 63); + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* Encoding T2 */ + /* pattern="11101,01,0011,S.1,1111,(0),imm3.3,Rd.4,imm2.2,type.2,Rm.4" width=32 stringency=17 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFFEF0000)==0xEA6F0000)) { + res->instrSize = 32; + if(!((instr & 0x8000)==0x0)) { + res->flags |= FLAG_UNPREDICTABLE; + } + if(!(req->arch & ARCH_ARMv6T2) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_S] = (instr & 0x100000)>>20; + res->fields_mask[FIELD_S >> 6] |= 1LL << (FIELD_S & 63); + char S_width = 1; + res->fields[FIELD_imm3] = (instr & 0x7000)>>12; + res->fields_mask[FIELD_imm3 >> 6] |= 1LL << (FIELD_imm3 & 63); + char imm3_width = 3; + res->fields[FIELD_Rd] = (instr & 0xF00)>>8; + res->fields_mask[FIELD_Rd >> 6] |= 1LL << (FIELD_Rd & 63); + char Rd_width = 4; + res->fields[FIELD_imm2] = (instr & 0xC0)>>6; + res->fields_mask[FIELD_imm2 >> 6] |= 1LL << (FIELD_imm2 & 63); + char imm2_width = 2; + res->fields[FIELD_type] = (instr & 0x30)>>4; + res->fields_mask[FIELD_type >> 6] |= 1LL << (FIELD_type & 63); + char type_width = 2; + res->fields[FIELD_Rm] = instr & 0xF; + res->fields_mask[FIELD_Rm >> 6] |= 1LL << (FIELD_Rm & 63); + char Rm_width = 4; + + static const instruction_format instr_formats[] = + { + { /* MVN{S}<c> <Rd>,<Rm>{,<shift>} */ + "mvn", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_OPTIONAL_STATUS, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rd,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rm,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_SHIFT,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_MVN; + + /* pcode: d = UInt(Rd) */ + res->fields[FIELD_d] = (res->fields[FIELD_Rd]); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: m = UInt(Rm) */ + res->fields[FIELD_m] = (res->fields[FIELD_Rm]); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + /* pcode: setflags = (S == '1') */ + res->fields[FIELD_setflags] = ((res->fields[FIELD_S]) == (0x1)); + res->fields_mask[FIELD_setflags >> 6] |= 1LL << (FIELD_setflags & 63); + /* pcode: (shift_t, shift_n) = DecodeImmShift(type, imm3:imm2) */ + res->fields[FIELD_shift_t] = DecodeImmShift_shift_t(res->fields[FIELD_type], (res->fields[FIELD_imm3]<<2)|(res->fields[FIELD_imm2])); + res->fields_mask[FIELD_shift_t >> 6] |= 1LL << (FIELD_shift_t & 63); + res->fields[FIELD_shift_n] = DecodeImmShift_shift_n(res->fields[FIELD_type], (res->fields[FIELD_imm3]<<2)|(res->fields[FIELD_imm2])); + res->fields_mask[FIELD_shift_n >> 6] |= 1LL << (FIELD_shift_n & 63); + /* pcode: if BadReg(d) || BadReg(m) then UNPREDICTABLE */ + if((BadReg(res->fields[FIELD_d])) || (BadReg(res->fields[FIELD_m]))) { + res->flags |= FLAG_UNPREDICTABLE; + } + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: EF4FC262 +int nop(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + /* Encoding T1 */ + /* pattern="1011,1111,0000,0000" width=16 stringency=16 */ + { + uint16_t instr = req->instr_word16; + if(((instr & 0xFFFF)==0xBF00)) { + res->instrSize = 16; + if(!(req->arch & ARCH_ARMv6T2) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + static const instruction_format instr_formats[] = + { + { /* NOP<c> */ + "nop", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 0 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_NOP; + + /* pcode: nop */ + while(0); + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* Encoding T2 */ + /* pattern="11110,0,111,01,0,(1)(1)(1)(1),10,(0),0,(0),000,00000000" width=32 stringency=32 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFFF0D7FF)==0xF3A08000)) { + res->instrSize = 32; + if(!((instr & 0xF2800)==0xF0000)) { + res->flags |= FLAG_UNPREDICTABLE; + } + if(!(req->arch & ARCH_ARMv6T2) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + static const instruction_format instr_formats[] = + { + { /* NOP<c>.W */ + "nop", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_WIDE, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 0 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_NOP; + + /* pcode: nop */ + while(0); + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: 82E45CF1 +int orn_immediate(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + /* Encoding T1 */ + /* pattern="11110,i.1,0,0011,S.1,Rn.4,0,imm3.3,Rd.4,imm8.8" width=32 stringency=13 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFBE08000)==0xF0600000)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ARMv6T2) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_i] = (instr & 0x4000000)>>26; + res->fields_mask[FIELD_i >> 6] |= 1LL << (FIELD_i & 63); + char i_width = 1; + res->fields[FIELD_S] = (instr & 0x100000)>>20; + res->fields_mask[FIELD_S >> 6] |= 1LL << (FIELD_S & 63); + char S_width = 1; + res->fields[FIELD_Rn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Rn >> 6] |= 1LL << (FIELD_Rn & 63); + char Rn_width = 4; + res->fields[FIELD_imm3] = (instr & 0x7000)>>12; + res->fields_mask[FIELD_imm3 >> 6] |= 1LL << (FIELD_imm3 & 63); + char imm3_width = 3; + res->fields[FIELD_Rd] = (instr & 0xF00)>>8; + res->fields_mask[FIELD_Rd >> 6] |= 1LL << (FIELD_Rd & 63); + char Rd_width = 4; + res->fields[FIELD_imm8] = instr & 0xFF; + res->fields_mask[FIELD_imm8 >> 6] |= 1LL << (FIELD_imm8 & 63); + char imm8_width = 8; + + static const instruction_format instr_formats[] = + { + { /* ORN{S}<c> <Rd>,<Rn>,#<imm32> */ + "orn", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_OPTIONAL_STATUS, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rd,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rn,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_IMM,FIELD_imm32,FIELD_UNINIT,"#","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_ORN; + + /* pcode: if Rn == '1111' then SEE MVN (immediate) */ + if((res->fields[FIELD_Rn]) == (0xF)) { + + return mvn_immediate(req, res); + } + /* pcode: d = UInt(Rd) */ + res->fields[FIELD_d] = (res->fields[FIELD_Rd]); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: n = UInt(Rn) */ + res->fields[FIELD_n] = (res->fields[FIELD_Rn]); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: setflags = (S == '1') */ + res->fields[FIELD_setflags] = ((res->fields[FIELD_S]) == (0x1)); + res->fields_mask[FIELD_setflags >> 6] |= 1LL << (FIELD_setflags & 63); + /* pcode: (imm32, carry) = ThumbExpandImm_C(i:imm3:imm8, APSR.C) */ + res->fields[FIELD_imm32] = ThumbExpandImm_C_imm32((res->fields[FIELD_i]<<(8+3))|(res->fields[FIELD_imm3]<<8)|(res->fields[FIELD_imm8]), res->fields[FIELD_APSR_C]); + res->fields_mask[FIELD_imm32 >> 6] |= 1LL << (FIELD_imm32 & 63); + res->fields[FIELD_carry] = ThumbExpandImm_C_cout((res->fields[FIELD_i]<<(8+3))|(res->fields[FIELD_imm3]<<8)|(res->fields[FIELD_imm8]), res->fields[FIELD_APSR_C]); + res->fields_mask[FIELD_carry >> 6] |= 1LL << (FIELD_carry & 63); + /* TODO: handle ThumbExpandImm_C's possible setting of UNPREDICTABLE */ while(0); + /* pcode: if BadReg(d) || n == 13 then UNPREDICTABLE */ + if((BadReg(res->fields[FIELD_d])) || ((res->fields[FIELD_n]) == (13))) { + res->flags |= FLAG_UNPREDICTABLE; + } + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: 5BB4DC7B +int orn_register(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + /* Encoding T1 */ + /* pattern="11101,01,0011,S.1,Rn.4,(0),imm3.3,Rd.4,imm2.2,type.2,Rm.4" width=32 stringency=13 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFFE00000)==0xEA600000)) { + res->instrSize = 32; + if(!((instr & 0x8000)==0x0)) { + res->flags |= FLAG_UNPREDICTABLE; + } + if(!(req->arch & ARCH_ARMv6T2) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_S] = (instr & 0x100000)>>20; + res->fields_mask[FIELD_S >> 6] |= 1LL << (FIELD_S & 63); + char S_width = 1; + res->fields[FIELD_Rn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Rn >> 6] |= 1LL << (FIELD_Rn & 63); + char Rn_width = 4; + res->fields[FIELD_imm3] = (instr & 0x7000)>>12; + res->fields_mask[FIELD_imm3 >> 6] |= 1LL << (FIELD_imm3 & 63); + char imm3_width = 3; + res->fields[FIELD_Rd] = (instr & 0xF00)>>8; + res->fields_mask[FIELD_Rd >> 6] |= 1LL << (FIELD_Rd & 63); + char Rd_width = 4; + res->fields[FIELD_imm2] = (instr & 0xC0)>>6; + res->fields_mask[FIELD_imm2 >> 6] |= 1LL << (FIELD_imm2 & 63); + char imm2_width = 2; + res->fields[FIELD_type] = (instr & 0x30)>>4; + res->fields_mask[FIELD_type >> 6] |= 1LL << (FIELD_type & 63); + char type_width = 2; + res->fields[FIELD_Rm] = instr & 0xF; + res->fields_mask[FIELD_Rm >> 6] |= 1LL << (FIELD_Rm & 63); + char Rm_width = 4; + + static const instruction_format instr_formats[] = + { + { /* ORN{S}<c> <Rd>,<Rn>,<Rm>{,<shift>} */ + "orn", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_OPTIONAL_STATUS, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rd,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rn,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rm,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_SHIFT,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 4 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_ORN; + + /* pcode: if Rn == '1111' then SEE MVN (register) */ + if((res->fields[FIELD_Rn]) == (0xF)) { + + return mvn_register(req, res); + } + /* pcode: d = UInt(Rd) */ + res->fields[FIELD_d] = (res->fields[FIELD_Rd]); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: n = UInt(Rn) */ + res->fields[FIELD_n] = (res->fields[FIELD_Rn]); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: m = UInt(Rm) */ + res->fields[FIELD_m] = (res->fields[FIELD_Rm]); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + /* pcode: setflags = (S == '1') */ + res->fields[FIELD_setflags] = ((res->fields[FIELD_S]) == (0x1)); + res->fields_mask[FIELD_setflags >> 6] |= 1LL << (FIELD_setflags & 63); + /* pcode: (shift_t, shift_n) = DecodeImmShift(type, imm3:imm2) */ + res->fields[FIELD_shift_t] = DecodeImmShift_shift_t(res->fields[FIELD_type], (res->fields[FIELD_imm3]<<2)|(res->fields[FIELD_imm2])); + res->fields_mask[FIELD_shift_t >> 6] |= 1LL << (FIELD_shift_t & 63); + res->fields[FIELD_shift_n] = DecodeImmShift_shift_n(res->fields[FIELD_type], (res->fields[FIELD_imm3]<<2)|(res->fields[FIELD_imm2])); + res->fields_mask[FIELD_shift_n >> 6] |= 1LL << (FIELD_shift_n & 63); + /* pcode: if BadReg(d) || n == 13 || BadReg(m) then UNPREDICTABLE */ + if(((BadReg(res->fields[FIELD_d])) || ((res->fields[FIELD_n]) == (13))) || (BadReg(res->fields[FIELD_m]))) { + res->flags |= FLAG_UNPREDICTABLE; + } + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: 4D2E88A1 +int orr_immediate(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + /* Encoding T1 */ + /* pattern="11110,i.1,0,0010,S.1,Rn.4,0,imm3.3,Rd.4,imm8.8" width=32 stringency=13 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFBE08000)==0xF0400000)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ARMv6T2) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_i] = (instr & 0x4000000)>>26; + res->fields_mask[FIELD_i >> 6] |= 1LL << (FIELD_i & 63); + char i_width = 1; + res->fields[FIELD_S] = (instr & 0x100000)>>20; + res->fields_mask[FIELD_S >> 6] |= 1LL << (FIELD_S & 63); + char S_width = 1; + res->fields[FIELD_Rn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Rn >> 6] |= 1LL << (FIELD_Rn & 63); + char Rn_width = 4; + res->fields[FIELD_imm3] = (instr & 0x7000)>>12; + res->fields_mask[FIELD_imm3 >> 6] |= 1LL << (FIELD_imm3 & 63); + char imm3_width = 3; + res->fields[FIELD_Rd] = (instr & 0xF00)>>8; + res->fields_mask[FIELD_Rd >> 6] |= 1LL << (FIELD_Rd & 63); + char Rd_width = 4; + res->fields[FIELD_imm8] = instr & 0xFF; + res->fields_mask[FIELD_imm8 >> 6] |= 1LL << (FIELD_imm8 & 63); + char imm8_width = 8; + + static const instruction_format instr_formats[] = + { + { /* ORR{S}<c> <Rd>,<Rn>,#<imm32> */ + "orr", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_OPTIONAL_STATUS, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rd,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rn,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_IMM,FIELD_imm32,FIELD_UNINIT,"#","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_ORR; + + /* pcode: if Rn == '1111' then SEE MOV (immediate) */ + if((res->fields[FIELD_Rn]) == (0xF)) { + + return mov_immediate(req, res); + } + /* pcode: d = UInt(Rd) */ + res->fields[FIELD_d] = (res->fields[FIELD_Rd]); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: n = UInt(Rn) */ + res->fields[FIELD_n] = (res->fields[FIELD_Rn]); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: setflags = (S == '1') */ + res->fields[FIELD_setflags] = ((res->fields[FIELD_S]) == (0x1)); + res->fields_mask[FIELD_setflags >> 6] |= 1LL << (FIELD_setflags & 63); + /* pcode: (imm32, carry) = ThumbExpandImm_C(i:imm3:imm8, APSR.C) */ + res->fields[FIELD_imm32] = ThumbExpandImm_C_imm32((res->fields[FIELD_i]<<(8+3))|(res->fields[FIELD_imm3]<<8)|(res->fields[FIELD_imm8]), res->fields[FIELD_APSR_C]); + res->fields_mask[FIELD_imm32 >> 6] |= 1LL << (FIELD_imm32 & 63); + res->fields[FIELD_carry] = ThumbExpandImm_C_cout((res->fields[FIELD_i]<<(8+3))|(res->fields[FIELD_imm3]<<8)|(res->fields[FIELD_imm8]), res->fields[FIELD_APSR_C]); + res->fields_mask[FIELD_carry >> 6] |= 1LL << (FIELD_carry & 63); + /* TODO: handle ThumbExpandImm_C's possible setting of UNPREDICTABLE */ while(0); + /* pcode: if BadReg(d) || n == 13 then UNPREDICTABLE */ + if((BadReg(res->fields[FIELD_d])) || ((res->fields[FIELD_n]) == (13))) { + res->flags |= FLAG_UNPREDICTABLE; + } + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: 40615183 +int orr_register(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + /* Encoding T1 */ + /* pattern="010000,1100,Rm.3,Rdn.3" width=16 stringency=10 */ + { + uint16_t instr = req->instr_word16; + if(((instr & 0xFFC0)==0x4300)) { + res->instrSize = 16; + if(!(req->arch & ARCH_ARMv4T) && !(req->arch & ARCH_ARMv5T) && !(req->arch & ARCH_ARMv6) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_Rm] = (instr & 0x38)>>3; + res->fields_mask[FIELD_Rm >> 6] |= 1LL << (FIELD_Rm & 63); + char Rm_width = 3; + res->fields[FIELD_Rdn] = instr & 0x7; + res->fields_mask[FIELD_Rdn >> 6] |= 1LL << (FIELD_Rdn & 63); + char Rdn_width = 3; + + static const instruction_format instr_formats[] = + { + { /* ORRS <Rdn>,<Rm> */ + "orrs", /* .operation (const char *) */ + 0, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rdn,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rm,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + { /* ORR<c> <Rdn>,<Rm> */ + "orr", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rdn,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rm,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 2; + res->mnem = armv7::ARMV7_ORRS; + + /* pcode: d = UInt(Rdn) */ + res->fields[FIELD_d] = (res->fields[FIELD_Rdn]); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: n = UInt(Rdn) */ + res->fields[FIELD_n] = (res->fields[FIELD_Rdn]); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: m = UInt(Rm) */ + res->fields[FIELD_m] = (res->fields[FIELD_Rm]); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + /* pcode: setflags = !InITBlock() */ + res->fields[FIELD_setflags] = !(req->inIfThen == IFTHEN_YES); + res->fields_mask[FIELD_setflags >> 6] |= 1LL << (FIELD_setflags & 63); + /* pcode: (shift_t, shift_n) = (SRType_LSL, 0) */ + res->fields[FIELD_shift_t] = 0; + res->fields_mask[FIELD_shift_t >> 6] |= 1LL << (FIELD_shift_t & 63); + res->fields[FIELD_shift_n] = 0; + res->fields_mask[FIELD_shift_n >> 6] |= 1LL << (FIELD_shift_n & 63); + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* Encoding T2 */ + /* pattern="11101,01,0010,S.1,Rn.4,(0),imm3.3,Rd.4,imm2.2,type.2,Rm.4" width=32 stringency=13 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFFE00000)==0xEA400000)) { + res->instrSize = 32; + if(!((instr & 0x8000)==0x0)) { + res->flags |= FLAG_UNPREDICTABLE; + } + if(!(req->arch & ARCH_ARMv6T2) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_S] = (instr & 0x100000)>>20; + res->fields_mask[FIELD_S >> 6] |= 1LL << (FIELD_S & 63); + char S_width = 1; + res->fields[FIELD_Rn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Rn >> 6] |= 1LL << (FIELD_Rn & 63); + char Rn_width = 4; + res->fields[FIELD_imm3] = (instr & 0x7000)>>12; + res->fields_mask[FIELD_imm3 >> 6] |= 1LL << (FIELD_imm3 & 63); + char imm3_width = 3; + res->fields[FIELD_Rd] = (instr & 0xF00)>>8; + res->fields_mask[FIELD_Rd >> 6] |= 1LL << (FIELD_Rd & 63); + char Rd_width = 4; + res->fields[FIELD_imm2] = (instr & 0xC0)>>6; + res->fields_mask[FIELD_imm2 >> 6] |= 1LL << (FIELD_imm2 & 63); + char imm2_width = 2; + res->fields[FIELD_type] = (instr & 0x30)>>4; + res->fields_mask[FIELD_type >> 6] |= 1LL << (FIELD_type & 63); + char type_width = 2; + res->fields[FIELD_Rm] = instr & 0xF; + res->fields_mask[FIELD_Rm >> 6] |= 1LL << (FIELD_Rm & 63); + char Rm_width = 4; + + static const instruction_format instr_formats[] = + { + { /* ORR{S}<c> <Rd>,<Rn>,<Rm>{,<shift>} */ + "orr", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_OPTIONAL_STATUS, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rd,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rn,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rm,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_SHIFT,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 4 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_ORR; + + /* pcode: if Rn == '1111' then SEE MOV (register) */ + if((res->fields[FIELD_Rn]) == (0xF)) { + + return mov_register(req, res); + } + /* pcode: d = UInt(Rd) */ + res->fields[FIELD_d] = (res->fields[FIELD_Rd]); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: n = UInt(Rn) */ + res->fields[FIELD_n] = (res->fields[FIELD_Rn]); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: m = UInt(Rm) */ + res->fields[FIELD_m] = (res->fields[FIELD_Rm]); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + /* pcode: setflags = (S == '1') */ + res->fields[FIELD_setflags] = ((res->fields[FIELD_S]) == (0x1)); + res->fields_mask[FIELD_setflags >> 6] |= 1LL << (FIELD_setflags & 63); + /* pcode: (shift_t, shift_n) = DecodeImmShift(type, imm3:imm2) */ + res->fields[FIELD_shift_t] = DecodeImmShift_shift_t(res->fields[FIELD_type], (res->fields[FIELD_imm3]<<2)|(res->fields[FIELD_imm2])); + res->fields_mask[FIELD_shift_t >> 6] |= 1LL << (FIELD_shift_t & 63); + res->fields[FIELD_shift_n] = DecodeImmShift_shift_n(res->fields[FIELD_type], (res->fields[FIELD_imm3]<<2)|(res->fields[FIELD_imm2])); + res->fields_mask[FIELD_shift_n >> 6] |= 1LL << (FIELD_shift_n & 63); + /* pcode: if BadReg(d) || n == 13 || BadReg(m) then UNPREDICTABLE */ + if(((BadReg(res->fields[FIELD_d])) || ((res->fields[FIELD_n]) == (13))) || (BadReg(res->fields[FIELD_m]))) { + res->flags |= FLAG_UNPREDICTABLE; + } + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: 4573D5CD +int parallel_add_sub_signed(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + uint32_t instr = req->instr_word32; + uint32_t op1 = (instr & 0x700000)>>20; + uint32_t op2 = (instr & 0x30)>>4; + if(((op1 & 0x7)==0x1) && ((op2 & 0x3)==0x0)) return sadd16(req, res); + if(((op1 & 0x7)==0x2) && ((op2 & 0x3)==0x0)) return sasx(req, res); + if(((op1 & 0x7)==0x6) && ((op2 & 0x3)==0x0)) return ssax(req, res); + if(((op1 & 0x7)==0x5) && ((op2 & 0x3)==0x0)) return ssub16(req, res); + if(((op1 & 0x7)==0x0) && ((op2 & 0x3)==0x0)) return sadd8(req, res); + if(((op1 & 0x7)==0x4) && ((op2 & 0x3)==0x0)) return ssub8(req, res); + if(((op1 & 0x7)==0x1) && ((op2 & 0x3)==0x1)) return qadd16(req, res); + if(((op1 & 0x7)==0x2) && ((op2 & 0x3)==0x1)) return qasx(req, res); + if(((op1 & 0x7)==0x6) && ((op2 & 0x3)==0x1)) return qsax(req, res); + if(((op1 & 0x7)==0x5) && ((op2 & 0x3)==0x1)) return qsub16(req, res); + if(((op1 & 0x7)==0x0) && ((op2 & 0x3)==0x1)) return qadd8(req, res); + if(((op1 & 0x7)==0x4) && ((op2 & 0x3)==0x1)) return qsub8(req, res); + if(((op1 & 0x7)==0x1) && ((op2 & 0x3)==0x2)) return shadd16(req, res); + if(((op1 & 0x7)==0x2) && ((op2 & 0x3)==0x2)) return shasx(req, res); + if(((op1 & 0x7)==0x6) && ((op2 & 0x3)==0x2)) return shsax(req, res); + if(((op1 & 0x7)==0x5) && ((op2 & 0x3)==0x2)) return shsub16(req, res); + if(((op1 & 0x7)==0x0) && ((op2 & 0x3)==0x2)) return shadd8(req, res); + if(((op1 & 0x7)==0x4) && ((op2 & 0x3)==0x2)) return shsub8(req, res); + return undefined(req, res); +} + +// gen_crc: F17D6F9E +int parallel_add_sub_unsigned(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + uint32_t instr = req->instr_word32; + uint32_t op1 = (instr & 0x700000)>>20; + uint32_t op2 = (instr & 0x30)>>4; + if(((op1 & 0x7)==0x1) && ((op2 & 0x3)==0x0)) return uadd16(req, res); + if(((op1 & 0x7)==0x2) && ((op2 & 0x3)==0x0)) return uasx(req, res); + if(((op1 & 0x7)==0x6) && ((op2 & 0x3)==0x0)) return usax(req, res); + if(((op1 & 0x7)==0x5) && ((op2 & 0x3)==0x0)) return usub16(req, res); + if(((op1 & 0x7)==0x0) && ((op2 & 0x3)==0x0)) return uadd8(req, res); + if(((op1 & 0x7)==0x4) && ((op2 & 0x3)==0x0)) return usub8(req, res); + if(((op1 & 0x7)==0x1) && ((op2 & 0x3)==0x1)) return uqadd16(req, res); + if(((op1 & 0x7)==0x2) && ((op2 & 0x3)==0x1)) return uqasx(req, res); + if(((op1 & 0x7)==0x6) && ((op2 & 0x3)==0x1)) return uqsax(req, res); + if(((op1 & 0x7)==0x5) && ((op2 & 0x3)==0x1)) return uqsub16(req, res); + if(((op1 & 0x7)==0x0) && ((op2 & 0x3)==0x1)) return uqadd8(req, res); + if(((op1 & 0x7)==0x4) && ((op2 & 0x3)==0x1)) return uqsub8(req, res); + if(((op1 & 0x7)==0x1) && ((op2 & 0x3)==0x2)) return uhadd16(req, res); + if(((op1 & 0x7)==0x2) && ((op2 & 0x3)==0x2)) return uhasx(req, res); + if(((op1 & 0x7)==0x6) && ((op2 & 0x3)==0x2)) return uhsax(req, res); + if(((op1 & 0x7)==0x5) && ((op2 & 0x3)==0x2)) return uhsub16(req, res); + if(((op1 & 0x7)==0x0) && ((op2 & 0x3)==0x2)) return uhadd8(req, res); + if(((op1 & 0x7)==0x4) && ((op2 & 0x3)==0x2)) return uhsub8(req, res); + return undefined(req, res); +} + +// gen_crc: DDB34223 +int pkh(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + /* Encoding T1 */ + /* pattern="11101,01,0110,0,Rn.4,(0),imm3.3,Rd.4,imm2.2,0,0,Rm.4" width=32 stringency=15 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFFF00030)==0xEAC00000)) { + res->instrSize = 32; + if(!((instr & 0x8000)==0x0)) { + res->flags |= FLAG_UNPREDICTABLE; + } + if(!(req->arch & ARCH_ARMv6T2) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_Rn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Rn >> 6] |= 1LL << (FIELD_Rn & 63); + char Rn_width = 4; + res->fields[FIELD_imm3] = (instr & 0x7000)>>12; + res->fields_mask[FIELD_imm3 >> 6] |= 1LL << (FIELD_imm3 & 63); + char imm3_width = 3; + res->fields[FIELD_Rd] = (instr & 0xF00)>>8; + res->fields_mask[FIELD_Rd >> 6] |= 1LL << (FIELD_Rd & 63); + char Rd_width = 4; + res->fields[FIELD_imm2] = (instr & 0xC0)>>6; + res->fields_mask[FIELD_imm2 >> 6] |= 1LL << (FIELD_imm2 & 63); + char imm2_width = 2; + res->fields[FIELD_Rm] = instr & 0xF; + res->fields_mask[FIELD_Rm >> 6] |= 1LL << (FIELD_Rm & 63); + char Rm_width = 4; + + static const instruction_format instr_formats[] = + { + { /* PKHBT<c> <Rd>,<Rn>,<Rm>{,<shift>} */ + "pkhbt", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rd,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rn,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rm,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_SHIFT,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 4 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_PKHBT; + + /* pcode: tb = 0 */ + res->fields[FIELD_tb] = 0; + res->fields_mask[FIELD_tb >> 6] |= 1LL << (FIELD_tb & 63); + /* pcode: d = UInt(Rd) */ + res->fields[FIELD_d] = (res->fields[FIELD_Rd]); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: n = UInt(Rn) */ + res->fields[FIELD_n] = (res->fields[FIELD_Rn]); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: m = UInt(Rm) */ + res->fields[FIELD_m] = (res->fields[FIELD_Rm]); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + /* pcode: tbform = (tb == '1') */ + res->fields[FIELD_tbform] = ((res->fields[FIELD_tb]) == (0x1)); + res->fields_mask[FIELD_tbform >> 6] |= 1LL << (FIELD_tbform & 63); + /* pcode: (shift_t, shift_n) = DecodeImmShift(tb:'0', imm3:imm2) */ + res->fields[FIELD_shift_t] = DecodeImmShift_shift_t((res->fields[FIELD_tb]<<1)|(0x0), (res->fields[FIELD_imm3]<<2)|(res->fields[FIELD_imm2])); + res->fields_mask[FIELD_shift_t >> 6] |= 1LL << (FIELD_shift_t & 63); + res->fields[FIELD_shift_n] = DecodeImmShift_shift_n((res->fields[FIELD_tb]<<1)|(0x0), (res->fields[FIELD_imm3]<<2)|(res->fields[FIELD_imm2])); + res->fields_mask[FIELD_shift_n >> 6] |= 1LL << (FIELD_shift_n & 63); + /* pcode: if BadReg(d) || BadReg(n) || BadReg(m) then UNPREDICTABLE */ + if(((BadReg(res->fields[FIELD_d])) || (BadReg(res->fields[FIELD_n]))) || (BadReg(res->fields[FIELD_m]))) { + res->flags |= FLAG_UNPREDICTABLE; + } + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* Encoding T1 */ + /* pattern="11101,01,0110,0,Rn.4,(0),imm3.3,Rd.4,imm2.2,1,0,Rm.4" width=32 stringency=15 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFFF00030)==0xEAC00020)) { + res->instrSize = 32; + if(!((instr & 0x8000)==0x0)) { + res->flags |= FLAG_UNPREDICTABLE; + } + if(!(req->arch & ARCH_ARMv6T2) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_Rn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Rn >> 6] |= 1LL << (FIELD_Rn & 63); + char Rn_width = 4; + res->fields[FIELD_imm3] = (instr & 0x7000)>>12; + res->fields_mask[FIELD_imm3 >> 6] |= 1LL << (FIELD_imm3 & 63); + char imm3_width = 3; + res->fields[FIELD_Rd] = (instr & 0xF00)>>8; + res->fields_mask[FIELD_Rd >> 6] |= 1LL << (FIELD_Rd & 63); + char Rd_width = 4; + res->fields[FIELD_imm2] = (instr & 0xC0)>>6; + res->fields_mask[FIELD_imm2 >> 6] |= 1LL << (FIELD_imm2 & 63); + char imm2_width = 2; + res->fields[FIELD_Rm] = instr & 0xF; + res->fields_mask[FIELD_Rm >> 6] |= 1LL << (FIELD_Rm & 63); + char Rm_width = 4; + + static const instruction_format instr_formats[] = + { + { /* PKHTB<c> <Rd>,<Rn>,<Rm>{,<shift>} */ + "pkhtb", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rd,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rn,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rm,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_SHIFT,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 4 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_PKHTB; + + /* pcode: tb = 1 */ + res->fields[FIELD_tb] = 1; + res->fields_mask[FIELD_tb >> 6] |= 1LL << (FIELD_tb & 63); + /* pcode: d = UInt(Rd) */ + res->fields[FIELD_d] = (res->fields[FIELD_Rd]); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: n = UInt(Rn) */ + res->fields[FIELD_n] = (res->fields[FIELD_Rn]); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: m = UInt(Rm) */ + res->fields[FIELD_m] = (res->fields[FIELD_Rm]); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + /* pcode: tbform = (tb == '1') */ + res->fields[FIELD_tbform] = ((res->fields[FIELD_tb]) == (0x1)); + res->fields_mask[FIELD_tbform >> 6] |= 1LL << (FIELD_tbform & 63); + /* pcode: (shift_t, shift_n) = DecodeImmShift(tb:'0', imm3:imm2) */ + res->fields[FIELD_shift_t] = DecodeImmShift_shift_t((res->fields[FIELD_tb]<<1)|(0x0), (res->fields[FIELD_imm3]<<2)|(res->fields[FIELD_imm2])); + res->fields_mask[FIELD_shift_t >> 6] |= 1LL << (FIELD_shift_t & 63); + res->fields[FIELD_shift_n] = DecodeImmShift_shift_n((res->fields[FIELD_tb]<<1)|(0x0), (res->fields[FIELD_imm3]<<2)|(res->fields[FIELD_imm2])); + res->fields_mask[FIELD_shift_n >> 6] |= 1LL << (FIELD_shift_n & 63); + /* pcode: if BadReg(d) || BadReg(n) || BadReg(m) then UNPREDICTABLE */ + if(((BadReg(res->fields[FIELD_d])) || (BadReg(res->fields[FIELD_n]))) || (BadReg(res->fields[FIELD_m]))) { + res->flags |= FLAG_UNPREDICTABLE; + } + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: 5BE87C49 +int pld(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + uint32_t instr = req->instr_word32; + uint32_t Rn = (instr & 0xF0000)>>16; + uint32_t bits = (instr & 0xF80)>>7; + if(((bits & 0x1F)==0x0) && 1) return pld_pldw_register(req, res); + if(((Rn & 0xF)==0xF) && 1) return pld_literal(req, res); + if(1) return pld_pldw_immediate(req, res); + return undefined(req, res); +} + +// gen_crc: 63E7872A +int pld_literal(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + /* Encoding T1 */ + /* pattern="11111,00,0,U.1,0,(0),1,1111,1111,imm12.12" width=32 stringency=22 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFF5FF000)==0xF81FF000)) { + res->instrSize = 32; + if(!((instr & 0x200000)==0x0)) { + res->flags |= FLAG_UNPREDICTABLE; + } + if(!(req->arch & ARCH_ARMv6T2) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_U] = (instr & 0x800000)>>23; + res->fields_mask[FIELD_U >> 6] |= 1LL << (FIELD_U & 63); + char U_width = 1; + res->fields[FIELD_imm12] = instr & 0xFFF; + res->fields_mask[FIELD_imm12 >> 6] |= 1LL << (FIELD_imm12 & 63); + char imm12_width = 12; + + static const instruction_format instr_formats[] = + { + { /* PLD<c> <label> */ + "pld", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_LABEL,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 1 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_PLD; + + /* pcode: imm32 = ZeroExtend(imm12, 32) */ + res->fields[FIELD_imm32] = res->fields[FIELD_imm12]; + res->fields_mask[FIELD_imm32 >> 6] |= 1LL << (FIELD_imm32 & 63); + /* pcode: add = (U == '1') */ + res->fields[FIELD_add] = ((res->fields[FIELD_U]) == (0x1)); + res->fields_mask[FIELD_add >> 6] |= 1LL << (FIELD_add & 63); + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: 03562851 +int pld_pldw_immediate(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + /* Encoding T1 */ + /* pattern="11111,00,0,1,0,0,1,Rn.4,1111,imm12.12" width=32 stringency=18 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFFF0F000)==0xF890F000)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ARMv6T2) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_Rn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Rn >> 6] |= 1LL << (FIELD_Rn & 63); + char Rn_width = 4; + res->fields[FIELD_imm12] = instr & 0xFFF; + res->fields_mask[FIELD_imm12 >> 6] |= 1LL << (FIELD_imm12 & 63); + char imm12_width = 12; + + static const instruction_format instr_formats[] = + { + { /* PLD<c> [<Rn>,#<imm12>] */ + "pld", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_MEMORY_ONE_REG_IMM,FIELD_Rn,FIELD_imm12,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 1 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_PLD; + + /* pcode: if Rn == '1111' then SEE PLD (literal) */ + if((res->fields[FIELD_Rn]) == (0xF)) { + + return pld_literal(req, res); + } + /* pcode: n = UInt(Rn) */ + res->fields[FIELD_n] = (res->fields[FIELD_Rn]); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: imm32 = ZeroExtend(imm12, 32) */ + res->fields[FIELD_imm32] = res->fields[FIELD_imm12]; + res->fields_mask[FIELD_imm32 >> 6] |= 1LL << (FIELD_imm32 & 63); + /* pcode: add = TRUE */ + res->fields[FIELD_add] = 1; + res->fields_mask[FIELD_add >> 6] |= 1LL << (FIELD_add & 63); + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* Encoding T1 */ + /* pattern="11111,00,0,1,0,1,1,Rn.4,1111,imm12.12" width=32 stringency=18 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFFF0F000)==0xF8B0F000)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ARMv7_WITH_MP)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_Rn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Rn >> 6] |= 1LL << (FIELD_Rn & 63); + char Rn_width = 4; + res->fields[FIELD_imm12] = instr & 0xFFF; + res->fields_mask[FIELD_imm12 >> 6] |= 1LL << (FIELD_imm12 & 63); + char imm12_width = 12; + + static const instruction_format instr_formats[] = + { + { /* PLDW<c> [<Rn>,#<imm12>] */ + "pldw", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_MEMORY_ONE_REG_IMM,FIELD_Rn,FIELD_imm12,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 1 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_PLDW; + + /* pcode: if Rn == '1111' then SEE PLD (literal) */ + if((res->fields[FIELD_Rn]) == (0xF)) { + + return pld_literal(req, res); + } + /* pcode: n = UInt(Rn) */ + res->fields[FIELD_n] = (res->fields[FIELD_Rn]); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: imm32 = ZeroExtend(imm12, 32) */ + res->fields[FIELD_imm32] = res->fields[FIELD_imm12]; + res->fields_mask[FIELD_imm32 >> 6] |= 1LL << (FIELD_imm32 & 63); + /* pcode: add = TRUE */ + res->fields[FIELD_add] = 1; + res->fields_mask[FIELD_add >> 6] |= 1LL << (FIELD_add & 63); + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* Encoding T2 */ + /* pattern="11111,00,0,0,0,0,1,Rn.4,1111,1,100,imm8.8" width=32 stringency=20 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFFF0FF00)==0xF810FC00)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ARMv6T2) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_Rn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Rn >> 6] |= 1LL << (FIELD_Rn & 63); + char Rn_width = 4; + res->fields[FIELD_imm8] = instr & 0xFF; + res->fields_mask[FIELD_imm8 >> 6] |= 1LL << (FIELD_imm8 & 63); + char imm8_width = 8; + + static const instruction_format instr_formats[] = + { + { /* PLD<c> [<Rn>,#-<imm8>] */ + "pld", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_MEMORY_ONE_REG_NEG_IMM,FIELD_Rn,FIELD_imm8,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 1 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_PLD; + + /* pcode: if Rn == '1111' then SEE PLD (literal) */ + if((res->fields[FIELD_Rn]) == (0xF)) { + + return pld_literal(req, res); + } + /* pcode: n = UInt(Rn) */ + res->fields[FIELD_n] = (res->fields[FIELD_Rn]); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: imm32 = ZeroExtend(imm8, 32) */ + res->fields[FIELD_imm32] = res->fields[FIELD_imm8]; + res->fields_mask[FIELD_imm32 >> 6] |= 1LL << (FIELD_imm32 & 63); + /* pcode: add = FALSE */ + res->fields[FIELD_add] = 0; + res->fields_mask[FIELD_add >> 6] |= 1LL << (FIELD_add & 63); + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* Encoding T2 */ + /* pattern="11111,00,0,0,0,1,1,Rn.4,1111,1,100,imm8.8" width=32 stringency=20 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFFF0FF00)==0xF830FC00)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ARMv7_WITH_MP)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_Rn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Rn >> 6] |= 1LL << (FIELD_Rn & 63); + char Rn_width = 4; + res->fields[FIELD_imm8] = instr & 0xFF; + res->fields_mask[FIELD_imm8 >> 6] |= 1LL << (FIELD_imm8 & 63); + char imm8_width = 8; + + static const instruction_format instr_formats[] = + { + { /* PLDW<c> [<Rn>,#-<imm8>] */ + "pldw", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_MEMORY_ONE_REG_NEG_IMM,FIELD_Rn,FIELD_imm8,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 1 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_PLDW; + + /* pcode: if Rn == '1111' then SEE PLD (literal) */ + if((res->fields[FIELD_Rn]) == (0xF)) { + + return pld_literal(req, res); + } + /* pcode: n = UInt(Rn) */ + res->fields[FIELD_n] = (res->fields[FIELD_Rn]); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: imm32 = ZeroExtend(imm8, 32) */ + res->fields[FIELD_imm32] = res->fields[FIELD_imm8]; + res->fields_mask[FIELD_imm32 >> 6] |= 1LL << (FIELD_imm32 & 63); + /* pcode: add = FALSE */ + res->fields[FIELD_add] = 0; + res->fields_mask[FIELD_add >> 6] |= 1LL << (FIELD_add & 63); + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: 51ABAEBD +int pld_pldw_register(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + /* Encoding T1 */ + /* pattern="11111,00,0,0,0,0,1,Rn.4,1111,0,00000,imm2.2,Rm.4" width=32 stringency=22 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFFF0FFC0)==0xF810F000)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ARMv6T2) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_Rn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Rn >> 6] |= 1LL << (FIELD_Rn & 63); + char Rn_width = 4; + res->fields[FIELD_imm2] = (instr & 0x30)>>4; + res->fields_mask[FIELD_imm2 >> 6] |= 1LL << (FIELD_imm2 & 63); + char imm2_width = 2; + res->fields[FIELD_Rm] = instr & 0xF; + res->fields_mask[FIELD_Rm >> 6] |= 1LL << (FIELD_Rm & 63); + char Rm_width = 4; + + static const instruction_format instr_formats[] = + { + { /* PLD<c> [<Rn>,<Rm>{,<shift>}] */ + "pld", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_MEMORY_TWO_REG_SHIFT,FIELD_Rn,FIELD_Rm,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 1 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_PLD; + + /* pcode: if Rn == '1111' then SEE PLD (literal) */ + if((res->fields[FIELD_Rn]) == (0xF)) { + + return pld_literal(req, res); + } + /* pcode: n = UInt(Rn) */ + res->fields[FIELD_n] = (res->fields[FIELD_Rn]); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: m = UInt(Rm) */ + res->fields[FIELD_m] = (res->fields[FIELD_Rm]); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + /* pcode: add = TRUE */ + res->fields[FIELD_add] = 1; + res->fields_mask[FIELD_add >> 6] |= 1LL << (FIELD_add & 63); + /* pcode: (shift_t, shift_n) = (SRType_LSL, UInt(imm2)) */ + res->fields[FIELD_shift_t] = 0; + res->fields_mask[FIELD_shift_t >> 6] |= 1LL << (FIELD_shift_t & 63); + res->fields[FIELD_shift_n] = (res->fields[FIELD_imm2]); + res->fields_mask[FIELD_shift_n >> 6] |= 1LL << (FIELD_shift_n & 63); + /* pcode: if BadReg(m) then UNPREDICTABLE */ + if(BadReg(res->fields[FIELD_m])) { + res->flags |= FLAG_UNPREDICTABLE; + } + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* Encoding T1 */ + /* pattern="11111,00,0,0,0,1,1,Rn.4,1111,0,00000,imm2.2,Rm.4" width=32 stringency=22 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFFF0FFC0)==0xF830F000)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ARMv7_WITH_MP)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_Rn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Rn >> 6] |= 1LL << (FIELD_Rn & 63); + char Rn_width = 4; + res->fields[FIELD_imm2] = (instr & 0x30)>>4; + res->fields_mask[FIELD_imm2 >> 6] |= 1LL << (FIELD_imm2 & 63); + char imm2_width = 2; + res->fields[FIELD_Rm] = instr & 0xF; + res->fields_mask[FIELD_Rm >> 6] |= 1LL << (FIELD_Rm & 63); + char Rm_width = 4; + + static const instruction_format instr_formats[] = + { + { /* PLDW<c> [<Rn>,<Rm>{,<shift>}] */ + "pldw", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_MEMORY_TWO_REG_SHIFT,FIELD_Rn,FIELD_Rm,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 1 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_PLDW; + + /* pcode: if Rn == '1111' then SEE PLD (literal) */ + if((res->fields[FIELD_Rn]) == (0xF)) { + + return pld_literal(req, res); + } + /* pcode: n = UInt(Rn) */ + res->fields[FIELD_n] = (res->fields[FIELD_Rn]); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: m = UInt(Rm) */ + res->fields[FIELD_m] = (res->fields[FIELD_Rm]); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + /* pcode: add = TRUE */ + res->fields[FIELD_add] = 1; + res->fields_mask[FIELD_add >> 6] |= 1LL << (FIELD_add & 63); + /* pcode: (shift_t, shift_n) = (SRType_LSL, UInt(imm2)) */ + res->fields[FIELD_shift_t] = 0; + res->fields_mask[FIELD_shift_t >> 6] |= 1LL << (FIELD_shift_t & 63); + res->fields[FIELD_shift_n] = (res->fields[FIELD_imm2]); + res->fields_mask[FIELD_shift_n >> 6] |= 1LL << (FIELD_shift_n & 63); + /* pcode: if BadReg(m) then UNPREDICTABLE */ + if(BadReg(res->fields[FIELD_m])) { + res->flags |= FLAG_UNPREDICTABLE; + } + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: E0F17E47 +int pli_immediate_literal(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + /* Encoding T1 */ + /* pattern="11111,00,1,1,00,1,Rn.4,1111,imm12.12" width=32 stringency=18 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFFF0F000)==0xF990F000)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_Rn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Rn >> 6] |= 1LL << (FIELD_Rn & 63); + char Rn_width = 4; + res->fields[FIELD_imm12] = instr & 0xFFF; + res->fields_mask[FIELD_imm12 >> 6] |= 1LL << (FIELD_imm12 & 63); + char imm12_width = 12; + + static const instruction_format instr_formats[] = + { + { /* PLI<c> [<Rn>,#<imm12>] */ + "pli", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_MEMORY_ONE_REG_IMM,FIELD_Rn,FIELD_imm12,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 1 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_PLI; + + /* pcode: n = UInt(Rn) */ + res->fields[FIELD_n] = (res->fields[FIELD_Rn]); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: imm32 = ZeroExtend(imm12, 32) */ + res->fields[FIELD_imm32] = res->fields[FIELD_imm12]; + res->fields_mask[FIELD_imm32 >> 6] |= 1LL << (FIELD_imm32 & 63); + /* pcode: add = TRUE */ + res->fields[FIELD_add] = 1; + res->fields_mask[FIELD_add >> 6] |= 1LL << (FIELD_add & 63); + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* Encoding T2 */ + /* pattern="11111,00,1,0,00,1,Rn.4,1111,1,100,imm8.8" width=32 stringency=20 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFFF0FF00)==0xF910FC00)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_Rn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Rn >> 6] |= 1LL << (FIELD_Rn & 63); + char Rn_width = 4; + res->fields[FIELD_imm8] = instr & 0xFF; + res->fields_mask[FIELD_imm8 >> 6] |= 1LL << (FIELD_imm8 & 63); + char imm8_width = 8; + + static const instruction_format instr_formats[] = + { + { /* PLI<c> [<Rn>,#-<imm8>] */ + "pli", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_MEMORY_ONE_REG_NEG_IMM,FIELD_Rn,FIELD_imm8,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 1 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_PLI; + + /* pcode: n = UInt(Rn) */ + res->fields[FIELD_n] = (res->fields[FIELD_Rn]); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: imm32 = ZeroExtend(imm8, 32) */ + res->fields[FIELD_imm32] = res->fields[FIELD_imm8]; + res->fields_mask[FIELD_imm32 >> 6] |= 1LL << (FIELD_imm32 & 63); + /* pcode: add = FALSE */ + res->fields[FIELD_add] = 0; + res->fields_mask[FIELD_add >> 6] |= 1LL << (FIELD_add & 63); + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* Encoding T3 */ + /* pattern="11111,00,1,U.1,00,1,1111,1111,imm12.12" width=32 stringency=22 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFF7FF000)==0xF91FF000)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_U] = (instr & 0x800000)>>23; + res->fields_mask[FIELD_U >> 6] |= 1LL << (FIELD_U & 63); + char U_width = 1; + res->fields[FIELD_imm12] = instr & 0xFFF; + res->fields_mask[FIELD_imm12 >> 6] |= 1LL << (FIELD_imm12 & 63); + char imm12_width = 12; + + static const instruction_format instr_formats[] = + { + { /* PLI<c> <label> */ + "pli", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_LABEL,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 1 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_PLI; + + /* pcode: n = 15 */ + res->fields[FIELD_n] = 15; + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: imm32 = ZeroExtend(imm12, 32) */ + res->fields[FIELD_imm32] = res->fields[FIELD_imm12]; + res->fields_mask[FIELD_imm32 >> 6] |= 1LL << (FIELD_imm32 & 63); + /* pcode: add = (U == '1') */ + res->fields[FIELD_add] = ((res->fields[FIELD_U]) == (0x1)); + res->fields_mask[FIELD_add >> 6] |= 1LL << (FIELD_add & 63); + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: 1FF4FF33 +int pli_register(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + /* Encoding T1 */ + /* pattern="11111,00,1,0,00,1,Rn.4,1111,0,00000,imm2.2,Rm.4" width=32 stringency=22 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFFF0FFC0)==0xF910F000)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_Rn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Rn >> 6] |= 1LL << (FIELD_Rn & 63); + char Rn_width = 4; + res->fields[FIELD_imm2] = (instr & 0x30)>>4; + res->fields_mask[FIELD_imm2 >> 6] |= 1LL << (FIELD_imm2 & 63); + char imm2_width = 2; + res->fields[FIELD_Rm] = instr & 0xF; + res->fields_mask[FIELD_Rm >> 6] |= 1LL << (FIELD_Rm & 63); + char Rm_width = 4; + + static const instruction_format instr_formats[] = + { + { /* PLI<c> [<Rn>,<Rm>{,<shift>}] */ + "pli", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_MEMORY_TWO_REG_SHIFT,FIELD_Rn,FIELD_Rm,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 1 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_PLI; + + /* pcode: if Rn == '1111' then SEE PLI (immediate, literal) */ + if((res->fields[FIELD_Rn]) == (0xF)) { + + return pli_immediate_literal(req, res); + } + /* pcode: n = UInt(Rn) */ + res->fields[FIELD_n] = (res->fields[FIELD_Rn]); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: m = UInt(Rm) */ + res->fields[FIELD_m] = (res->fields[FIELD_Rm]); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + /* pcode: add = TRUE */ + res->fields[FIELD_add] = 1; + res->fields_mask[FIELD_add >> 6] |= 1LL << (FIELD_add & 63); + /* pcode: (shift_t, shift_n) = (SRType_LSL, UInt(imm2)) */ + res->fields[FIELD_shift_t] = 0; + res->fields_mask[FIELD_shift_t >> 6] |= 1LL << (FIELD_shift_t & 63); + res->fields[FIELD_shift_n] = (res->fields[FIELD_imm2]); + res->fields_mask[FIELD_shift_n >> 6] |= 1LL << (FIELD_shift_n & 63); + /* pcode: if BadReg(m) then UNPREDICTABLE */ + if(BadReg(res->fields[FIELD_m])) { + res->flags |= FLAG_UNPREDICTABLE; + } + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: 3C8C61E3 +int pop(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + /* Encoding T1 */ + /* pattern="1011,1,10,P.1,register_list.8" width=16 stringency=8 */ + { + uint16_t instr = req->instr_word16; + if(((instr & 0xFE00)==0xBC00)) { + res->instrSize = 16; + if(!(req->arch & ARCH_ARMv4T) && !(req->arch & ARCH_ARMv5T) && !(req->arch & ARCH_ARMv6) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_P] = (instr & 0x100)>>8; + res->fields_mask[FIELD_P >> 6] |= 1LL << (FIELD_P & 63); + char P_width = 1; + res->fields[FIELD_register_list] = instr & 0xFF; + res->fields_mask[FIELD_register_list >> 6] |= 1LL << (FIELD_register_list & 63); + char register_list_width = 8; + + static const instruction_format instr_formats[] = + { + { /* POP<c> <registers> */ + "pop", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REGISTERS,FIELD_registers,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 1 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_POP; + + /* pcode: registers = P:'0000000':register_list */ + res->fields[FIELD_registers] = (res->fields[FIELD_P]<<(7+register_list_width))|(0x0<<register_list_width)|(res->fields[FIELD_register_list]); + res->fields_mask[FIELD_registers >> 6] |= 1LL << (FIELD_registers & 63); + /* pcode: if BitCount(registers) < 1 then UNPREDICTABLE */ + if((BitCount(res->fields[FIELD_registers])) < (1)) { + res->flags |= FLAG_UNPREDICTABLE; + } + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* Encoding T2 */ + /* pattern="11101,00,010,1,1,1101,P.1,M.1,(0),register_list.13" width=32 stringency=20 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFFFF0000)==0xE8BD0000)) { + res->instrSize = 32; + if(!((instr & 0x2000)==0x0)) { + res->flags |= FLAG_UNPREDICTABLE; + } + if(!(req->arch & ARCH_ARMv6T2) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_P] = (instr & 0x8000)>>15; + res->fields_mask[FIELD_P >> 6] |= 1LL << (FIELD_P & 63); + char P_width = 1; + res->fields[FIELD_M] = (instr & 0x4000)>>14; + res->fields_mask[FIELD_M >> 6] |= 1LL << (FIELD_M & 63); + char M_width = 1; + res->fields[FIELD_register_list] = instr & 0x1FFF; + res->fields_mask[FIELD_register_list >> 6] |= 1LL << (FIELD_register_list & 63); + char register_list_width = 13; + + static const instruction_format instr_formats[] = + { + { /* POP<c> <registers> */ + "pop", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REGISTERS,FIELD_registers,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 1 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_POP; + + /* pcode: registers = P:M:'0':register_list */ + res->fields[FIELD_registers] = (res->fields[FIELD_P]<<(1+register_list_width+M_width))|(res->fields[FIELD_M]<<(1+register_list_width))|(0x0<<register_list_width)|(res->fields[FIELD_register_list]); + res->fields_mask[FIELD_registers >> 6] |= 1LL << (FIELD_registers & 63); + /* pcode: if BitCount(registers) < 2 || (P == '1' && M == '1') then UNPREDICTABLE */ + if(((BitCount(res->fields[FIELD_registers])) < (2)) || ((((res->fields[FIELD_P]) == (0x1)) && ((res->fields[FIELD_M]) == (0x1))))) { + res->flags |= FLAG_UNPREDICTABLE; + } + /* pcode: if registers<15> == '1' && InITBlock() && !LastInITBlock() then UNPREDICTABLE */ + if(((((res->fields[FIELD_registers] & (1<<15)) >> 15) == (0x1)) && (req->inIfThen == IFTHEN_YES)) && (!(req->inIfThenLast == IFTHENLAST_YES))) { + res->flags |= FLAG_UNPREDICTABLE; + } + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* Encoding T3 */ + /* pattern="11111,00,0,0,10,1,1101,Rt.4,1,011,00000100" width=32 stringency=28 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFFFF0FFF)==0xF85D0B04)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ARMv6T2) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_Rt] = (instr & 0xF000)>>12; + res->fields_mask[FIELD_Rt >> 6] |= 1LL << (FIELD_Rt & 63); + char Rt_width = 4; + + static const instruction_format instr_formats[] = + { + { /* POP<c> <registers> */ + "pop", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REGISTERS,FIELD_registers,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 1 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_POP; + + /* pcode: t = UInt(Rt) */ + res->fields[FIELD_t] = (res->fields[FIELD_Rt]); + res->fields_mask[FIELD_t >> 6] |= 1LL << (FIELD_t & 63); + /* pcode: registers = Zeros(16) */ + res->fields[FIELD_registers] = /* 16-bit */ 0; + res->fields_mask[FIELD_registers >> 6] |= 1LL << (FIELD_registers & 63); + /* pcode: registers<t> = '1' */ + res->fields[FIELD_registers] |= (0x1 << res->fields[FIELD_t]); + res->fields_mask[FIELD_registers >> 6] |= 1LL << (FIELD_registers & 63); + /* pcode: if t == 13 || (t == 15 && InITBlock() && !LastInITBlock()) then UNPREDICTABLE */ + if(((res->fields[FIELD_t]) == (13)) || (((((res->fields[FIELD_t]) == (15)) && (req->inIfThen == IFTHEN_YES)) && (!(req->inIfThenLast == IFTHENLAST_YES))))) { + res->flags |= FLAG_UNPREDICTABLE; + } + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: 6D631478 +int push(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + /* Encoding T1 */ + /* pattern="1011,0,10,M.1,register_list.8" width=16 stringency=8 */ + { + uint16_t instr = req->instr_word16; + if(((instr & 0xFE00)==0xB400)) { + res->instrSize = 16; + if(!(req->arch & ARCH_ARMv4T) && !(req->arch & ARCH_ARMv5T) && !(req->arch & ARCH_ARMv6) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_M] = (instr & 0x100)>>8; + res->fields_mask[FIELD_M >> 6] |= 1LL << (FIELD_M & 63); + char M_width = 1; + res->fields[FIELD_register_list] = instr & 0xFF; + res->fields_mask[FIELD_register_list >> 6] |= 1LL << (FIELD_register_list & 63); + char register_list_width = 8; + + static const instruction_format instr_formats[] = + { + { /* PUSH<c> <registers> */ + "push", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REGISTERS,FIELD_registers,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 1 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_PUSH; + + /* pcode: registers = '0':M:'000000':register_list */ + res->fields[FIELD_registers] = (0x0<<(6+register_list_width+M_width))|(res->fields[FIELD_M]<<(6+register_list_width))|(0x0<<register_list_width)|(res->fields[FIELD_register_list]); + res->fields_mask[FIELD_registers >> 6] |= 1LL << (FIELD_registers & 63); + /* pcode: if BitCount(registers) < 1 then UNPREDICTABLE */ + if((BitCount(res->fields[FIELD_registers])) < (1)) { + res->flags |= FLAG_UNPREDICTABLE; + } + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* Encoding T2 */ + /* pattern="11101,00,xx0,1,0,1101,(0),M.1,(0),register_list.13" width=32 stringency=18 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFE7F0000)==0xE82D0000)) { + res->instrSize = 32; + if(!((instr & 0xA000)==0x0)) { + res->flags |= FLAG_UNPREDICTABLE; + } + if(!(req->arch & ARCH_ARMv6T2) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_M] = (instr & 0x4000)>>14; + res->fields_mask[FIELD_M >> 6] |= 1LL << (FIELD_M & 63); + char M_width = 1; + res->fields[FIELD_register_list] = instr & 0x1FFF; + res->fields_mask[FIELD_register_list >> 6] |= 1LL << (FIELD_register_list & 63); + char register_list_width = 13; + + static const instruction_format instr_formats[] = + { + { /* PUSH<c> <registers> */ + "push", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REGISTERS,FIELD_registers,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 1 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_PUSH; + + /* pcode: registers = '0':M:'0':register_list */ + res->fields[FIELD_registers] = (0x0<<(1+register_list_width+M_width))|(res->fields[FIELD_M]<<(1+register_list_width))|(0x0<<register_list_width)|(res->fields[FIELD_register_list]); + res->fields_mask[FIELD_registers >> 6] |= 1LL << (FIELD_registers & 63); + /* pcode: if BitCount(registers) < 2 then UNPREDICTABLE */ + if((BitCount(res->fields[FIELD_registers])) < (2)) { + res->flags |= FLAG_UNPREDICTABLE; + } + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* Encoding T3 */ + /* pattern="11111,00,0,0,10,0,1101,Rt.4,1,101,00000100" width=32 stringency=28 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFFFF0FFF)==0xF84D0D04)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ARMv6T2) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_Rt] = (instr & 0xF000)>>12; + res->fields_mask[FIELD_Rt >> 6] |= 1LL << (FIELD_Rt & 63); + char Rt_width = 4; + + static const instruction_format instr_formats[] = + { + { /* PUSH<c> <registers> */ + "push", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REGISTERS,FIELD_registers,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 1 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_PUSH; + + /* pcode: t = UInt(Rt) */ + res->fields[FIELD_t] = (res->fields[FIELD_Rt]); + res->fields_mask[FIELD_t >> 6] |= 1LL << (FIELD_t & 63); + /* pcode: registers = Zeros(16) */ + res->fields[FIELD_registers] = /* 16-bit */ 0; + res->fields_mask[FIELD_registers >> 6] |= 1LL << (FIELD_registers & 63); + /* pcode: registers<t> = '1' */ + res->fields[FIELD_registers] |= (0x1 << res->fields[FIELD_t]); + res->fields_mask[FIELD_registers >> 6] |= 1LL << (FIELD_registers & 63); + /* pcode: if BadReg(t) then UNPREDICTABLE */ + if(BadReg(res->fields[FIELD_t])) { + res->flags |= FLAG_UNPREDICTABLE; + } + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: D009E097 +int qadd(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + /* Encoding T1 */ + /* pattern="11111,010,1,000,Rn.4,1111,Rd.4,1,000,Rm.4" width=32 stringency=20 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFFF0F0F0)==0xFA80F080)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ARMv6T2) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_Rn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Rn >> 6] |= 1LL << (FIELD_Rn & 63); + char Rn_width = 4; + res->fields[FIELD_Rd] = (instr & 0xF00)>>8; + res->fields_mask[FIELD_Rd >> 6] |= 1LL << (FIELD_Rd & 63); + char Rd_width = 4; + res->fields[FIELD_Rm] = instr & 0xF; + res->fields_mask[FIELD_Rm >> 6] |= 1LL << (FIELD_Rm & 63); + char Rm_width = 4; + + static const instruction_format instr_formats[] = + { + { /* QADD<c> <Rd>,<Rm>,<Rn> */ + "qadd", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rd,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rm,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rn,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_QADD; + + /* pcode: d = UInt(Rd) */ + res->fields[FIELD_d] = (res->fields[FIELD_Rd]); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: n = UInt(Rn) */ + res->fields[FIELD_n] = (res->fields[FIELD_Rn]); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: m = UInt(Rm) */ + res->fields[FIELD_m] = (res->fields[FIELD_Rm]); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + /* pcode: if BadReg(d) || BadReg(n) || BadReg(m) then UNPREDICTABLE */ + if(((BadReg(res->fields[FIELD_d])) || (BadReg(res->fields[FIELD_n]))) || (BadReg(res->fields[FIELD_m]))) { + res->flags |= FLAG_UNPREDICTABLE; + } + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: 8E13444B +int qadd16(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + /* Encoding T1 */ + /* pattern="11111,010,1,001,Rn.4,1111,Rd.4,0,001,Rm.4" width=32 stringency=20 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFFF0F0F0)==0xFA90F010)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ARMv6T2) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_Rn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Rn >> 6] |= 1LL << (FIELD_Rn & 63); + char Rn_width = 4; + res->fields[FIELD_Rd] = (instr & 0xF00)>>8; + res->fields_mask[FIELD_Rd >> 6] |= 1LL << (FIELD_Rd & 63); + char Rd_width = 4; + res->fields[FIELD_Rm] = instr & 0xF; + res->fields_mask[FIELD_Rm >> 6] |= 1LL << (FIELD_Rm & 63); + char Rm_width = 4; + + static const instruction_format instr_formats[] = + { + { /* QADD16<c> <Rd>,<Rn>,<Rm> */ + "qadd16", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rd,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rn,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rm,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_QADD16; + + /* pcode: d = UInt(Rd) */ + res->fields[FIELD_d] = (res->fields[FIELD_Rd]); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: n = UInt(Rn) */ + res->fields[FIELD_n] = (res->fields[FIELD_Rn]); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: m = UInt(Rm) */ + res->fields[FIELD_m] = (res->fields[FIELD_Rm]); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + /* pcode: if BadReg(d) || BadReg(n) || BadReg(m) then UNPREDICTABLE */ + if(((BadReg(res->fields[FIELD_d])) || (BadReg(res->fields[FIELD_n]))) || (BadReg(res->fields[FIELD_m]))) { + res->flags |= FLAG_UNPREDICTABLE; + } + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: C80D5988 +int qadd8(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + /* Encoding T1 */ + /* pattern="11111,010,1,000,Rn.4,1111,Rd.4,0,001,Rm.4" width=32 stringency=20 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFFF0F0F0)==0xFA80F010)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ARMv6T2) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_Rn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Rn >> 6] |= 1LL << (FIELD_Rn & 63); + char Rn_width = 4; + res->fields[FIELD_Rd] = (instr & 0xF00)>>8; + res->fields_mask[FIELD_Rd >> 6] |= 1LL << (FIELD_Rd & 63); + char Rd_width = 4; + res->fields[FIELD_Rm] = instr & 0xF; + res->fields_mask[FIELD_Rm >> 6] |= 1LL << (FIELD_Rm & 63); + char Rm_width = 4; + + static const instruction_format instr_formats[] = + { + { /* QADD8<c> <Rd>,<Rn>,<Rm> */ + "qadd8", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rd,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rn,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rm,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_QADD8; + + /* pcode: d = UInt(Rd) */ + res->fields[FIELD_d] = (res->fields[FIELD_Rd]); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: n = UInt(Rn) */ + res->fields[FIELD_n] = (res->fields[FIELD_Rn]); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: m = UInt(Rm) */ + res->fields[FIELD_m] = (res->fields[FIELD_Rm]); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + /* pcode: if BadReg(d) || BadReg(n) || BadReg(m) then UNPREDICTABLE */ + if(((BadReg(res->fields[FIELD_d])) || (BadReg(res->fields[FIELD_n]))) || (BadReg(res->fields[FIELD_m]))) { + res->flags |= FLAG_UNPREDICTABLE; + } + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: 2DDA4794 +int qasx(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + /* Encoding T1 */ + /* pattern="11111,010,1,010,Rn.4,1111,Rd.4,0,001,Rm.4" width=32 stringency=20 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFFF0F0F0)==0xFAA0F010)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ARMv6T2) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_Rn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Rn >> 6] |= 1LL << (FIELD_Rn & 63); + char Rn_width = 4; + res->fields[FIELD_Rd] = (instr & 0xF00)>>8; + res->fields_mask[FIELD_Rd >> 6] |= 1LL << (FIELD_Rd & 63); + char Rd_width = 4; + res->fields[FIELD_Rm] = instr & 0xF; + res->fields_mask[FIELD_Rm >> 6] |= 1LL << (FIELD_Rm & 63); + char Rm_width = 4; + + static const instruction_format instr_formats[] = + { + { /* QASX<c> <Rd>,<Rn>,<Rm> */ + "qasx", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rd,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rn,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rm,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_QASX; + + /* pcode: d = UInt(Rd) */ + res->fields[FIELD_d] = (res->fields[FIELD_Rd]); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: n = UInt(Rn) */ + res->fields[FIELD_n] = (res->fields[FIELD_Rn]); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: m = UInt(Rm) */ + res->fields[FIELD_m] = (res->fields[FIELD_Rm]); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + /* pcode: if BadReg(d) || BadReg(n) || BadReg(m) then UNPREDICTABLE */ + if(((BadReg(res->fields[FIELD_d])) || (BadReg(res->fields[FIELD_n]))) || (BadReg(res->fields[FIELD_m]))) { + res->flags |= FLAG_UNPREDICTABLE; + } + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: 25DEF501 +int qdadd(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + /* Encoding T1 */ + /* pattern="11111,010,1,000,Rn.4,1111,Rd.4,1,001,Rm.4" width=32 stringency=20 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFFF0F0F0)==0xFA80F090)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ARMv6T2) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_Rn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Rn >> 6] |= 1LL << (FIELD_Rn & 63); + char Rn_width = 4; + res->fields[FIELD_Rd] = (instr & 0xF00)>>8; + res->fields_mask[FIELD_Rd >> 6] |= 1LL << (FIELD_Rd & 63); + char Rd_width = 4; + res->fields[FIELD_Rm] = instr & 0xF; + res->fields_mask[FIELD_Rm >> 6] |= 1LL << (FIELD_Rm & 63); + char Rm_width = 4; + + static const instruction_format instr_formats[] = + { + { /* QDADD<c> <Rd>,<Rm>,<Rn> */ + "qdadd", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rd,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rm,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rn,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_QDADD; + + /* pcode: d = UInt(Rd) */ + res->fields[FIELD_d] = (res->fields[FIELD_Rd]); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: n = UInt(Rn) */ + res->fields[FIELD_n] = (res->fields[FIELD_Rn]); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: m = UInt(Rm) */ + res->fields[FIELD_m] = (res->fields[FIELD_Rm]); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + /* pcode: if BadReg(d) || BadReg(n) || BadReg(m) then UNPREDICTABLE */ + if(((BadReg(res->fields[FIELD_d])) || (BadReg(res->fields[FIELD_n]))) || (BadReg(res->fields[FIELD_m]))) { + res->flags |= FLAG_UNPREDICTABLE; + } + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: A09CDBDD +int qdsub(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + /* Encoding T1 */ + /* pattern="11111,010,1,000,Rn.4,1111,Rd.4,1,011,Rm.4" width=32 stringency=20 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFFF0F0F0)==0xFA80F0B0)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ARMv6T2) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_Rn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Rn >> 6] |= 1LL << (FIELD_Rn & 63); + char Rn_width = 4; + res->fields[FIELD_Rd] = (instr & 0xF00)>>8; + res->fields_mask[FIELD_Rd >> 6] |= 1LL << (FIELD_Rd & 63); + char Rd_width = 4; + res->fields[FIELD_Rm] = instr & 0xF; + res->fields_mask[FIELD_Rm >> 6] |= 1LL << (FIELD_Rm & 63); + char Rm_width = 4; + + static const instruction_format instr_formats[] = + { + { /* QDSUB<c> <Rd>,<Rm>,<Rn> */ + "qdsub", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rd,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rm,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rn,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_QDSUB; + + /* pcode: d = UInt(Rd) */ + res->fields[FIELD_d] = (res->fields[FIELD_Rd]); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: n = UInt(Rn) */ + res->fields[FIELD_n] = (res->fields[FIELD_Rn]); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: m = UInt(Rm) */ + res->fields[FIELD_m] = (res->fields[FIELD_Rm]); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + /* pcode: if BadReg(d) || BadReg(n) || BadReg(m) then UNPREDICTABLE */ + if(((BadReg(res->fields[FIELD_d])) || (BadReg(res->fields[FIELD_n]))) || (BadReg(res->fields[FIELD_m]))) { + res->flags |= FLAG_UNPREDICTABLE; + } + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: D349E767 +int qsax(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + /* Encoding T1 */ + /* pattern="11111,010,1,110,Rn.4,1111,Rd.4,0,001,Rm.4" width=32 stringency=20 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFFF0F0F0)==0xFAE0F010)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ARMv6T2) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_Rn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Rn >> 6] |= 1LL << (FIELD_Rn & 63); + char Rn_width = 4; + res->fields[FIELD_Rd] = (instr & 0xF00)>>8; + res->fields_mask[FIELD_Rd >> 6] |= 1LL << (FIELD_Rd & 63); + char Rd_width = 4; + res->fields[FIELD_Rm] = instr & 0xF; + res->fields_mask[FIELD_Rm >> 6] |= 1LL << (FIELD_Rm & 63); + char Rm_width = 4; + + static const instruction_format instr_formats[] = + { + { /* QSAX<c> <Rd>,<Rn>,<Rm> */ + "qsax", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rd,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rn,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rm,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_QSAX; + + /* pcode: d = UInt(Rd) */ + res->fields[FIELD_d] = (res->fields[FIELD_Rd]); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: n = UInt(Rn) */ + res->fields[FIELD_n] = (res->fields[FIELD_Rn]); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: m = UInt(Rm) */ + res->fields[FIELD_m] = (res->fields[FIELD_Rm]); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + /* pcode: if BadReg(d) || BadReg(n) || BadReg(m) then UNPREDICTABLE */ + if(((BadReg(res->fields[FIELD_d])) || (BadReg(res->fields[FIELD_n]))) || (BadReg(res->fields[FIELD_m]))) { + res->flags |= FLAG_UNPREDICTABLE; + } + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: 554BCE4B +int qsub(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + /* Encoding T1 */ + /* pattern="11111,010,1,000,Rn.4,1111,Rd.4,1,010,Rm.4" width=32 stringency=20 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFFF0F0F0)==0xFA80F0A0)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ARMv6T2) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_Rn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Rn >> 6] |= 1LL << (FIELD_Rn & 63); + char Rn_width = 4; + res->fields[FIELD_Rd] = (instr & 0xF00)>>8; + res->fields_mask[FIELD_Rd >> 6] |= 1LL << (FIELD_Rd & 63); + char Rd_width = 4; + res->fields[FIELD_Rm] = instr & 0xF; + res->fields_mask[FIELD_Rm >> 6] |= 1LL << (FIELD_Rm & 63); + char Rm_width = 4; + + static const instruction_format instr_formats[] = + { + { /* QSUB<c> <Rd>,<Rm>,<Rn> */ + "qsub", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rd,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rm,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rn,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_QSUB; + + /* pcode: d = UInt(Rd) */ + res->fields[FIELD_d] = (res->fields[FIELD_Rd]); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: n = UInt(Rn) */ + res->fields[FIELD_n] = (res->fields[FIELD_Rn]); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: m = UInt(Rm) */ + res->fields[FIELD_m] = (res->fields[FIELD_Rm]); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + /* pcode: if BadReg(d) || BadReg(n) || BadReg(m) then UNPREDICTABLE */ + if(((BadReg(res->fields[FIELD_d])) || (BadReg(res->fields[FIELD_n]))) || (BadReg(res->fields[FIELD_m]))) { + res->flags |= FLAG_UNPREDICTABLE; + } + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: C8710F32 +int qsub16(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + /* Encoding T1 */ + /* pattern="11111,010,1,101,Rn.4,1111,Rd.4,0,001,Rm.4" width=32 stringency=20 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFFF0F0F0)==0xFAD0F010)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ARMv6T2) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_Rn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Rn >> 6] |= 1LL << (FIELD_Rn & 63); + char Rn_width = 4; + res->fields[FIELD_Rd] = (instr & 0xF00)>>8; + res->fields_mask[FIELD_Rd >> 6] |= 1LL << (FIELD_Rd & 63); + char Rd_width = 4; + res->fields[FIELD_Rm] = instr & 0xF; + res->fields_mask[FIELD_Rm >> 6] |= 1LL << (FIELD_Rm & 63); + char Rm_width = 4; + + static const instruction_format instr_formats[] = + { + { /* QSUB16<c> <Rd>,<Rn>,<Rm> */ + "qsub16", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rd,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rn,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rm,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_QSUB16; + + /* pcode: d = UInt(Rd) */ + res->fields[FIELD_d] = (res->fields[FIELD_Rd]); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: n = UInt(Rn) */ + res->fields[FIELD_n] = (res->fields[FIELD_Rn]); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: m = UInt(Rm) */ + res->fields[FIELD_m] = (res->fields[FIELD_Rm]); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + /* pcode: if BadReg(d) || BadReg(n) || BadReg(m) then UNPREDICTABLE */ + if(((BadReg(res->fields[FIELD_d])) || (BadReg(res->fields[FIELD_n]))) || (BadReg(res->fields[FIELD_m]))) { + res->flags |= FLAG_UNPREDICTABLE; + } + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: CDC40997 +int qsub8(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + /* Encoding T1 */ + /* pattern="11111,010,1,100,Rn.4,1111,Rd.4,0,001,Rm.4" width=32 stringency=20 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFFF0F0F0)==0xFAC0F010)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ARMv6T2) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_Rn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Rn >> 6] |= 1LL << (FIELD_Rn & 63); + char Rn_width = 4; + res->fields[FIELD_Rd] = (instr & 0xF00)>>8; + res->fields_mask[FIELD_Rd >> 6] |= 1LL << (FIELD_Rd & 63); + char Rd_width = 4; + res->fields[FIELD_Rm] = instr & 0xF; + res->fields_mask[FIELD_Rm >> 6] |= 1LL << (FIELD_Rm & 63); + char Rm_width = 4; + + static const instruction_format instr_formats[] = + { + { /* QSUB8<c> <Rd>,<Rn>,<Rm> */ + "qsub8", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rd,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rn,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rm,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_QSUB8; + + /* pcode: d = UInt(Rd) */ + res->fields[FIELD_d] = (res->fields[FIELD_Rd]); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: n = UInt(Rn) */ + res->fields[FIELD_n] = (res->fields[FIELD_Rn]); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: m = UInt(Rm) */ + res->fields[FIELD_m] = (res->fields[FIELD_Rm]); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + /* pcode: if BadReg(d) || BadReg(n) || BadReg(m) then UNPREDICTABLE */ + if(((BadReg(res->fields[FIELD_d])) || (BadReg(res->fields[FIELD_n]))) || (BadReg(res->fields[FIELD_m]))) { + res->flags |= FLAG_UNPREDICTABLE; + } + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: D4F1A733 +int rbit(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + /* Encoding T1 */ + /* pattern="11111,010,1,001,Rm.4,1111,Rd.4,1,010,Rm.4" width=32 stringency=20 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFFF0F0F0)==0xFA90F0A0)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ARMv6T2) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_Rm] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Rm >> 6] |= 1LL << (FIELD_Rm & 63); + char Rm_width = 4; + res->fields[FIELD_Rd] = (instr & 0xF00)>>8; + res->fields_mask[FIELD_Rd >> 6] |= 1LL << (FIELD_Rd & 63); + char Rd_width = 4; + res->fields[FIELD_Rm_check] = instr & 0xF; + res->fields_mask[FIELD_Rm_check >> 6] |= 1LL << (FIELD_Rm_check & 63); + char Rm_check_width = 4; + + static const instruction_format instr_formats[] = + { + { /* RBIT<c> <Rd>,<Rm> */ + "rbit", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rd,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rm,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_RBIT; + + /* pcode: if !Consistent(Rm) then UNPREDICTABLE */ + if(!((res->fields[FIELD_Rm] == res->fields[FIELD_Rm_check]))) { + res->flags |= FLAG_UNPREDICTABLE; + } + /* pcode: d = UInt(Rd) */ + res->fields[FIELD_d] = (res->fields[FIELD_Rd]); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: m = UInt(Rm) */ + res->fields[FIELD_m] = (res->fields[FIELD_Rm]); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + /* pcode: if BadReg(d) || BadReg(m) then UNPREDICTABLE */ + if((BadReg(res->fields[FIELD_d])) || (BadReg(res->fields[FIELD_m]))) { + res->flags |= FLAG_UNPREDICTABLE; + } + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: 4D049644 +int rev(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + /* Encoding T1 */ + /* pattern="1011,1010,00,Rm.3,Rd.3" width=16 stringency=10 */ + { + uint16_t instr = req->instr_word16; + if(((instr & 0xFFC0)==0xBA00)) { + res->instrSize = 16; + if(!(req->arch & ARCH_ARMv6) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_Rm] = (instr & 0x38)>>3; + res->fields_mask[FIELD_Rm >> 6] |= 1LL << (FIELD_Rm & 63); + char Rm_width = 3; + res->fields[FIELD_Rd] = instr & 0x7; + res->fields_mask[FIELD_Rd >> 6] |= 1LL << (FIELD_Rd & 63); + char Rd_width = 3; + + static const instruction_format instr_formats[] = + { + { /* REV<c> <Rd>,<Rm> */ + "rev", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rd,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rm,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_REV; + + /* pcode: d = UInt(Rd) */ + res->fields[FIELD_d] = (res->fields[FIELD_Rd]); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: m = UInt(Rm) */ + res->fields[FIELD_m] = (res->fields[FIELD_Rm]); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* Encoding T2 */ + /* pattern="11111,010,1,001,Rm.4,1111,Rd.4,1,000,Rm.4" width=32 stringency=20 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFFF0F0F0)==0xFA90F080)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ARMv6) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_Rm] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Rm >> 6] |= 1LL << (FIELD_Rm & 63); + char Rm_width = 4; + res->fields[FIELD_Rd] = (instr & 0xF00)>>8; + res->fields_mask[FIELD_Rd >> 6] |= 1LL << (FIELD_Rd & 63); + char Rd_width = 4; + res->fields[FIELD_Rm_check] = instr & 0xF; + res->fields_mask[FIELD_Rm_check >> 6] |= 1LL << (FIELD_Rm_check & 63); + char Rm_check_width = 4; + + static const instruction_format instr_formats[] = + { + { /* REV<c>.W <Rd>,<Rm> */ + "rev", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_WIDE, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rd,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rm,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_REV; + + /* pcode: if !Consistent(Rm) then UNPREDICTABLE */ + if(!((res->fields[FIELD_Rm] == res->fields[FIELD_Rm_check]))) { + res->flags |= FLAG_UNPREDICTABLE; + } + /* pcode: d = UInt(Rd) */ + res->fields[FIELD_d] = (res->fields[FIELD_Rd]); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: m = UInt(Rm) */ + res->fields[FIELD_m] = (res->fields[FIELD_Rm]); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + /* pcode: if BadReg(d) || BadReg(m) then UNPREDICTABLE */ + if((BadReg(res->fields[FIELD_d])) || (BadReg(res->fields[FIELD_m]))) { + res->flags |= FLAG_UNPREDICTABLE; + } + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: D9A8582E +int rev16(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + /* Encoding T1 */ + /* pattern="1011,1010,01,Rm.3,Rd.3" width=16 stringency=10 */ + { + uint16_t instr = req->instr_word16; + if(((instr & 0xFFC0)==0xBA40)) { + res->instrSize = 16; + if(!(req->arch & ARCH_ARMv6) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_Rm] = (instr & 0x38)>>3; + res->fields_mask[FIELD_Rm >> 6] |= 1LL << (FIELD_Rm & 63); + char Rm_width = 3; + res->fields[FIELD_Rd] = instr & 0x7; + res->fields_mask[FIELD_Rd >> 6] |= 1LL << (FIELD_Rd & 63); + char Rd_width = 3; + + static const instruction_format instr_formats[] = + { + { /* REV16<c> <Rd>,<Rm> */ + "rev16", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rd,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rm,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_REV16; + + /* pcode: d = UInt(Rd) */ + res->fields[FIELD_d] = (res->fields[FIELD_Rd]); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: m = UInt(Rm) */ + res->fields[FIELD_m] = (res->fields[FIELD_Rm]); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* Encoding T2 */ + /* pattern="11111,010,1,001,Rm.4,1111,Rd.4,1,001,Rm.4" width=32 stringency=20 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFFF0F0F0)==0xFA90F090)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ARMv6T2) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_Rm] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Rm >> 6] |= 1LL << (FIELD_Rm & 63); + char Rm_width = 4; + res->fields[FIELD_Rd] = (instr & 0xF00)>>8; + res->fields_mask[FIELD_Rd >> 6] |= 1LL << (FIELD_Rd & 63); + char Rd_width = 4; + res->fields[FIELD_Rm_check] = instr & 0xF; + res->fields_mask[FIELD_Rm_check >> 6] |= 1LL << (FIELD_Rm_check & 63); + char Rm_check_width = 4; + + static const instruction_format instr_formats[] = + { + { /* REV16<c>.W <Rd>,<Rm> */ + "rev16", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_WIDE, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rd,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rm,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_REV16; + + /* pcode: if !Consistent(Rm) then UNPREDICTABLE */ + if(!((res->fields[FIELD_Rm] == res->fields[FIELD_Rm_check]))) { + res->flags |= FLAG_UNPREDICTABLE; + } + /* pcode: d = UInt(Rd) */ + res->fields[FIELD_d] = (res->fields[FIELD_Rd]); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: m = UInt(Rm) */ + res->fields[FIELD_m] = (res->fields[FIELD_Rm]); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + /* pcode: if BadReg(d) || BadReg(m) then UNPREDICTABLE */ + if((BadReg(res->fields[FIELD_d])) || (BadReg(res->fields[FIELD_m]))) { + res->flags |= FLAG_UNPREDICTABLE; + } + /* pcode: nop */ + while(0); + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: C1570AB5 +int revsh(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + /* Encoding T1 */ + /* pattern="1011,1010,11,Rm.3,Rd.3" width=16 stringency=10 */ + { + uint16_t instr = req->instr_word16; + if(((instr & 0xFFC0)==0xBAC0)) { + res->instrSize = 16; + if(!(req->arch & ARCH_ARMv6) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_Rm] = (instr & 0x38)>>3; + res->fields_mask[FIELD_Rm >> 6] |= 1LL << (FIELD_Rm & 63); + char Rm_width = 3; + res->fields[FIELD_Rd] = instr & 0x7; + res->fields_mask[FIELD_Rd >> 6] |= 1LL << (FIELD_Rd & 63); + char Rd_width = 3; + + static const instruction_format instr_formats[] = + { + { /* REVSH<c> <Rd>,<Rm> */ + "revsh", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rd,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rm,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_REVSH; + + /* pcode: d = UInt(Rd) */ + res->fields[FIELD_d] = (res->fields[FIELD_Rd]); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: m = UInt(Rm) */ + res->fields[FIELD_m] = (res->fields[FIELD_Rm]); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* Encoding T2 */ + /* pattern="11111,010,1,001,Rm.4,1111,Rd.4,1,011,Rm.4" width=32 stringency=20 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFFF0F0F0)==0xFA90F0B0)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ARMv6T2) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_Rm] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Rm >> 6] |= 1LL << (FIELD_Rm & 63); + char Rm_width = 4; + res->fields[FIELD_Rd] = (instr & 0xF00)>>8; + res->fields_mask[FIELD_Rd >> 6] |= 1LL << (FIELD_Rd & 63); + char Rd_width = 4; + res->fields[FIELD_Rm_check] = instr & 0xF; + res->fields_mask[FIELD_Rm_check >> 6] |= 1LL << (FIELD_Rm_check & 63); + char Rm_check_width = 4; + + static const instruction_format instr_formats[] = + { + { /* REVSH<c>.W <Rd>,<Rm> */ + "revsh", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_WIDE, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rd,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rm,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_REVSH; + + /* pcode: if !Consistent(Rm) then UNPREDICTABLE */ + if(!((res->fields[FIELD_Rm] == res->fields[FIELD_Rm_check]))) { + res->flags |= FLAG_UNPREDICTABLE; + } + /* pcode: d = UInt(Rd) */ + res->fields[FIELD_d] = (res->fields[FIELD_Rd]); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: m = UInt(Rm) */ + res->fields[FIELD_m] = (res->fields[FIELD_Rm]); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + /* pcode: if BadReg(d) || BadReg(m) then UNPREDICTABLE */ + if((BadReg(res->fields[FIELD_d])) || (BadReg(res->fields[FIELD_m]))) { + res->flags |= FLAG_UNPREDICTABLE; + } + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: 003CFCB6 +int rfe(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + /* Encoding T1 */ + /* pattern="11101,00,00,0,W.1,1,Rn.4,(1)(1),(0)(0)(0)(0)(0)(0)(0)(0)(0)(0)(0)(0)(0)(0)" width=32 stringency=28 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFFD00000)==0xE8100000)) { + res->instrSize = 32; + if(!((instr & 0xFFFF)==0xC000)) { + res->flags |= FLAG_UNPREDICTABLE; + } + if(!(req->arch & ARCH_ARMv6T2) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_W] = (instr & 0x200000)>>21; + res->fields_mask[FIELD_W >> 6] |= 1LL << (FIELD_W & 63); + char W_width = 1; + res->fields[FIELD_Rn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Rn >> 6] |= 1LL << (FIELD_Rn & 63); + char Rn_width = 4; + + static const instruction_format instr_formats[] = + { + { /* RFEDB<c> <Rn>{!} */ + "rfedb", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rn,FIELD_UNINIT,"","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 1 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_RFEDB; + + /* pcode: n = UInt(Rn) */ + res->fields[FIELD_n] = (res->fields[FIELD_Rn]); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: wback = (W == '1') */ + res->fields[FIELD_wback] = ((res->fields[FIELD_W]) == (0x1)); + res->fields_mask[FIELD_wback >> 6] |= 1LL << (FIELD_wback & 63); + /* pcode: increment = FALSE */ + res->fields[FIELD_increment] = 0; + res->fields_mask[FIELD_increment >> 6] |= 1LL << (FIELD_increment & 63); + /* pcode: wordhigher = FALSE */ + res->fields[FIELD_wordhigher] = 0; + res->fields_mask[FIELD_wordhigher >> 6] |= 1LL << (FIELD_wordhigher & 63); + /* pcode: if n == 15 then UNPREDICTABLE */ + if((res->fields[FIELD_n]) == (15)) { + res->flags |= FLAG_UNPREDICTABLE; + } + /* pcode: if InITBlock() && !LastInITBlock() then UNPREDICTABLE */ + if((req->inIfThen == IFTHEN_YES) && (!(req->inIfThenLast == IFTHENLAST_YES))) { + res->flags |= FLAG_UNPREDICTABLE; + } + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* Encoding T2 */ + /* pattern="11101,00,11,0,W.1,1,Rn.4,(1)(1),(0)(0)(0)(0)(0)(0)(0)(0)(0)(0)(0)(0)(0)(0)" width=32 stringency=28 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFFD00000)==0xE9900000)) { + res->instrSize = 32; + if(!((instr & 0xFFFF)==0xC000)) { + res->flags |= FLAG_UNPREDICTABLE; + } + if(!(req->arch & ARCH_ARMv6T2) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_W] = (instr & 0x200000)>>21; + res->fields_mask[FIELD_W >> 6] |= 1LL << (FIELD_W & 63); + char W_width = 1; + res->fields[FIELD_Rn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Rn >> 6] |= 1LL << (FIELD_Rn & 63); + char Rn_width = 4; + + static const instruction_format instr_formats[] = + { + { /* RFE{IA}<c> <Rn>{!} */ + "rfe", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_INCREMENT_AFTER, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rn,FIELD_UNINIT,"","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 1 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_RFE; + + /* pcode: n = UInt(Rn) */ + res->fields[FIELD_n] = (res->fields[FIELD_Rn]); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: wback = (W == '1') */ + res->fields[FIELD_wback] = ((res->fields[FIELD_W]) == (0x1)); + res->fields_mask[FIELD_wback >> 6] |= 1LL << (FIELD_wback & 63); + /* pcode: increment = TRUE */ + res->fields[FIELD_increment] = 1; + res->fields_mask[FIELD_increment >> 6] |= 1LL << (FIELD_increment & 63); + /* pcode: wordhigher = FALSE */ + res->fields[FIELD_wordhigher] = 0; + res->fields_mask[FIELD_wordhigher >> 6] |= 1LL << (FIELD_wordhigher & 63); + /* pcode: if n == 15 then UNPREDICTABLE */ + if((res->fields[FIELD_n]) == (15)) { + res->flags |= FLAG_UNPREDICTABLE; + } + /* pcode: if InITBlock() && !LastInITBlock() then UNPREDICTABLE */ + if((req->inIfThen == IFTHEN_YES) && (!(req->inIfThenLast == IFTHENLAST_YES))) { + res->flags |= FLAG_UNPREDICTABLE; + } + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* Encoding A1 */ + /* pattern="1111,100,P.1,U.1,0,W.1,1,Rn.4,(0)(0)(0)(0),(1)(0)(1)(0),(0)(0)(0)(0)(0)(0)(0)(0)" width=32 stringency=28 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFE500000)==0xF8100000)) { + res->instrSize = 32; + if(!((instr & 0xFFFF)==0xA00)) { + res->flags |= FLAG_UNPREDICTABLE; + } + if(!(req->arch & ARCH_ARMv6) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_P] = (instr & 0x1000000)>>24; + res->fields_mask[FIELD_P >> 6] |= 1LL << (FIELD_P & 63); + char P_width = 1; + res->fields[FIELD_U] = (instr & 0x800000)>>23; + res->fields_mask[FIELD_U >> 6] |= 1LL << (FIELD_U & 63); + char U_width = 1; + res->fields[FIELD_W] = (instr & 0x200000)>>21; + res->fields_mask[FIELD_W >> 6] |= 1LL << (FIELD_W & 63); + char W_width = 1; + res->fields[FIELD_Rn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Rn >> 6] |= 1LL << (FIELD_Rn & 63); + char Rn_width = 4; + + static const instruction_format instr_formats[] = + { + { /* RFE{<amode>} <Rn>{!} */ + "rfe", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_AMODE, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rn,FIELD_UNINIT,"","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 1 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_RFE; + + /* pcode: n = UInt(Rn) */ + res->fields[FIELD_n] = (res->fields[FIELD_Rn]); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: wback = (W == '1') */ + res->fields[FIELD_wback] = ((res->fields[FIELD_W]) == (0x1)); + res->fields_mask[FIELD_wback >> 6] |= 1LL << (FIELD_wback & 63); + /* pcode: inc = (U == '1') */ + res->fields[FIELD_inc] = ((res->fields[FIELD_U]) == (0x1)); + res->fields_mask[FIELD_inc >> 6] |= 1LL << (FIELD_inc & 63); + /* pcode: wordhigher = (P == U) */ + res->fields[FIELD_wordhigher] = ((res->fields[FIELD_P]) == (res->fields[FIELD_U])); + res->fields_mask[FIELD_wordhigher >> 6] |= 1LL << (FIELD_wordhigher & 63); + /* pcode: if n == 15 then UNPREDICTABLE */ + if((res->fields[FIELD_n]) == (15)) { + res->flags |= FLAG_UNPREDICTABLE; + } + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: B9C9DC37 +int ror_immediate(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + /* Encoding T1 */ + /* pattern="11101,01,0010,S.1,1111,(0),imm3.3,Rd.4,imm2.2,11,Rm.4" width=32 stringency=19 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFFEF0030)==0xEA4F0030)) { + res->instrSize = 32; + if(!((instr & 0x8000)==0x0)) { + res->flags |= FLAG_UNPREDICTABLE; + } + if(!(req->arch & ARCH_ARMv6T2) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_S] = (instr & 0x100000)>>20; + res->fields_mask[FIELD_S >> 6] |= 1LL << (FIELD_S & 63); + char S_width = 1; + res->fields[FIELD_imm3] = (instr & 0x7000)>>12; + res->fields_mask[FIELD_imm3 >> 6] |= 1LL << (FIELD_imm3 & 63); + char imm3_width = 3; + res->fields[FIELD_Rd] = (instr & 0xF00)>>8; + res->fields_mask[FIELD_Rd >> 6] |= 1LL << (FIELD_Rd & 63); + char Rd_width = 4; + res->fields[FIELD_imm2] = (instr & 0xC0)>>6; + res->fields_mask[FIELD_imm2 >> 6] |= 1LL << (FIELD_imm2 & 63); + char imm2_width = 2; + res->fields[FIELD_Rm] = instr & 0xF; + res->fields_mask[FIELD_Rm >> 6] |= 1LL << (FIELD_Rm & 63); + char Rm_width = 4; + + static const instruction_format instr_formats[] = + { + { /* ROR{S}<c> <Rd>,<Rm>,#<shift_n> */ + "ror", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_OPTIONAL_STATUS, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rd,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rm,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_IMM,FIELD_shift_n,FIELD_UNINIT,"#","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_ROR; + + /* pcode: if (imm3:imm2) == '00000' then SEE RRX */ + if((((res->fields[FIELD_imm3]<<2)|(res->fields[FIELD_imm2]))) == (0x0)) { + + return rrx(req, res); + } + /* pcode: d = UInt(Rd) */ + res->fields[FIELD_d] = (res->fields[FIELD_Rd]); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: m = UInt(Rm) */ + res->fields[FIELD_m] = (res->fields[FIELD_Rm]); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + /* pcode: setflags = (S == '1') */ + res->fields[FIELD_setflags] = ((res->fields[FIELD_S]) == (0x1)); + res->fields_mask[FIELD_setflags >> 6] |= 1LL << (FIELD_setflags & 63); + /* pcode: (-, shift_n) = DecodeImmShift('11', imm3:imm2) */ + res->fields[FIELD_shift_n] = DecodeImmShift_shift_n(0x3, (res->fields[FIELD_imm3]<<2)|(res->fields[FIELD_imm2])); + res->fields_mask[FIELD_shift_n >> 6] |= 1LL << (FIELD_shift_n & 63); + /* pcode: if BadReg(d) || BadReg(m) then UNPREDICTABLE */ + if((BadReg(res->fields[FIELD_d])) || (BadReg(res->fields[FIELD_m]))) { + res->flags |= FLAG_UNPREDICTABLE; + } + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: E005B91B +int ror_register(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + /* Encoding T1 */ + /* pattern="010000,0111,Rm.3,Rdn.3" width=16 stringency=10 */ + { + uint16_t instr = req->instr_word16; + if(((instr & 0xFFC0)==0x41C0)) { + res->instrSize = 16; + if(!(req->arch & ARCH_ARMv4T) && !(req->arch & ARCH_ARMv5T) && !(req->arch & ARCH_ARMv6) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_Rm] = (instr & 0x38)>>3; + res->fields_mask[FIELD_Rm >> 6] |= 1LL << (FIELD_Rm & 63); + char Rm_width = 3; + res->fields[FIELD_Rdn] = instr & 0x7; + res->fields_mask[FIELD_Rdn >> 6] |= 1LL << (FIELD_Rdn & 63); + char Rdn_width = 3; + + static const instruction_format instr_formats[] = + { + { /* RORS <Rdn>,<Rm> */ + "rors", /* .operation (const char *) */ + 0, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rdn,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rm,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + { /* ROR<c> <Rdn>,<Rm> */ + "ror", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rdn,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rm,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 2; + res->mnem = armv7::ARMV7_RORS; + + /* pcode: d = UInt(Rdn) */ + res->fields[FIELD_d] = (res->fields[FIELD_Rdn]); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: n = UInt(Rdn) */ + res->fields[FIELD_n] = (res->fields[FIELD_Rdn]); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: m = UInt(Rm) */ + res->fields[FIELD_m] = (res->fields[FIELD_Rm]); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + /* pcode: setflags = !InITBlock() */ + res->fields[FIELD_setflags] = !(req->inIfThen == IFTHEN_YES); + res->fields_mask[FIELD_setflags >> 6] |= 1LL << (FIELD_setflags & 63); + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* Encoding T2 */ + /* pattern="11111,010,0,11,S.1,Rn.4,1111,Rd.4,0,000,Rm.4" width=32 stringency=20 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFFE0F0F0)==0xFA60F000)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ARMv6T2) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_S] = (instr & 0x100000)>>20; + res->fields_mask[FIELD_S >> 6] |= 1LL << (FIELD_S & 63); + char S_width = 1; + res->fields[FIELD_Rn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Rn >> 6] |= 1LL << (FIELD_Rn & 63); + char Rn_width = 4; + res->fields[FIELD_Rd] = (instr & 0xF00)>>8; + res->fields_mask[FIELD_Rd >> 6] |= 1LL << (FIELD_Rd & 63); + char Rd_width = 4; + res->fields[FIELD_Rm] = instr & 0xF; + res->fields_mask[FIELD_Rm >> 6] |= 1LL << (FIELD_Rm & 63); + char Rm_width = 4; + + static const instruction_format instr_formats[] = + { + { /* ROR{S}<c> <Rd>,<Rn>,<Rm> */ + "ror", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_OPTIONAL_STATUS, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rd,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rn,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rm,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_ROR; + + /* pcode: d = UInt(Rd) */ + res->fields[FIELD_d] = (res->fields[FIELD_Rd]); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: n = UInt(Rn) */ + res->fields[FIELD_n] = (res->fields[FIELD_Rn]); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: m = UInt(Rm) */ + res->fields[FIELD_m] = (res->fields[FIELD_Rm]); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + /* pcode: setflags = (S == '1') */ + res->fields[FIELD_setflags] = ((res->fields[FIELD_S]) == (0x1)); + res->fields_mask[FIELD_setflags >> 6] |= 1LL << (FIELD_setflags & 63); + /* pcode: if BadReg(d) || BadReg(n) || BadReg(m) then UNPREDICTABLE */ + if(((BadReg(res->fields[FIELD_d])) || (BadReg(res->fields[FIELD_n]))) || (BadReg(res->fields[FIELD_m]))) { + res->flags |= FLAG_UNPREDICTABLE; + } + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: BB29C9EB +int rrx(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + /* Encoding T1 */ + /* pattern="11101,01,0010,S.1,1111,(0),000,Rd.4,00,11,Rm.4" width=32 stringency=24 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFFEF70F0)==0xEA4F0030)) { + res->instrSize = 32; + if(!((instr & 0x8000)==0x0)) { + res->flags |= FLAG_UNPREDICTABLE; + } + if(!(req->arch & ARCH_ARMv6T2) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_S] = (instr & 0x100000)>>20; + res->fields_mask[FIELD_S >> 6] |= 1LL << (FIELD_S & 63); + char S_width = 1; + res->fields[FIELD_Rd] = (instr & 0xF00)>>8; + res->fields_mask[FIELD_Rd >> 6] |= 1LL << (FIELD_Rd & 63); + char Rd_width = 4; + res->fields[FIELD_Rm] = instr & 0xF; + res->fields_mask[FIELD_Rm >> 6] |= 1LL << (FIELD_Rm & 63); + char Rm_width = 4; + + static const instruction_format instr_formats[] = + { + { /* RRX{S}<c> <Rd>,<Rm> */ + "rrx", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_OPTIONAL_STATUS, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rd,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rm,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_RRX; + + /* pcode: d = UInt(Rd) */ + res->fields[FIELD_d] = (res->fields[FIELD_Rd]); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: m = UInt(Rm) */ + res->fields[FIELD_m] = (res->fields[FIELD_Rm]); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + /* pcode: setflags = (S == '1') */ + res->fields[FIELD_setflags] = ((res->fields[FIELD_S]) == (0x1)); + res->fields_mask[FIELD_setflags >> 6] |= 1LL << (FIELD_setflags & 63); + /* pcode: if BadReg(d) || BadReg(m) then UNPREDICTABLE */ + if((BadReg(res->fields[FIELD_d])) || (BadReg(res->fields[FIELD_m]))) { + res->flags |= FLAG_UNPREDICTABLE; + } + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: B8E23078 +int rsb_immediate(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + /* Encoding T1 */ + /* pattern="010000,1001,Rn.3,Rd.3" width=16 stringency=10 */ + { + uint16_t instr = req->instr_word16; + if(((instr & 0xFFC0)==0x4240)) { + res->instrSize = 16; + if(!(req->arch & ARCH_ARMv4T) && !(req->arch & ARCH_ARMv5T) && !(req->arch & ARCH_ARMv6) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_Rn] = (instr & 0x38)>>3; + res->fields_mask[FIELD_Rn >> 6] |= 1LL << (FIELD_Rn & 63); + char Rn_width = 3; + res->fields[FIELD_Rd] = instr & 0x7; + res->fields_mask[FIELD_Rd >> 6] |= 1LL << (FIELD_Rd & 63); + char Rd_width = 3; + + static const instruction_format instr_formats[] = + { + { /* RSBS <Rd>,<Rn>,#0 */ + "rsbs", /* .operation (const char *) */ + 0, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rd,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rn,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_ZERO,FIELD_UNINIT,FIELD_UNINIT,"#0","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + { /* RSB<c> <Rd>,<Rn>,#0 */ + "rsb", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rd,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rn,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_ZERO,FIELD_UNINIT,FIELD_UNINIT,"#0","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 2; + res->mnem = armv7::ARMV7_RSBS; + + /* pcode: d = UInt(Rd) */ + res->fields[FIELD_d] = (res->fields[FIELD_Rd]); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: n = UInt(Rn) */ + res->fields[FIELD_n] = (res->fields[FIELD_Rn]); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: setflags = !InITBlock() */ + res->fields[FIELD_setflags] = !(req->inIfThen == IFTHEN_YES); + res->fields_mask[FIELD_setflags >> 6] |= 1LL << (FIELD_setflags & 63); + /* pcode: imm32 = Zeros(32) */ + res->fields[FIELD_imm32] = /* 32-bit */ 0; + res->fields_mask[FIELD_imm32 >> 6] |= 1LL << (FIELD_imm32 & 63); + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* Encoding T2 */ + /* pattern="11110,i.1,0,1110,S.1,Rn.4,0,imm3.3,Rd.4,imm8.8" width=32 stringency=13 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFBE08000)==0xF1C00000)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ARMv6T2) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_i] = (instr & 0x4000000)>>26; + res->fields_mask[FIELD_i >> 6] |= 1LL << (FIELD_i & 63); + char i_width = 1; + res->fields[FIELD_S] = (instr & 0x100000)>>20; + res->fields_mask[FIELD_S >> 6] |= 1LL << (FIELD_S & 63); + char S_width = 1; + res->fields[FIELD_Rn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Rn >> 6] |= 1LL << (FIELD_Rn & 63); + char Rn_width = 4; + res->fields[FIELD_imm3] = (instr & 0x7000)>>12; + res->fields_mask[FIELD_imm3 >> 6] |= 1LL << (FIELD_imm3 & 63); + char imm3_width = 3; + res->fields[FIELD_Rd] = (instr & 0xF00)>>8; + res->fields_mask[FIELD_Rd >> 6] |= 1LL << (FIELD_Rd & 63); + char Rd_width = 4; + res->fields[FIELD_imm8] = instr & 0xFF; + res->fields_mask[FIELD_imm8 >> 6] |= 1LL << (FIELD_imm8 & 63); + char imm8_width = 8; + + static const instruction_format instr_formats[] = + { + { /* RSB{S}<c> <Rd>,<Rn>,#<imm32> */ + "rsb", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_OPTIONAL_STATUS, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rd,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rn,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_IMM,FIELD_imm32,FIELD_UNINIT,"#","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_RSB; + + /* pcode: d = UInt(Rd) */ + res->fields[FIELD_d] = (res->fields[FIELD_Rd]); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: n = UInt(Rn) */ + res->fields[FIELD_n] = (res->fields[FIELD_Rn]); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: setflags = (S == '1') */ + res->fields[FIELD_setflags] = ((res->fields[FIELD_S]) == (0x1)); + res->fields_mask[FIELD_setflags >> 6] |= 1LL << (FIELD_setflags & 63); + /* pcode: imm32 = ThumbExpandImm(i:imm3:imm8) */ + res->fields[FIELD_imm32] = ThumbExpandImm_C_imm32((res->fields[FIELD_i]<<(8+3))|(res->fields[FIELD_imm3]<<8)|(res->fields[FIELD_imm8]), req->carry_in); + /* TODO: handle ThumbExpandImm_C's possible setting of UNPREDICTABLE */ while(0); + res->fields_mask[FIELD_imm32 >> 6] |= 1LL << (FIELD_imm32 & 63); + /* pcode: if BadReg(d) || BadReg(n) then UNPREDICTABLE */ + if((BadReg(res->fields[FIELD_d])) || (BadReg(res->fields[FIELD_n]))) { + res->flags |= FLAG_UNPREDICTABLE; + } + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: D83957E7 +int rsb_register(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + /* Encoding T1 */ + /* pattern="11101,01,1110,S.1,Rn.4,(0),imm3.3,Rd.4,imm2.2,type.2,Rm.4" width=32 stringency=13 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFFE00000)==0xEBC00000)) { + res->instrSize = 32; + if(!((instr & 0x8000)==0x0)) { + res->flags |= FLAG_UNPREDICTABLE; + } + if(!(req->arch & ARCH_ARMv6T2) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_S] = (instr & 0x100000)>>20; + res->fields_mask[FIELD_S >> 6] |= 1LL << (FIELD_S & 63); + char S_width = 1; + res->fields[FIELD_Rn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Rn >> 6] |= 1LL << (FIELD_Rn & 63); + char Rn_width = 4; + res->fields[FIELD_imm3] = (instr & 0x7000)>>12; + res->fields_mask[FIELD_imm3 >> 6] |= 1LL << (FIELD_imm3 & 63); + char imm3_width = 3; + res->fields[FIELD_Rd] = (instr & 0xF00)>>8; + res->fields_mask[FIELD_Rd >> 6] |= 1LL << (FIELD_Rd & 63); + char Rd_width = 4; + res->fields[FIELD_imm2] = (instr & 0xC0)>>6; + res->fields_mask[FIELD_imm2 >> 6] |= 1LL << (FIELD_imm2 & 63); + char imm2_width = 2; + res->fields[FIELD_type] = (instr & 0x30)>>4; + res->fields_mask[FIELD_type >> 6] |= 1LL << (FIELD_type & 63); + char type_width = 2; + res->fields[FIELD_Rm] = instr & 0xF; + res->fields_mask[FIELD_Rm >> 6] |= 1LL << (FIELD_Rm & 63); + char Rm_width = 4; + + static const instruction_format instr_formats[] = + { + { /* RSB{S}<c> <Rd>,<Rn>,<Rm>{,<shift>} */ + "rsb", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_OPTIONAL_STATUS, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rd,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rn,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rm,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_SHIFT,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 4 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_RSB; + + /* pcode: d = UInt(Rd) */ + res->fields[FIELD_d] = (res->fields[FIELD_Rd]); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: n = UInt(Rn) */ + res->fields[FIELD_n] = (res->fields[FIELD_Rn]); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: m = UInt(Rm) */ + res->fields[FIELD_m] = (res->fields[FIELD_Rm]); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + /* pcode: setflags = (S == '1') */ + res->fields[FIELD_setflags] = ((res->fields[FIELD_S]) == (0x1)); + res->fields_mask[FIELD_setflags >> 6] |= 1LL << (FIELD_setflags & 63); + /* pcode: (shift_t, shift_n) = DecodeImmShift(type, imm3:imm2) */ + res->fields[FIELD_shift_t] = DecodeImmShift_shift_t(res->fields[FIELD_type], (res->fields[FIELD_imm3]<<2)|(res->fields[FIELD_imm2])); + res->fields_mask[FIELD_shift_t >> 6] |= 1LL << (FIELD_shift_t & 63); + res->fields[FIELD_shift_n] = DecodeImmShift_shift_n(res->fields[FIELD_type], (res->fields[FIELD_imm3]<<2)|(res->fields[FIELD_imm2])); + res->fields_mask[FIELD_shift_n >> 6] |= 1LL << (FIELD_shift_n & 63); + /* pcode: if BadReg(d) || BadReg(n) || BadReg(m) then UNPREDICTABLE */ + if(((BadReg(res->fields[FIELD_d])) || (BadReg(res->fields[FIELD_n]))) || (BadReg(res->fields[FIELD_m]))) { + res->flags |= FLAG_UNPREDICTABLE; + } + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: 7F370B6B +int sadd16(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + /* Encoding T1 */ + /* pattern="11111,010,1,001,Rn.4,1111,Rd.4,0,000,Rm.4" width=32 stringency=20 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFFF0F0F0)==0xFA90F000)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ARMv6T2) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_Rn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Rn >> 6] |= 1LL << (FIELD_Rn & 63); + char Rn_width = 4; + res->fields[FIELD_Rd] = (instr & 0xF00)>>8; + res->fields_mask[FIELD_Rd >> 6] |= 1LL << (FIELD_Rd & 63); + char Rd_width = 4; + res->fields[FIELD_Rm] = instr & 0xF; + res->fields_mask[FIELD_Rm >> 6] |= 1LL << (FIELD_Rm & 63); + char Rm_width = 4; + + static const instruction_format instr_formats[] = + { + { /* SADD16<c> <Rd>,<Rn>,<Rm> */ + "sadd16", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rd,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rn,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rm,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_SADD16; + + /* pcode: d = UInt(Rd) */ + res->fields[FIELD_d] = (res->fields[FIELD_Rd]); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: n = UInt(Rn) */ + res->fields[FIELD_n] = (res->fields[FIELD_Rn]); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: m = UInt(Rm) */ + res->fields[FIELD_m] = (res->fields[FIELD_Rm]); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + /* pcode: if BadReg(d) || BadReg(n) || BadReg(m) then UNPREDICTABLE */ + if(((BadReg(res->fields[FIELD_d])) || (BadReg(res->fields[FIELD_n]))) || (BadReg(res->fields[FIELD_m]))) { + res->flags |= FLAG_UNPREDICTABLE; + } + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: 9FE6DBC8 +int sadd8(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + /* Encoding T1 */ + /* pattern="11111,010,1,000,Rn.4,1111,Rd.4,0,000,Rm.4" width=32 stringency=20 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFFF0F0F0)==0xFA80F000)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ARMv6T2) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_Rn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Rn >> 6] |= 1LL << (FIELD_Rn & 63); + char Rn_width = 4; + res->fields[FIELD_Rd] = (instr & 0xF00)>>8; + res->fields_mask[FIELD_Rd >> 6] |= 1LL << (FIELD_Rd & 63); + char Rd_width = 4; + res->fields[FIELD_Rm] = instr & 0xF; + res->fields_mask[FIELD_Rm >> 6] |= 1LL << (FIELD_Rm & 63); + char Rm_width = 4; + + static const instruction_format instr_formats[] = + { + { /* SADD8<c> <Rd>,<Rn>,<Rm> */ + "sadd8", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rd,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rn,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rm,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_SADD8; + + /* pcode: d = UInt(Rd) */ + res->fields[FIELD_d] = (res->fields[FIELD_Rd]); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: n = UInt(Rn) */ + res->fields[FIELD_n] = (res->fields[FIELD_Rn]); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: m = UInt(Rm) */ + res->fields[FIELD_m] = (res->fields[FIELD_Rm]); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + /* pcode: if BadReg(d) || BadReg(n) || BadReg(m) then UNPREDICTABLE */ + if(((BadReg(res->fields[FIELD_d])) || (BadReg(res->fields[FIELD_n]))) || (BadReg(res->fields[FIELD_m]))) { + res->flags |= FLAG_UNPREDICTABLE; + } + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: 09ABC271 +int sasx(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + /* Encoding T1 */ + /* pattern="11111,010,1,010,Rn.4,1111,Rd.4,0,000,Rm.4" width=32 stringency=20 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFFF0F0F0)==0xFAA0F000)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ARMv6T2) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_Rn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Rn >> 6] |= 1LL << (FIELD_Rn & 63); + char Rn_width = 4; + res->fields[FIELD_Rd] = (instr & 0xF00)>>8; + res->fields_mask[FIELD_Rd >> 6] |= 1LL << (FIELD_Rd & 63); + char Rd_width = 4; + res->fields[FIELD_Rm] = instr & 0xF; + res->fields_mask[FIELD_Rm >> 6] |= 1LL << (FIELD_Rm & 63); + char Rm_width = 4; + + static const instruction_format instr_formats[] = + { + { /* SASX<c> <Rd>,<Rn>,<Rm> */ + "sasx", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rd,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rn,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rm,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_SASX; + + /* pcode: d = UInt(Rd) */ + res->fields[FIELD_d] = (res->fields[FIELD_Rd]); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: n = UInt(Rn) */ + res->fields[FIELD_n] = (res->fields[FIELD_Rn]); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: m = UInt(Rm) */ + res->fields[FIELD_m] = (res->fields[FIELD_Rm]); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + /* pcode: if BadReg(d) || BadReg(n) || BadReg(m) then UNPREDICTABLE */ + if(((BadReg(res->fields[FIELD_d])) || (BadReg(res->fields[FIELD_n]))) || (BadReg(res->fields[FIELD_m]))) { + res->flags |= FLAG_UNPREDICTABLE; + } + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: 846AF9F9 +int sbc_immediate(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + /* Encoding T1 */ + /* pattern="11110,i.1,0,1011,S.1,Rn.4,0,imm3.3,Rd.4,imm8.8" width=32 stringency=13 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFBE08000)==0xF1600000)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ARMv6T2) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_i] = (instr & 0x4000000)>>26; + res->fields_mask[FIELD_i >> 6] |= 1LL << (FIELD_i & 63); + char i_width = 1; + res->fields[FIELD_S] = (instr & 0x100000)>>20; + res->fields_mask[FIELD_S >> 6] |= 1LL << (FIELD_S & 63); + char S_width = 1; + res->fields[FIELD_Rn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Rn >> 6] |= 1LL << (FIELD_Rn & 63); + char Rn_width = 4; + res->fields[FIELD_imm3] = (instr & 0x7000)>>12; + res->fields_mask[FIELD_imm3 >> 6] |= 1LL << (FIELD_imm3 & 63); + char imm3_width = 3; + res->fields[FIELD_Rd] = (instr & 0xF00)>>8; + res->fields_mask[FIELD_Rd >> 6] |= 1LL << (FIELD_Rd & 63); + char Rd_width = 4; + res->fields[FIELD_imm8] = instr & 0xFF; + res->fields_mask[FIELD_imm8 >> 6] |= 1LL << (FIELD_imm8 & 63); + char imm8_width = 8; + + static const instruction_format instr_formats[] = + { + { /* SBC{S}<c> <Rd>,<Rn>,#<imm32> */ + "sbc", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_OPTIONAL_STATUS, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rd,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rn,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_IMM,FIELD_imm32,FIELD_UNINIT,"#","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_SBC; + + /* pcode: d = UInt(Rd) */ + res->fields[FIELD_d] = (res->fields[FIELD_Rd]); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: n = UInt(Rn) */ + res->fields[FIELD_n] = (res->fields[FIELD_Rn]); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: setflags = (S == '1') */ + res->fields[FIELD_setflags] = ((res->fields[FIELD_S]) == (0x1)); + res->fields_mask[FIELD_setflags >> 6] |= 1LL << (FIELD_setflags & 63); + /* pcode: imm32 = ThumbExpandImm(i:imm3:imm8) */ + res->fields[FIELD_imm32] = ThumbExpandImm_C_imm32((res->fields[FIELD_i]<<(8+3))|(res->fields[FIELD_imm3]<<8)|(res->fields[FIELD_imm8]), req->carry_in); + /* TODO: handle ThumbExpandImm_C's possible setting of UNPREDICTABLE */ while(0); + res->fields_mask[FIELD_imm32 >> 6] |= 1LL << (FIELD_imm32 & 63); + /* pcode: if BadReg(d) || BadReg(n) then UNPREDICTABLE */ + if((BadReg(res->fields[FIELD_d])) || (BadReg(res->fields[FIELD_n]))) { + res->flags |= FLAG_UNPREDICTABLE; + } + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: 2F8556F6 +int sbc_register(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + /* Encoding T1 */ + /* pattern="010000,0110,Rm.3,Rdn.3" width=16 stringency=10 */ + { + uint16_t instr = req->instr_word16; + if(((instr & 0xFFC0)==0x4180)) { + res->instrSize = 16; + if(!(req->arch & ARCH_ARMv4T) && !(req->arch & ARCH_ARMv5T) && !(req->arch & ARCH_ARMv6) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_Rm] = (instr & 0x38)>>3; + res->fields_mask[FIELD_Rm >> 6] |= 1LL << (FIELD_Rm & 63); + char Rm_width = 3; + res->fields[FIELD_Rdn] = instr & 0x7; + res->fields_mask[FIELD_Rdn >> 6] |= 1LL << (FIELD_Rdn & 63); + char Rdn_width = 3; + + static const instruction_format instr_formats[] = + { + { /* SBCS <Rdn>,<Rm> */ + "sbcs", /* .operation (const char *) */ + 0, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rdn,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rm,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + { /* SBC<c> <Rdn>,<Rm> */ + "sbc", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rdn,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rm,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 2; + res->mnem = armv7::ARMV7_SBCS; + + /* pcode: d = UInt(Rdn) */ + res->fields[FIELD_d] = (res->fields[FIELD_Rdn]); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: n = UInt(Rdn) */ + res->fields[FIELD_n] = (res->fields[FIELD_Rdn]); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: m = UInt(Rm) */ + res->fields[FIELD_m] = (res->fields[FIELD_Rm]); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + /* pcode: setflags = !InITBlock() */ + res->fields[FIELD_setflags] = !(req->inIfThen == IFTHEN_YES); + res->fields_mask[FIELD_setflags >> 6] |= 1LL << (FIELD_setflags & 63); + /* pcode: (shift_t, shift_n) = (SRType_LSL, 0) */ + res->fields[FIELD_shift_t] = 0; + res->fields_mask[FIELD_shift_t >> 6] |= 1LL << (FIELD_shift_t & 63); + res->fields[FIELD_shift_n] = 0; + res->fields_mask[FIELD_shift_n >> 6] |= 1LL << (FIELD_shift_n & 63); + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* Encoding T2 */ + /* pattern="11101,01,1011,S.1,Rn.4,(0),imm3.3,Rd.4,imm2.2,type.2,Rm.4" width=32 stringency=13 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFFE00000)==0xEB600000)) { + res->instrSize = 32; + if(!((instr & 0x8000)==0x0)) { + res->flags |= FLAG_UNPREDICTABLE; + } + if(!(req->arch & ARCH_ARMv6T2) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_S] = (instr & 0x100000)>>20; + res->fields_mask[FIELD_S >> 6] |= 1LL << (FIELD_S & 63); + char S_width = 1; + res->fields[FIELD_Rn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Rn >> 6] |= 1LL << (FIELD_Rn & 63); + char Rn_width = 4; + res->fields[FIELD_imm3] = (instr & 0x7000)>>12; + res->fields_mask[FIELD_imm3 >> 6] |= 1LL << (FIELD_imm3 & 63); + char imm3_width = 3; + res->fields[FIELD_Rd] = (instr & 0xF00)>>8; + res->fields_mask[FIELD_Rd >> 6] |= 1LL << (FIELD_Rd & 63); + char Rd_width = 4; + res->fields[FIELD_imm2] = (instr & 0xC0)>>6; + res->fields_mask[FIELD_imm2 >> 6] |= 1LL << (FIELD_imm2 & 63); + char imm2_width = 2; + res->fields[FIELD_type] = (instr & 0x30)>>4; + res->fields_mask[FIELD_type >> 6] |= 1LL << (FIELD_type & 63); + char type_width = 2; + res->fields[FIELD_Rm] = instr & 0xF; + res->fields_mask[FIELD_Rm >> 6] |= 1LL << (FIELD_Rm & 63); + char Rm_width = 4; + + static const instruction_format instr_formats[] = + { + { /* SBC{S}<c> <Rd>,<Rn>,<Rm>{,<shift>} */ + "sbc", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_OPTIONAL_STATUS, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rd,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rn,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rm,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_SHIFT,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 4 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_SBC; + + /* pcode: d = UInt(Rd) */ + res->fields[FIELD_d] = (res->fields[FIELD_Rd]); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: n = UInt(Rn) */ + res->fields[FIELD_n] = (res->fields[FIELD_Rn]); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: m = UInt(Rm) */ + res->fields[FIELD_m] = (res->fields[FIELD_Rm]); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + /* pcode: setflags = (S == '1') */ + res->fields[FIELD_setflags] = ((res->fields[FIELD_S]) == (0x1)); + res->fields_mask[FIELD_setflags >> 6] |= 1LL << (FIELD_setflags & 63); + /* pcode: (shift_t, shift_n) = DecodeImmShift(type, imm3:imm2) */ + res->fields[FIELD_shift_t] = DecodeImmShift_shift_t(res->fields[FIELD_type], (res->fields[FIELD_imm3]<<2)|(res->fields[FIELD_imm2])); + res->fields_mask[FIELD_shift_t >> 6] |= 1LL << (FIELD_shift_t & 63); + res->fields[FIELD_shift_n] = DecodeImmShift_shift_n(res->fields[FIELD_type], (res->fields[FIELD_imm3]<<2)|(res->fields[FIELD_imm2])); + res->fields_mask[FIELD_shift_n >> 6] |= 1LL << (FIELD_shift_n & 63); + /* pcode: if BadReg(d) || BadReg(n) || BadReg(m) then UNPREDICTABLE */ + if(((BadReg(res->fields[FIELD_d])) || (BadReg(res->fields[FIELD_n]))) || (BadReg(res->fields[FIELD_m]))) { + res->flags |= FLAG_UNPREDICTABLE; + } + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: DE399C47 +int sbfx(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + /* Encoding T1 */ + /* pattern="11110,(0),11,010,0,Rn.4,0,imm3.3,Rd.4,imm2.2,(0),widthm1.5" width=32 stringency=15 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFBF08000)==0xF3400000)) { + res->instrSize = 32; + if(!((instr & 0x4000020)==0x0)) { + res->flags |= FLAG_UNPREDICTABLE; + } + if(!(req->arch & ARCH_ARMv6T2) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_Rn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Rn >> 6] |= 1LL << (FIELD_Rn & 63); + char Rn_width = 4; + res->fields[FIELD_imm3] = (instr & 0x7000)>>12; + res->fields_mask[FIELD_imm3 >> 6] |= 1LL << (FIELD_imm3 & 63); + char imm3_width = 3; + res->fields[FIELD_Rd] = (instr & 0xF00)>>8; + res->fields_mask[FIELD_Rd >> 6] |= 1LL << (FIELD_Rd & 63); + char Rd_width = 4; + res->fields[FIELD_imm2] = (instr & 0xC0)>>6; + res->fields_mask[FIELD_imm2 >> 6] |= 1LL << (FIELD_imm2 & 63); + char imm2_width = 2; + res->fields[FIELD_widthm1] = instr & 0x1F; + res->fields_mask[FIELD_widthm1 >> 6] |= 1LL << (FIELD_widthm1 & 63); + char widthm1_width = 5; + + static const instruction_format instr_formats[] = + { + { /* SBFX<c> <Rd>,<Rn>,#<lsbit>,#<width> */ + "sbfx", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rd,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rn,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_IMM,FIELD_lsbit,FIELD_UNINIT,"#","",WRITEBACK_NO}, + {OPERAND_FORMAT_IMM,FIELD_width,FIELD_UNINIT,"#","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 4 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_SBFX; + + /* pcode: d = UInt(Rd) */ + res->fields[FIELD_d] = (res->fields[FIELD_Rd]); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: n = UInt(Rn) */ + res->fields[FIELD_n] = (res->fields[FIELD_Rn]); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: lsbit = UInt(imm3:imm2) */ + res->fields[FIELD_lsbit] = ((res->fields[FIELD_imm3]<<2)|(res->fields[FIELD_imm2])); + res->fields_mask[FIELD_lsbit >> 6] |= 1LL << (FIELD_lsbit & 63); + /* pcode: width = UInt(widthm1)+1 */ + res->fields[FIELD_width] = ((res->fields[FIELD_widthm1])) + (1); + res->fields_mask[FIELD_width >> 6] |= 1LL << (FIELD_width & 63); + /* pcode: if BadReg(d) || BadReg(n) then UNPREDICTABLE */ + if((BadReg(res->fields[FIELD_d])) || (BadReg(res->fields[FIELD_n]))) { + res->flags |= FLAG_UNPREDICTABLE; + } + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: E1917B5F +int sdiv(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + /* Encoding T1 */ + /* pattern="11111,011100,1,Rn.4,(1)(1)(1)(1),Rd.4,1111,Rm.4" width=32 stringency=20 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFFF000F0)==0xFB9000F0)) { + res->instrSize = 32; + if(!((instr & 0xF000)==0xF000)) { + res->flags |= FLAG_UNPREDICTABLE; + } + if(!(req->arch & ARCH_ARMv7_R)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_Rn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Rn >> 6] |= 1LL << (FIELD_Rn & 63); + char Rn_width = 4; + res->fields[FIELD_Rd] = (instr & 0xF00)>>8; + res->fields_mask[FIELD_Rd >> 6] |= 1LL << (FIELD_Rd & 63); + char Rd_width = 4; + res->fields[FIELD_Rm] = instr & 0xF; + res->fields_mask[FIELD_Rm >> 6] |= 1LL << (FIELD_Rm & 63); + char Rm_width = 4; + + static const instruction_format instr_formats[] = + { + { /* SDIV<c> <Rd>,<Rn>,<Rm> */ + "sdiv", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rd,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rn,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rm,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_SDIV; + + /* pcode: d = UInt(Rd) */ + res->fields[FIELD_d] = (res->fields[FIELD_Rd]); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: n = UInt(Rn) */ + res->fields[FIELD_n] = (res->fields[FIELD_Rn]); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: m = UInt(Rm) */ + res->fields[FIELD_m] = (res->fields[FIELD_Rm]); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + /* pcode: if BadReg(d) || BadReg(n) || BadReg(m) then UNPREDICTABLE */ + if(((BadReg(res->fields[FIELD_d])) || (BadReg(res->fields[FIELD_n]))) || (BadReg(res->fields[FIELD_m]))) { + res->flags |= FLAG_UNPREDICTABLE; + } + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: 8F897136 +int sel(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + /* Encoding T1 */ + /* pattern="11111,010,1,010,Rn.4,1111,Rd.4,1,000,Rm.4" width=32 stringency=20 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFFF0F0F0)==0xFAA0F080)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ARMv6T2) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_Rn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Rn >> 6] |= 1LL << (FIELD_Rn & 63); + char Rn_width = 4; + res->fields[FIELD_Rd] = (instr & 0xF00)>>8; + res->fields_mask[FIELD_Rd >> 6] |= 1LL << (FIELD_Rd & 63); + char Rd_width = 4; + res->fields[FIELD_Rm] = instr & 0xF; + res->fields_mask[FIELD_Rm >> 6] |= 1LL << (FIELD_Rm & 63); + char Rm_width = 4; + + static const instruction_format instr_formats[] = + { + { /* SEL<c> <Rd>,<Rn>,<Rm> */ + "sel", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rd,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rn,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rm,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_SEL; + + /* pcode: d = UInt(Rd) */ + res->fields[FIELD_d] = (res->fields[FIELD_Rd]); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: n = UInt(Rn) */ + res->fields[FIELD_n] = (res->fields[FIELD_Rn]); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: m = UInt(Rm) */ + res->fields[FIELD_m] = (res->fields[FIELD_Rm]); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + /* pcode: if BadReg(d) || BadReg(n) || BadReg(m) then UNPREDICTABLE */ + if(((BadReg(res->fields[FIELD_d])) || (BadReg(res->fields[FIELD_n]))) || (BadReg(res->fields[FIELD_m]))) { + res->flags |= FLAG_UNPREDICTABLE; + } + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: DAC77320 +int setend(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + /* Encoding T1 */ + /* pattern="1011,0110,010,(1),E.1,(0)(0)(0)" width=16 stringency=16 */ + { + uint16_t instr = req->instr_word16; + if(((instr & 0xFFE0)==0xB640)) { + res->instrSize = 16; + if(!((instr & 0x17)==0x10)) { + res->flags |= FLAG_UNPREDICTABLE; + } + if(!(req->arch & ARCH_ARMv6) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_E] = (instr & 0x8)>>3; + res->fields_mask[FIELD_E >> 6] |= 1LL << (FIELD_E & 63); + char E_width = 1; + + static const instruction_format instr_formats[] = + { + { /* SETEND <E> */ + "setend", /* .operation (const char *) */ + 0, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_ENDIAN,FIELD_E,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 1 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_SETEND; + + /* pcode: set_bigend = (E == '1') */ + res->fields[FIELD_set_bigend] = ((res->fields[FIELD_E]) == (0x1)); + res->fields_mask[FIELD_set_bigend >> 6] |= 1LL << (FIELD_set_bigend & 63); + /* pcode: if InITBlock() then UNPREDICTABLE */ + if(req->inIfThen == IFTHEN_YES) { + res->flags |= FLAG_UNPREDICTABLE; + } + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: 266EBC2E +int sev(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + /* Encoding T1 */ + /* pattern="1011,1111,0100,0000" width=16 stringency=16 */ + { + uint16_t instr = req->instr_word16; + if(((instr & 0xFFFF)==0xBF40)) { + res->instrSize = 16; + if(!(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + static const instruction_format instr_formats[] = + { + { /* SEV<c> */ + "sev", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 0 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_SEV; + + /* pcode: nop */ + while(0); + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* Encoding T2 */ + /* pattern="11110,0,111,01,0,(1)(1)(1)(1),10,(0),0,(0),000,00000100" width=32 stringency=32 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFFF0D7FF)==0xF3A08004)) { + res->instrSize = 32; + if(!((instr & 0xF2800)==0xF0000)) { + res->flags |= FLAG_UNPREDICTABLE; + } + if(!(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + static const instruction_format instr_formats[] = + { + { /* SEV<c>.W */ + "sev", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_WIDE, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 0 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_SEV; + + /* pcode: nop */ + while(0); + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: 5FEF6FBA +int shadd16(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + /* Encoding T1 */ + /* pattern="11111,010,1,001,Rn.4,1111,Rd.4,0,010,Rm.4" width=32 stringency=20 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFFF0F0F0)==0xFA90F020)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ARMv6T2) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_Rn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Rn >> 6] |= 1LL << (FIELD_Rn & 63); + char Rn_width = 4; + res->fields[FIELD_Rd] = (instr & 0xF00)>>8; + res->fields_mask[FIELD_Rd >> 6] |= 1LL << (FIELD_Rd & 63); + char Rd_width = 4; + res->fields[FIELD_Rm] = instr & 0xF; + res->fields_mask[FIELD_Rm >> 6] |= 1LL << (FIELD_Rm & 63); + char Rm_width = 4; + + static const instruction_format instr_formats[] = + { + { /* SHADD16<c> <Rd>,<Rn>,<Rm> */ + "shadd16", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rd,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rn,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rm,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_SHADD16; + + /* pcode: d = UInt(Rd) */ + res->fields[FIELD_d] = (res->fields[FIELD_Rd]); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: n = UInt(Rn) */ + res->fields[FIELD_n] = (res->fields[FIELD_Rn]); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: m = UInt(Rm) */ + res->fields[FIELD_m] = (res->fields[FIELD_Rm]); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + /* pcode: if BadReg(d) || BadReg(n) || BadReg(m) then UNPREDICTABLE */ + if(((BadReg(res->fields[FIELD_d])) || (BadReg(res->fields[FIELD_n]))) || (BadReg(res->fields[FIELD_m]))) { + res->flags |= FLAG_UNPREDICTABLE; + } + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: AFA85C8F +int shadd8(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + /* Encoding T1 */ + /* pattern="11111,010,1,000,Rn.4,1111,Rd.4,0,010,Rm.4" width=32 stringency=20 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFFF0F0F0)==0xFA80F020)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ARMv6T2) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_Rn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Rn >> 6] |= 1LL << (FIELD_Rn & 63); + char Rn_width = 4; + res->fields[FIELD_Rd] = (instr & 0xF00)>>8; + res->fields_mask[FIELD_Rd >> 6] |= 1LL << (FIELD_Rd & 63); + char Rd_width = 4; + res->fields[FIELD_Rm] = instr & 0xF; + res->fields_mask[FIELD_Rm >> 6] |= 1LL << (FIELD_Rm & 63); + char Rm_width = 4; + + static const instruction_format instr_formats[] = + { + { /* SHADD8<c> <Rd>,<Rn>,<Rm> */ + "shadd8", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rd,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rn,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rm,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_SHADD8; + + /* pcode: d = UInt(Rd) */ + res->fields[FIELD_d] = (res->fields[FIELD_Rd]); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: n = UInt(Rn) */ + res->fields[FIELD_n] = (res->fields[FIELD_Rn]); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: m = UInt(Rm) */ + res->fields[FIELD_m] = (res->fields[FIELD_Rm]); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + /* pcode: if BadReg(d) || BadReg(n) || BadReg(m) then UNPREDICTABLE */ + if(((BadReg(res->fields[FIELD_d])) || (BadReg(res->fields[FIELD_n]))) || (BadReg(res->fields[FIELD_m]))) { + res->flags |= FLAG_UNPREDICTABLE; + } + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: 757C89AC +int shasx(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + /* Encoding T1 */ + /* pattern="11111,010,1,010,Rn.4,1111,Rd.4,0,010,Rm.4" width=32 stringency=20 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFFF0F0F0)==0xFAA0F020)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ARMv6T2) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_Rn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Rn >> 6] |= 1LL << (FIELD_Rn & 63); + char Rn_width = 4; + res->fields[FIELD_Rd] = (instr & 0xF00)>>8; + res->fields_mask[FIELD_Rd >> 6] |= 1LL << (FIELD_Rd & 63); + char Rd_width = 4; + res->fields[FIELD_Rm] = instr & 0xF; + res->fields_mask[FIELD_Rm >> 6] |= 1LL << (FIELD_Rm & 63); + char Rm_width = 4; + + static const instruction_format instr_formats[] = + { + { /* SHASX<c> <Rd>,<Rn>,<Rm> */ + "shasx", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rd,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rn,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rm,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_SHASX; + + /* pcode: d = UInt(Rd) */ + res->fields[FIELD_d] = (res->fields[FIELD_Rd]); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: n = UInt(Rn) */ + res->fields[FIELD_n] = (res->fields[FIELD_Rn]); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: m = UInt(Rm) */ + res->fields[FIELD_m] = (res->fields[FIELD_Rm]); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + /* pcode: if BadReg(d) || BadReg(n) || BadReg(m) then UNPREDICTABLE */ + if(((BadReg(res->fields[FIELD_d])) || (BadReg(res->fields[FIELD_n]))) || (BadReg(res->fields[FIELD_m]))) { + res->flags |= FLAG_UNPREDICTABLE; + } + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: F29F6C78 +int shift_immediate_add_sub_mov_cmp(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + uint16_t instr = req->instr_word16; + uint16_t Opcode = (instr & 0x3E00)>>9; + uint16_t clue = (instr & 0x1C0)>>6; + if(((Opcode & 0x1F)==0x0) && ((clue & 0x7)==0x0)) return mov_register(req, res); + if(((Opcode & 0x1F)==0xC) && 1) return add_register(req, res); + if(((Opcode & 0x1F)==0xD) && 1) return sub_register(req, res); + if(((Opcode & 0x1F)==0xE) && 1) return add_immediate(req, res); + if(((Opcode & 0x1F)==0xF) && 1) return sub_immediate(req, res); + if(((Opcode & 0x1C)==0x0) && 1) return lsl_immediate(req, res); + if(((Opcode & 0x1C)==0x4) && 1) return lsr_immediate(req, res); + if(((Opcode & 0x1C)==0x8) && 1) return asr_immediate(req, res); + if(((Opcode & 0x1C)==0x10) && 1) return mov_immediate(req, res); + if(((Opcode & 0x1C)==0x14) && 1) return cmp_immediate(req, res); + if(((Opcode & 0x1C)==0x18) && 1) return add_immediate(req, res); + if(((Opcode & 0x1C)==0x1C) && 1) return sub_immediate(req, res); + return undefined(req, res); +} + +// gen_crc: 8BEF295F +int shsax(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + /* Encoding T1 */ + /* pattern="11111,010,1,110,Rn.4,1111,Rd.4,0,010,Rm.4" width=32 stringency=20 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFFF0F0F0)==0xFAE0F020)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ARMv6T2) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_Rn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Rn >> 6] |= 1LL << (FIELD_Rn & 63); + char Rn_width = 4; + res->fields[FIELD_Rd] = (instr & 0xF00)>>8; + res->fields_mask[FIELD_Rd >> 6] |= 1LL << (FIELD_Rd & 63); + char Rd_width = 4; + res->fields[FIELD_Rm] = instr & 0xF; + res->fields_mask[FIELD_Rm >> 6] |= 1LL << (FIELD_Rm & 63); + char Rm_width = 4; + + static const instruction_format instr_formats[] = + { + { /* SHSAX<c> <Rd>,<Rn>,<Rm> */ + "shsax", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rd,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rn,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rm,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_SHSAX; + + /* pcode: d = UInt(Rd) */ + res->fields[FIELD_d] = (res->fields[FIELD_Rd]); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: n = UInt(Rn) */ + res->fields[FIELD_n] = (res->fields[FIELD_Rn]); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: m = UInt(Rm) */ + res->fields[FIELD_m] = (res->fields[FIELD_Rm]); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + /* pcode: if BadReg(d) || BadReg(n) || BadReg(m) then UNPREDICTABLE */ + if(((BadReg(res->fields[FIELD_d])) || (BadReg(res->fields[FIELD_n]))) || (BadReg(res->fields[FIELD_m]))) { + res->flags |= FLAG_UNPREDICTABLE; + } + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: 198D24C3 +int shsub16(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + /* Encoding T1 */ + /* pattern="11111,010,1,101,Rn.4,1111,Rd.4,0,010,Rm.4" width=32 stringency=20 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFFF0F0F0)==0xFAD0F020)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ARMv6T2) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_Rn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Rn >> 6] |= 1LL << (FIELD_Rn & 63); + char Rn_width = 4; + res->fields[FIELD_Rd] = (instr & 0xF00)>>8; + res->fields_mask[FIELD_Rd >> 6] |= 1LL << (FIELD_Rd & 63); + char Rd_width = 4; + res->fields[FIELD_Rm] = instr & 0xF; + res->fields_mask[FIELD_Rm >> 6] |= 1LL << (FIELD_Rm & 63); + char Rm_width = 4; + + static const instruction_format instr_formats[] = + { + { /* SHSUB16<c> <Rd>,<Rn>,<Rm> */ + "shsub16", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rd,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rn,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rm,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_SHSUB16; + + /* pcode: d = UInt(Rd) */ + res->fields[FIELD_d] = (res->fields[FIELD_Rd]); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: n = UInt(Rn) */ + res->fields[FIELD_n] = (res->fields[FIELD_Rn]); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: m = UInt(Rm) */ + res->fields[FIELD_m] = (res->fields[FIELD_Rm]); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + /* pcode: if BadReg(d) || BadReg(n) || BadReg(m) then UNPREDICTABLE */ + if(((BadReg(res->fields[FIELD_d])) || (BadReg(res->fields[FIELD_n]))) || (BadReg(res->fields[FIELD_m]))) { + res->flags |= FLAG_UNPREDICTABLE; + } + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: AA610C90 +int shsub8(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + /* Encoding T1 */ + /* pattern="11111,010,1,100,Rn.4,1111,Rd.4,0,010,Rm.4" width=32 stringency=20 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFFF0F0F0)==0xFAC0F020)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ARMv6T2) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_Rn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Rn >> 6] |= 1LL << (FIELD_Rn & 63); + char Rn_width = 4; + res->fields[FIELD_Rd] = (instr & 0xF00)>>8; + res->fields_mask[FIELD_Rd >> 6] |= 1LL << (FIELD_Rd & 63); + char Rd_width = 4; + res->fields[FIELD_Rm] = instr & 0xF; + res->fields_mask[FIELD_Rm >> 6] |= 1LL << (FIELD_Rm & 63); + char Rm_width = 4; + + static const instruction_format instr_formats[] = + { + { /* SHSUB8<c> <Rd>,<Rn>,<Rm> */ + "shsub8", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rd,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rn,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rm,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_SHSUB8; + + /* pcode: d = UInt(Rd) */ + res->fields[FIELD_d] = (res->fields[FIELD_Rd]); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: n = UInt(Rn) */ + res->fields[FIELD_n] = (res->fields[FIELD_Rn]); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: m = UInt(Rm) */ + res->fields[FIELD_m] = (res->fields[FIELD_Rm]); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + /* pcode: if BadReg(d) || BadReg(n) || BadReg(m) then UNPREDICTABLE */ + if(((BadReg(res->fields[FIELD_d])) || (BadReg(res->fields[FIELD_n]))) || (BadReg(res->fields[FIELD_m]))) { + res->flags |= FLAG_UNPREDICTABLE; + } + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: 0976DAC5 +int smc(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + /* Encoding T1 */ + /* pattern="11110,1111111,imm4.4,1000,(0)(0)(0)(0)(0)(0)(0)(0)(0)(0)(0)(0)" width=32 stringency=28 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFFF0F000)==0xF7F08000)) { + res->instrSize = 32; + if(!((instr & 0xFFF)==0x0)) { + res->flags |= FLAG_UNPREDICTABLE; + } + if(!(req->arch & ARCH_SECURITY_EXTENSIONS)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_imm4] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_imm4 >> 6] |= 1LL << (FIELD_imm4 & 63); + char imm4_width = 4; + + static const instruction_format instr_formats[] = + { + { /* SMC<c> #<imm4> */ + "smc", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_IMM,FIELD_imm4,FIELD_UNINIT,"#","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 1 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_SMC; + + /* pcode: imm32 = ZeroExtend(imm4, 32) */ + res->fields[FIELD_imm32] = res->fields[FIELD_imm4]; + res->fields_mask[FIELD_imm32 >> 6] |= 1LL << (FIELD_imm32 & 63); + /* pcode: if InITBlock() && !LastInITBlock() then UNPREDICTABLE */ + if((req->inIfThen == IFTHEN_YES) && (!(req->inIfThenLast == IFTHENLAST_YES))) { + res->flags |= FLAG_UNPREDICTABLE; + } + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: 123D1689 +int smlabb_smlabt_smlatb_smlatt(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + /* Encoding T1 */ + /* pattern="11111,0110,001,Rn.4,Ra.4,Rd.4,00,0,0,Rm.4" width=32 stringency=16 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFFF000F0)==0xFB100000)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ARMv6T2) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_Rn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Rn >> 6] |= 1LL << (FIELD_Rn & 63); + char Rn_width = 4; + res->fields[FIELD_Ra] = (instr & 0xF000)>>12; + res->fields_mask[FIELD_Ra >> 6] |= 1LL << (FIELD_Ra & 63); + char Ra_width = 4; + res->fields[FIELD_Rd] = (instr & 0xF00)>>8; + res->fields_mask[FIELD_Rd >> 6] |= 1LL << (FIELD_Rd & 63); + char Rd_width = 4; + res->fields[FIELD_Rm] = instr & 0xF; + res->fields_mask[FIELD_Rm >> 6] |= 1LL << (FIELD_Rm & 63); + char Rm_width = 4; + + static const instruction_format instr_formats[] = + { + { /* SMLABB<c> <Rd>,<Rn>,<Rm>,<Ra> */ + "smlabb", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rd,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rn,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rm,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Ra,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 4 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_SMLABB; + + /* pcode: if Ra == '1111' then SEE SMULBB, SMULBT, SMULTB, SMULTT */ + if((res->fields[FIELD_Ra]) == (0xF)) { + + return smulbb_smulbt_smultb_smultt(req, res); + } + /* pcode: d = UInt(Rd) */ + res->fields[FIELD_d] = (res->fields[FIELD_Rd]); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: n = UInt(Rn) */ + res->fields[FIELD_n] = (res->fields[FIELD_Rn]); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: m = UInt(Rm) */ + res->fields[FIELD_m] = (res->fields[FIELD_Rm]); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + /* pcode: a = UInt(Ra) */ + res->fields[FIELD_a] = (res->fields[FIELD_Ra]); + res->fields_mask[FIELD_a >> 6] |= 1LL << (FIELD_a & 63); + /* pcode: if BadReg(d) || BadReg(n) || BadReg(m) || a == 13 then UNPREDICTABLE */ + if((((BadReg(res->fields[FIELD_d])) || (BadReg(res->fields[FIELD_n]))) || (BadReg(res->fields[FIELD_m]))) || ((res->fields[FIELD_a]) == (13))) { + res->flags |= FLAG_UNPREDICTABLE; + } + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* Encoding T1 */ + /* pattern="11111,0110,001,Rn.4,Ra.4,Rd.4,00,0,1,Rm.4" width=32 stringency=16 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFFF000F0)==0xFB100010)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ARMv6T2) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_Rn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Rn >> 6] |= 1LL << (FIELD_Rn & 63); + char Rn_width = 4; + res->fields[FIELD_Ra] = (instr & 0xF000)>>12; + res->fields_mask[FIELD_Ra >> 6] |= 1LL << (FIELD_Ra & 63); + char Ra_width = 4; + res->fields[FIELD_Rd] = (instr & 0xF00)>>8; + res->fields_mask[FIELD_Rd >> 6] |= 1LL << (FIELD_Rd & 63); + char Rd_width = 4; + res->fields[FIELD_Rm] = instr & 0xF; + res->fields_mask[FIELD_Rm >> 6] |= 1LL << (FIELD_Rm & 63); + char Rm_width = 4; + + static const instruction_format instr_formats[] = + { + { /* SMLABT<c> <Rd>,<Rn>,<Rm>,<Ra> */ + "smlabt", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rd,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rn,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rm,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Ra,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 4 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_SMLABT; + + /* pcode: if Ra == '1111' then SEE SMULBB, SMULBT, SMULTB, SMULTT */ + if((res->fields[FIELD_Ra]) == (0xF)) { + + return smulbb_smulbt_smultb_smultt(req, res); + } + /* pcode: d = UInt(Rd) */ + res->fields[FIELD_d] = (res->fields[FIELD_Rd]); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: n = UInt(Rn) */ + res->fields[FIELD_n] = (res->fields[FIELD_Rn]); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: m = UInt(Rm) */ + res->fields[FIELD_m] = (res->fields[FIELD_Rm]); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + /* pcode: a = UInt(Ra) */ + res->fields[FIELD_a] = (res->fields[FIELD_Ra]); + res->fields_mask[FIELD_a >> 6] |= 1LL << (FIELD_a & 63); + /* pcode: if BadReg(d) || BadReg(n) || BadReg(m) || a == 13 then UNPREDICTABLE */ + if((((BadReg(res->fields[FIELD_d])) || (BadReg(res->fields[FIELD_n]))) || (BadReg(res->fields[FIELD_m]))) || ((res->fields[FIELD_a]) == (13))) { + res->flags |= FLAG_UNPREDICTABLE; + } + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* Encoding T1 */ + /* pattern="11111,0110,001,Rn.4,Ra.4,Rd.4,00,1,0,Rm.4" width=32 stringency=16 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFFF000F0)==0xFB100020)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ARMv6T2) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_Rn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Rn >> 6] |= 1LL << (FIELD_Rn & 63); + char Rn_width = 4; + res->fields[FIELD_Ra] = (instr & 0xF000)>>12; + res->fields_mask[FIELD_Ra >> 6] |= 1LL << (FIELD_Ra & 63); + char Ra_width = 4; + res->fields[FIELD_Rd] = (instr & 0xF00)>>8; + res->fields_mask[FIELD_Rd >> 6] |= 1LL << (FIELD_Rd & 63); + char Rd_width = 4; + res->fields[FIELD_Rm] = instr & 0xF; + res->fields_mask[FIELD_Rm >> 6] |= 1LL << (FIELD_Rm & 63); + char Rm_width = 4; + + static const instruction_format instr_formats[] = + { + { /* SMLATB<c> <Rd>,<Rn>,<Rm>,<Ra> */ + "smlatb", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rd,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rn,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rm,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Ra,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 4 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_SMLATB; + + /* pcode: if Ra == '1111' then SEE SMULBB, SMULBT, SMULTB, SMULTT */ + if((res->fields[FIELD_Ra]) == (0xF)) { + + return smulbb_smulbt_smultb_smultt(req, res); + } + /* pcode: d = UInt(Rd) */ + res->fields[FIELD_d] = (res->fields[FIELD_Rd]); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: n = UInt(Rn) */ + res->fields[FIELD_n] = (res->fields[FIELD_Rn]); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: m = UInt(Rm) */ + res->fields[FIELD_m] = (res->fields[FIELD_Rm]); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + /* pcode: a = UInt(Ra) */ + res->fields[FIELD_a] = (res->fields[FIELD_Ra]); + res->fields_mask[FIELD_a >> 6] |= 1LL << (FIELD_a & 63); + /* pcode: if BadReg(d) || BadReg(n) || BadReg(m) || a == 13 then UNPREDICTABLE */ + if((((BadReg(res->fields[FIELD_d])) || (BadReg(res->fields[FIELD_n]))) || (BadReg(res->fields[FIELD_m]))) || ((res->fields[FIELD_a]) == (13))) { + res->flags |= FLAG_UNPREDICTABLE; + } + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* Encoding T1 */ + /* pattern="11111,0110,001,Rn.4,Ra.4,Rd.4,00,1,1,Rm.4" width=32 stringency=16 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFFF000F0)==0xFB100030)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ARMv6T2) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_Rn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Rn >> 6] |= 1LL << (FIELD_Rn & 63); + char Rn_width = 4; + res->fields[FIELD_Ra] = (instr & 0xF000)>>12; + res->fields_mask[FIELD_Ra >> 6] |= 1LL << (FIELD_Ra & 63); + char Ra_width = 4; + res->fields[FIELD_Rd] = (instr & 0xF00)>>8; + res->fields_mask[FIELD_Rd >> 6] |= 1LL << (FIELD_Rd & 63); + char Rd_width = 4; + res->fields[FIELD_Rm] = instr & 0xF; + res->fields_mask[FIELD_Rm >> 6] |= 1LL << (FIELD_Rm & 63); + char Rm_width = 4; + + static const instruction_format instr_formats[] = + { + { /* SMLATT<c> <Rd>,<Rn>,<Rm>,<Ra> */ + "smlatt", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rd,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rn,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rm,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Ra,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 4 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_SMLATT; + + /* pcode: if Ra == '1111' then SEE SMULBB, SMULBT, SMULTB, SMULTT */ + if((res->fields[FIELD_Ra]) == (0xF)) { + + return smulbb_smulbt_smultb_smultt(req, res); + } + /* pcode: d = UInt(Rd) */ + res->fields[FIELD_d] = (res->fields[FIELD_Rd]); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: n = UInt(Rn) */ + res->fields[FIELD_n] = (res->fields[FIELD_Rn]); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: m = UInt(Rm) */ + res->fields[FIELD_m] = (res->fields[FIELD_Rm]); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + /* pcode: a = UInt(Ra) */ + res->fields[FIELD_a] = (res->fields[FIELD_Ra]); + res->fields_mask[FIELD_a >> 6] |= 1LL << (FIELD_a & 63); + /* pcode: if BadReg(d) || BadReg(n) || BadReg(m) || a == 13 then UNPREDICTABLE */ + if((((BadReg(res->fields[FIELD_d])) || (BadReg(res->fields[FIELD_n]))) || (BadReg(res->fields[FIELD_m]))) || ((res->fields[FIELD_a]) == (13))) { + res->flags |= FLAG_UNPREDICTABLE; + } + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: 3562FE93 +int smlad(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + /* Encoding T1 */ + /* pattern="11111,0110,010,Rn.4,Ra.4,Rd.4,000,0,Rm.4" width=32 stringency=16 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFFF000F0)==0xFB200000)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ARMv6T2) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_Rn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Rn >> 6] |= 1LL << (FIELD_Rn & 63); + char Rn_width = 4; + res->fields[FIELD_Ra] = (instr & 0xF000)>>12; + res->fields_mask[FIELD_Ra >> 6] |= 1LL << (FIELD_Ra & 63); + char Ra_width = 4; + res->fields[FIELD_Rd] = (instr & 0xF00)>>8; + res->fields_mask[FIELD_Rd >> 6] |= 1LL << (FIELD_Rd & 63); + char Rd_width = 4; + res->fields[FIELD_Rm] = instr & 0xF; + res->fields_mask[FIELD_Rm >> 6] |= 1LL << (FIELD_Rm & 63); + char Rm_width = 4; + + static const instruction_format instr_formats[] = + { + { /* SMLAD<c> <Rd>,<Rn>,<Rm>,<Ra> */ + "smlad", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rd,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rn,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rm,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Ra,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 4 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_SMLAD; + + /* pcode: M=0 */ + res->fields[FIELD_M] = 0; + res->fields_mask[FIELD_M >> 6] |= 1LL << (FIELD_M & 63); + /* pcode: if Ra == '1111' then SEE SMUAD */ + if((res->fields[FIELD_Ra]) == (0xF)) { + + return smuad(req, res); + } + /* pcode: d = UInt(Rd) */ + res->fields[FIELD_d] = (res->fields[FIELD_Rd]); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: n = UInt(Rn) */ + res->fields[FIELD_n] = (res->fields[FIELD_Rn]); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: m = UInt(Rm) */ + res->fields[FIELD_m] = (res->fields[FIELD_Rm]); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + /* pcode: a = UInt(Ra) */ + res->fields[FIELD_a] = (res->fields[FIELD_Ra]); + res->fields_mask[FIELD_a >> 6] |= 1LL << (FIELD_a & 63); + /* pcode: m_swap = (M == '1') */ + res->fields[FIELD_m_swap] = ((res->fields[FIELD_M]) == (0x1)); + res->fields_mask[FIELD_m_swap >> 6] |= 1LL << (FIELD_m_swap & 63); + /* pcode: if BadReg(d) || BadReg(n) || BadReg(m) || a == 13 then UNPREDICTABLE */ + if((((BadReg(res->fields[FIELD_d])) || (BadReg(res->fields[FIELD_n]))) || (BadReg(res->fields[FIELD_m]))) || ((res->fields[FIELD_a]) == (13))) { + res->flags |= FLAG_UNPREDICTABLE; + } + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* Encoding T1 */ + /* pattern="11111,0110,010,Rn.4,Ra.4,Rd.4,000,1,Rm.4" width=32 stringency=16 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFFF000F0)==0xFB200010)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ARMv6T2) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_Rn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Rn >> 6] |= 1LL << (FIELD_Rn & 63); + char Rn_width = 4; + res->fields[FIELD_Ra] = (instr & 0xF000)>>12; + res->fields_mask[FIELD_Ra >> 6] |= 1LL << (FIELD_Ra & 63); + char Ra_width = 4; + res->fields[FIELD_Rd] = (instr & 0xF00)>>8; + res->fields_mask[FIELD_Rd >> 6] |= 1LL << (FIELD_Rd & 63); + char Rd_width = 4; + res->fields[FIELD_Rm] = instr & 0xF; + res->fields_mask[FIELD_Rm >> 6] |= 1LL << (FIELD_Rm & 63); + char Rm_width = 4; + + static const instruction_format instr_formats[] = + { + { /* SMLADX<c> <Rd>,<Rn>,<Rm>,<Ra> */ + "smladx", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rd,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rn,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rm,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Ra,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 4 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_SMLADX; + + /* pcode: M=1 */ + res->fields[FIELD_M] = 1; + res->fields_mask[FIELD_M >> 6] |= 1LL << (FIELD_M & 63); + /* pcode: if Ra == '1111' then SEE SMUAD */ + if((res->fields[FIELD_Ra]) == (0xF)) { + + return smuad(req, res); + } + /* pcode: d = UInt(Rd) */ + res->fields[FIELD_d] = (res->fields[FIELD_Rd]); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: n = UInt(Rn) */ + res->fields[FIELD_n] = (res->fields[FIELD_Rn]); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: m = UInt(Rm) */ + res->fields[FIELD_m] = (res->fields[FIELD_Rm]); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + /* pcode: a = UInt(Ra) */ + res->fields[FIELD_a] = (res->fields[FIELD_Ra]); + res->fields_mask[FIELD_a >> 6] |= 1LL << (FIELD_a & 63); + /* pcode: m_swap = (M == '1') */ + res->fields[FIELD_m_swap] = ((res->fields[FIELD_M]) == (0x1)); + res->fields_mask[FIELD_m_swap >> 6] |= 1LL << (FIELD_m_swap & 63); + /* pcode: if BadReg(d) || BadReg(n) || BadReg(m) || a == 13 then UNPREDICTABLE */ + if((((BadReg(res->fields[FIELD_d])) || (BadReg(res->fields[FIELD_n]))) || (BadReg(res->fields[FIELD_m]))) || ((res->fields[FIELD_a]) == (13))) { + res->flags |= FLAG_UNPREDICTABLE; + } + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: AA80830E +int smlal(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + /* Encoding T1 */ + /* pattern="11111,0111,1,00,Rn.4,RdLo.4,RdHi.4,0000,Rm.4" width=32 stringency=16 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFFF000F0)==0xFBC00000)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ARMv6T2) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_Rn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Rn >> 6] |= 1LL << (FIELD_Rn & 63); + char Rn_width = 4; + res->fields[FIELD_RdLo] = (instr & 0xF000)>>12; + res->fields_mask[FIELD_RdLo >> 6] |= 1LL << (FIELD_RdLo & 63); + char RdLo_width = 4; + res->fields[FIELD_RdHi] = (instr & 0xF00)>>8; + res->fields_mask[FIELD_RdHi >> 6] |= 1LL << (FIELD_RdHi & 63); + char RdHi_width = 4; + res->fields[FIELD_Rm] = instr & 0xF; + res->fields_mask[FIELD_Rm >> 6] |= 1LL << (FIELD_Rm & 63); + char Rm_width = 4; + + static const instruction_format instr_formats[] = + { + { /* SMLAL<c> <RdLo>,<RdHi>,<Rn>,<Rm> */ + "smlal", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_RdLo,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_RdHi,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rn,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rm,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 4 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_SMLAL; + + /* pcode: dLo = UInt(RdLo) */ + res->fields[FIELD_dLo] = (res->fields[FIELD_RdLo]); + res->fields_mask[FIELD_dLo >> 6] |= 1LL << (FIELD_dLo & 63); + /* pcode: dHi = UInt(RdHi) */ + res->fields[FIELD_dHi] = (res->fields[FIELD_RdHi]); + res->fields_mask[FIELD_dHi >> 6] |= 1LL << (FIELD_dHi & 63); + /* pcode: n = UInt(Rn) */ + res->fields[FIELD_n] = (res->fields[FIELD_Rn]); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: m = UInt(Rm) */ + res->fields[FIELD_m] = (res->fields[FIELD_Rm]); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + /* pcode: setflags = FALSE */ + res->fields[FIELD_setflags] = 0; + res->fields_mask[FIELD_setflags >> 6] |= 1LL << (FIELD_setflags & 63); + /* pcode: if BadReg(dLo) || BadReg(dHi) || BadReg(n) || BadReg(m) then UNPREDICTABLE */ + if((((BadReg(res->fields[FIELD_dLo])) || (BadReg(res->fields[FIELD_dHi]))) || (BadReg(res->fields[FIELD_n]))) || (BadReg(res->fields[FIELD_m]))) { + res->flags |= FLAG_UNPREDICTABLE; + } + /* pcode: if dHi == dLo then UNPREDICTABLE */ + if((res->fields[FIELD_dHi]) == (res->fields[FIELD_dLo])) { + res->flags |= FLAG_UNPREDICTABLE; + } + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: AEF2A4E7 +int smlalbb_smlalbt_smlaltb_smlaltt(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + /* Encoding T1 */ + /* pattern="11111,0111,100,Rn.4,RdLo.4,RdHi.4,10,00,Rm.4" width=32 stringency=16 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFFF000F0)==0xFBC00080)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ARMv6T2) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_Rn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Rn >> 6] |= 1LL << (FIELD_Rn & 63); + char Rn_width = 4; + res->fields[FIELD_RdLo] = (instr & 0xF000)>>12; + res->fields_mask[FIELD_RdLo >> 6] |= 1LL << (FIELD_RdLo & 63); + char RdLo_width = 4; + res->fields[FIELD_RdHi] = (instr & 0xF00)>>8; + res->fields_mask[FIELD_RdHi >> 6] |= 1LL << (FIELD_RdHi & 63); + char RdHi_width = 4; + res->fields[FIELD_Rm] = instr & 0xF; + res->fields_mask[FIELD_Rm >> 6] |= 1LL << (FIELD_Rm & 63); + char Rm_width = 4; + + static const instruction_format instr_formats[] = + { + { /* SMLALBB<c> <RdLo>,<RdHi>,<Rn>,<Rm> */ + "smlalbb", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_RdLo,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_RdHi,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rn,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rm,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 4 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_SMLALBB; + + /* pcode: N=0 */ + res->fields[FIELD_N] = 0; + res->fields_mask[FIELD_N >> 6] |= 1LL << (FIELD_N & 63); + /* pcode: M=0 */ + res->fields[FIELD_M] = 0; + res->fields_mask[FIELD_M >> 6] |= 1LL << (FIELD_M & 63); + /* pcode: dLo = UInt(RdLo) */ + res->fields[FIELD_dLo] = (res->fields[FIELD_RdLo]); + res->fields_mask[FIELD_dLo >> 6] |= 1LL << (FIELD_dLo & 63); + /* pcode: dHi = UInt(RdHi) */ + res->fields[FIELD_dHi] = (res->fields[FIELD_RdHi]); + res->fields_mask[FIELD_dHi >> 6] |= 1LL << (FIELD_dHi & 63); + /* pcode: n = UInt(Rn) */ + res->fields[FIELD_n] = (res->fields[FIELD_Rn]); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: m = UInt(Rm) */ + res->fields[FIELD_m] = (res->fields[FIELD_Rm]); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + /* pcode: n_high = (N == '1') */ + res->fields[FIELD_n_high] = ((res->fields[FIELD_N]) == (0x1)); + res->fields_mask[FIELD_n_high >> 6] |= 1LL << (FIELD_n_high & 63); + /* pcode: m_high = (M == '1') */ + res->fields[FIELD_m_high] = ((res->fields[FIELD_M]) == (0x1)); + res->fields_mask[FIELD_m_high >> 6] |= 1LL << (FIELD_m_high & 63); + /* pcode: if BadReg(dLo) || BadReg(dHi) || BadReg(n) || BadReg(m) then UNPREDICTABLE */ + if((((BadReg(res->fields[FIELD_dLo])) || (BadReg(res->fields[FIELD_dHi]))) || (BadReg(res->fields[FIELD_n]))) || (BadReg(res->fields[FIELD_m]))) { + res->flags |= FLAG_UNPREDICTABLE; + } + /* pcode: if dHi == dLo then UNPREDICTABLE */ + if((res->fields[FIELD_dHi]) == (res->fields[FIELD_dLo])) { + res->flags |= FLAG_UNPREDICTABLE; + } + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* Encoding T1 */ + /* pattern="11111,0111,100,Rn.4,RdLo.4,RdHi.4,10,01,Rm.4" width=32 stringency=16 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFFF000F0)==0xFBC00090)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ARMv6T2) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_Rn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Rn >> 6] |= 1LL << (FIELD_Rn & 63); + char Rn_width = 4; + res->fields[FIELD_RdLo] = (instr & 0xF000)>>12; + res->fields_mask[FIELD_RdLo >> 6] |= 1LL << (FIELD_RdLo & 63); + char RdLo_width = 4; + res->fields[FIELD_RdHi] = (instr & 0xF00)>>8; + res->fields_mask[FIELD_RdHi >> 6] |= 1LL << (FIELD_RdHi & 63); + char RdHi_width = 4; + res->fields[FIELD_Rm] = instr & 0xF; + res->fields_mask[FIELD_Rm >> 6] |= 1LL << (FIELD_Rm & 63); + char Rm_width = 4; + + static const instruction_format instr_formats[] = + { + { /* SMLALBT<c> <RdLo>,<RdHi>,<Rn>,<Rm> */ + "smlalbt", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_RdLo,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_RdHi,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rn,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rm,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 4 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_SMLALBT; + + /* pcode: N=0 */ + res->fields[FIELD_N] = 0; + res->fields_mask[FIELD_N >> 6] |= 1LL << (FIELD_N & 63); + /* pcode: M=1 */ + res->fields[FIELD_M] = 1; + res->fields_mask[FIELD_M >> 6] |= 1LL << (FIELD_M & 63); + /* pcode: dLo = UInt(RdLo) */ + res->fields[FIELD_dLo] = (res->fields[FIELD_RdLo]); + res->fields_mask[FIELD_dLo >> 6] |= 1LL << (FIELD_dLo & 63); + /* pcode: dHi = UInt(RdHi) */ + res->fields[FIELD_dHi] = (res->fields[FIELD_RdHi]); + res->fields_mask[FIELD_dHi >> 6] |= 1LL << (FIELD_dHi & 63); + /* pcode: n = UInt(Rn) */ + res->fields[FIELD_n] = (res->fields[FIELD_Rn]); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: m = UInt(Rm) */ + res->fields[FIELD_m] = (res->fields[FIELD_Rm]); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + /* pcode: n_high = (N == '1') */ + res->fields[FIELD_n_high] = ((res->fields[FIELD_N]) == (0x1)); + res->fields_mask[FIELD_n_high >> 6] |= 1LL << (FIELD_n_high & 63); + /* pcode: m_high = (M == '1') */ + res->fields[FIELD_m_high] = ((res->fields[FIELD_M]) == (0x1)); + res->fields_mask[FIELD_m_high >> 6] |= 1LL << (FIELD_m_high & 63); + /* pcode: if BadReg(dLo) || BadReg(dHi) || BadReg(n) || BadReg(m) then UNPREDICTABLE */ + if((((BadReg(res->fields[FIELD_dLo])) || (BadReg(res->fields[FIELD_dHi]))) || (BadReg(res->fields[FIELD_n]))) || (BadReg(res->fields[FIELD_m]))) { + res->flags |= FLAG_UNPREDICTABLE; + } + /* pcode: if dHi == dLo then UNPREDICTABLE */ + if((res->fields[FIELD_dHi]) == (res->fields[FIELD_dLo])) { + res->flags |= FLAG_UNPREDICTABLE; + } + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* Encoding T1 */ + /* pattern="11111,0111,100,Rn.4,RdLo.4,RdHi.4,10,10,Rm.4" width=32 stringency=16 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFFF000F0)==0xFBC000A0)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ARMv6T2) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_Rn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Rn >> 6] |= 1LL << (FIELD_Rn & 63); + char Rn_width = 4; + res->fields[FIELD_RdLo] = (instr & 0xF000)>>12; + res->fields_mask[FIELD_RdLo >> 6] |= 1LL << (FIELD_RdLo & 63); + char RdLo_width = 4; + res->fields[FIELD_RdHi] = (instr & 0xF00)>>8; + res->fields_mask[FIELD_RdHi >> 6] |= 1LL << (FIELD_RdHi & 63); + char RdHi_width = 4; + res->fields[FIELD_Rm] = instr & 0xF; + res->fields_mask[FIELD_Rm >> 6] |= 1LL << (FIELD_Rm & 63); + char Rm_width = 4; + + static const instruction_format instr_formats[] = + { + { /* SMLALTB<c> <RdLo>,<RdHi>,<Rn>,<Rm> */ + "smlaltb", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_RdLo,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_RdHi,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rn,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rm,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 4 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_SMLALTB; + + /* pcode: N=1 */ + res->fields[FIELD_N] = 1; + res->fields_mask[FIELD_N >> 6] |= 1LL << (FIELD_N & 63); + /* pcode: M=0 */ + res->fields[FIELD_M] = 0; + res->fields_mask[FIELD_M >> 6] |= 1LL << (FIELD_M & 63); + /* pcode: dLo = UInt(RdLo) */ + res->fields[FIELD_dLo] = (res->fields[FIELD_RdLo]); + res->fields_mask[FIELD_dLo >> 6] |= 1LL << (FIELD_dLo & 63); + /* pcode: dHi = UInt(RdHi) */ + res->fields[FIELD_dHi] = (res->fields[FIELD_RdHi]); + res->fields_mask[FIELD_dHi >> 6] |= 1LL << (FIELD_dHi & 63); + /* pcode: n = UInt(Rn) */ + res->fields[FIELD_n] = (res->fields[FIELD_Rn]); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: m = UInt(Rm) */ + res->fields[FIELD_m] = (res->fields[FIELD_Rm]); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + /* pcode: n_high = (N == '1') */ + res->fields[FIELD_n_high] = ((res->fields[FIELD_N]) == (0x1)); + res->fields_mask[FIELD_n_high >> 6] |= 1LL << (FIELD_n_high & 63); + /* pcode: m_high = (M == '1') */ + res->fields[FIELD_m_high] = ((res->fields[FIELD_M]) == (0x1)); + res->fields_mask[FIELD_m_high >> 6] |= 1LL << (FIELD_m_high & 63); + /* pcode: if BadReg(dLo) || BadReg(dHi) || BadReg(n) || BadReg(m) then UNPREDICTABLE */ + if((((BadReg(res->fields[FIELD_dLo])) || (BadReg(res->fields[FIELD_dHi]))) || (BadReg(res->fields[FIELD_n]))) || (BadReg(res->fields[FIELD_m]))) { + res->flags |= FLAG_UNPREDICTABLE; + } + /* pcode: if dHi == dLo then UNPREDICTABLE */ + if((res->fields[FIELD_dHi]) == (res->fields[FIELD_dLo])) { + res->flags |= FLAG_UNPREDICTABLE; + } + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* Encoding T1 */ + /* pattern="11111,0111,100,Rn.4,RdLo.4,RdHi.4,10,11,Rm.4" width=32 stringency=16 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFFF000F0)==0xFBC000B0)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ARMv6T2) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_Rn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Rn >> 6] |= 1LL << (FIELD_Rn & 63); + char Rn_width = 4; + res->fields[FIELD_RdLo] = (instr & 0xF000)>>12; + res->fields_mask[FIELD_RdLo >> 6] |= 1LL << (FIELD_RdLo & 63); + char RdLo_width = 4; + res->fields[FIELD_RdHi] = (instr & 0xF00)>>8; + res->fields_mask[FIELD_RdHi >> 6] |= 1LL << (FIELD_RdHi & 63); + char RdHi_width = 4; + res->fields[FIELD_Rm] = instr & 0xF; + res->fields_mask[FIELD_Rm >> 6] |= 1LL << (FIELD_Rm & 63); + char Rm_width = 4; + + static const instruction_format instr_formats[] = + { + { /* SMLALTT<c> <RdLo>,<RdHi>,<Rn>,<Rm> */ + "smlaltt", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_RdLo,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_RdHi,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rn,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rm,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 4 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_SMLALTT; + + /* pcode: N=1 */ + res->fields[FIELD_N] = 1; + res->fields_mask[FIELD_N >> 6] |= 1LL << (FIELD_N & 63); + /* pcode: M=1 */ + res->fields[FIELD_M] = 1; + res->fields_mask[FIELD_M >> 6] |= 1LL << (FIELD_M & 63); + /* pcode: dLo = UInt(RdLo) */ + res->fields[FIELD_dLo] = (res->fields[FIELD_RdLo]); + res->fields_mask[FIELD_dLo >> 6] |= 1LL << (FIELD_dLo & 63); + /* pcode: dHi = UInt(RdHi) */ + res->fields[FIELD_dHi] = (res->fields[FIELD_RdHi]); + res->fields_mask[FIELD_dHi >> 6] |= 1LL << (FIELD_dHi & 63); + /* pcode: n = UInt(Rn) */ + res->fields[FIELD_n] = (res->fields[FIELD_Rn]); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: m = UInt(Rm) */ + res->fields[FIELD_m] = (res->fields[FIELD_Rm]); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + /* pcode: n_high = (N == '1') */ + res->fields[FIELD_n_high] = ((res->fields[FIELD_N]) == (0x1)); + res->fields_mask[FIELD_n_high >> 6] |= 1LL << (FIELD_n_high & 63); + /* pcode: m_high = (M == '1') */ + res->fields[FIELD_m_high] = ((res->fields[FIELD_M]) == (0x1)); + res->fields_mask[FIELD_m_high >> 6] |= 1LL << (FIELD_m_high & 63); + /* pcode: if BadReg(dLo) || BadReg(dHi) || BadReg(n) || BadReg(m) then UNPREDICTABLE */ + if((((BadReg(res->fields[FIELD_dLo])) || (BadReg(res->fields[FIELD_dHi]))) || (BadReg(res->fields[FIELD_n]))) || (BadReg(res->fields[FIELD_m]))) { + res->flags |= FLAG_UNPREDICTABLE; + } + /* pcode: if dHi == dLo then UNPREDICTABLE */ + if((res->fields[FIELD_dHi]) == (res->fields[FIELD_dLo])) { + res->flags |= FLAG_UNPREDICTABLE; + } + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: E33D1699 +int smlald(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + /* Encoding T1 */ + /* pattern="11111,0111,100,Rn.4,RdLo.4,RdHi.4,110,0,Rm.4" width=32 stringency=16 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFFF000F0)==0xFBC000C0)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ARMv6T2) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_Rn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Rn >> 6] |= 1LL << (FIELD_Rn & 63); + char Rn_width = 4; + res->fields[FIELD_RdLo] = (instr & 0xF000)>>12; + res->fields_mask[FIELD_RdLo >> 6] |= 1LL << (FIELD_RdLo & 63); + char RdLo_width = 4; + res->fields[FIELD_RdHi] = (instr & 0xF00)>>8; + res->fields_mask[FIELD_RdHi >> 6] |= 1LL << (FIELD_RdHi & 63); + char RdHi_width = 4; + res->fields[FIELD_Rm] = instr & 0xF; + res->fields_mask[FIELD_Rm >> 6] |= 1LL << (FIELD_Rm & 63); + char Rm_width = 4; + + static const instruction_format instr_formats[] = + { + { /* SMLALD<c> <RdLo>,<RdHi>,<Rn>,<Rm> */ + "smlald", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_RdLo,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_RdHi,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rn,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rm,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 4 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_SMLALD; + + /* pcode: M=0 */ + res->fields[FIELD_M] = 0; + res->fields_mask[FIELD_M >> 6] |= 1LL << (FIELD_M & 63); + /* pcode: dLo = UInt(RdLo) */ + res->fields[FIELD_dLo] = (res->fields[FIELD_RdLo]); + res->fields_mask[FIELD_dLo >> 6] |= 1LL << (FIELD_dLo & 63); + /* pcode: dHi = UInt(RdHi) */ + res->fields[FIELD_dHi] = (res->fields[FIELD_RdHi]); + res->fields_mask[FIELD_dHi >> 6] |= 1LL << (FIELD_dHi & 63); + /* pcode: n = UInt(Rn) */ + res->fields[FIELD_n] = (res->fields[FIELD_Rn]); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: m = UInt(Rm) */ + res->fields[FIELD_m] = (res->fields[FIELD_Rm]); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + /* pcode: m_swap = (M == '1') */ + res->fields[FIELD_m_swap] = ((res->fields[FIELD_M]) == (0x1)); + res->fields_mask[FIELD_m_swap >> 6] |= 1LL << (FIELD_m_swap & 63); + /* pcode: if BadReg(dLo) || BadReg(dHi) || BadReg(n) || BadReg(m) then UNPREDICTABLE */ + if((((BadReg(res->fields[FIELD_dLo])) || (BadReg(res->fields[FIELD_dHi]))) || (BadReg(res->fields[FIELD_n]))) || (BadReg(res->fields[FIELD_m]))) { + res->flags |= FLAG_UNPREDICTABLE; + } + /* pcode: if dHi == dLo then UNPREDICTABLE */ + if((res->fields[FIELD_dHi]) == (res->fields[FIELD_dLo])) { + res->flags |= FLAG_UNPREDICTABLE; + } + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* Encoding T1 */ + /* pattern="11111,0111,100,Rn.4,RdLo.4,RdHi.4,110,1,Rm.4" width=32 stringency=16 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFFF000F0)==0xFBC000D0)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ARMv6T2) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_Rn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Rn >> 6] |= 1LL << (FIELD_Rn & 63); + char Rn_width = 4; + res->fields[FIELD_RdLo] = (instr & 0xF000)>>12; + res->fields_mask[FIELD_RdLo >> 6] |= 1LL << (FIELD_RdLo & 63); + char RdLo_width = 4; + res->fields[FIELD_RdHi] = (instr & 0xF00)>>8; + res->fields_mask[FIELD_RdHi >> 6] |= 1LL << (FIELD_RdHi & 63); + char RdHi_width = 4; + res->fields[FIELD_Rm] = instr & 0xF; + res->fields_mask[FIELD_Rm >> 6] |= 1LL << (FIELD_Rm & 63); + char Rm_width = 4; + + static const instruction_format instr_formats[] = + { + { /* SMLALDX<c> <RdLo>,<RdHi>,<Rn>,<Rm> */ + "smlaldx", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_RdLo,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_RdHi,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rn,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rm,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 4 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_SMLALDX; + + /* pcode: M=1 */ + res->fields[FIELD_M] = 1; + res->fields_mask[FIELD_M >> 6] |= 1LL << (FIELD_M & 63); + /* pcode: dLo = UInt(RdLo) */ + res->fields[FIELD_dLo] = (res->fields[FIELD_RdLo]); + res->fields_mask[FIELD_dLo >> 6] |= 1LL << (FIELD_dLo & 63); + /* pcode: dHi = UInt(RdHi) */ + res->fields[FIELD_dHi] = (res->fields[FIELD_RdHi]); + res->fields_mask[FIELD_dHi >> 6] |= 1LL << (FIELD_dHi & 63); + /* pcode: n = UInt(Rn) */ + res->fields[FIELD_n] = (res->fields[FIELD_Rn]); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: m = UInt(Rm) */ + res->fields[FIELD_m] = (res->fields[FIELD_Rm]); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + /* pcode: m_swap = (M == '1') */ + res->fields[FIELD_m_swap] = ((res->fields[FIELD_M]) == (0x1)); + res->fields_mask[FIELD_m_swap >> 6] |= 1LL << (FIELD_m_swap & 63); + /* pcode: if BadReg(dLo) || BadReg(dHi) || BadReg(n) || BadReg(m) then UNPREDICTABLE */ + if((((BadReg(res->fields[FIELD_dLo])) || (BadReg(res->fields[FIELD_dHi]))) || (BadReg(res->fields[FIELD_n]))) || (BadReg(res->fields[FIELD_m]))) { + res->flags |= FLAG_UNPREDICTABLE; + } + /* pcode: if dHi == dLo then UNPREDICTABLE */ + if((res->fields[FIELD_dHi]) == (res->fields[FIELD_dLo])) { + res->flags |= FLAG_UNPREDICTABLE; + } + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: 500DF989 +int smlawb_smlawt(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + /* Encoding T1 */ + /* pattern="11111,0110,011,Rn.4,Ra.4,Rd.4,000,0,Rm.4" width=32 stringency=16 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFFF000F0)==0xFB300000)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ARMv6T2) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_Rn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Rn >> 6] |= 1LL << (FIELD_Rn & 63); + char Rn_width = 4; + res->fields[FIELD_Ra] = (instr & 0xF000)>>12; + res->fields_mask[FIELD_Ra >> 6] |= 1LL << (FIELD_Ra & 63); + char Ra_width = 4; + res->fields[FIELD_Rd] = (instr & 0xF00)>>8; + res->fields_mask[FIELD_Rd >> 6] |= 1LL << (FIELD_Rd & 63); + char Rd_width = 4; + res->fields[FIELD_Rm] = instr & 0xF; + res->fields_mask[FIELD_Rm >> 6] |= 1LL << (FIELD_Rm & 63); + char Rm_width = 4; + + static const instruction_format instr_formats[] = + { + { /* SMLAWB<c> <Rd>,<Rn>,<Rm>,<Ra> */ + "smlawb", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rd,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rn,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rm,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Ra,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 4 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_SMLAWB; + + /* pcode: M=0 */ + res->fields[FIELD_M] = 0; + res->fields_mask[FIELD_M >> 6] |= 1LL << (FIELD_M & 63); + /* pcode: if Ra == '1111' then SEE SMULWB, SMULWT */ + if((res->fields[FIELD_Ra]) == (0xF)) { + + return smulwb_smulwt(req, res); + } + /* pcode: d = UInt(Rd) */ + res->fields[FIELD_d] = (res->fields[FIELD_Rd]); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: n = UInt(Rn) */ + res->fields[FIELD_n] = (res->fields[FIELD_Rn]); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: m = UInt(Rm) */ + res->fields[FIELD_m] = (res->fields[FIELD_Rm]); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + /* pcode: a = UInt(Ra) */ + res->fields[FIELD_a] = (res->fields[FIELD_Ra]); + res->fields_mask[FIELD_a >> 6] |= 1LL << (FIELD_a & 63); + /* pcode: m_high = (M == '1') */ + res->fields[FIELD_m_high] = ((res->fields[FIELD_M]) == (0x1)); + res->fields_mask[FIELD_m_high >> 6] |= 1LL << (FIELD_m_high & 63); + /* pcode: if BadReg(d) || BadReg(n) || BadReg(m) || a == 13 then UNPREDICTABLE */ + if((((BadReg(res->fields[FIELD_d])) || (BadReg(res->fields[FIELD_n]))) || (BadReg(res->fields[FIELD_m]))) || ((res->fields[FIELD_a]) == (13))) { + res->flags |= FLAG_UNPREDICTABLE; + } + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* Encoding T1 */ + /* pattern="11111,0110,011,Rn.4,Ra.4,Rd.4,000,1,Rm.4" width=32 stringency=16 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFFF000F0)==0xFB300010)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ARMv6T2) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_Rn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Rn >> 6] |= 1LL << (FIELD_Rn & 63); + char Rn_width = 4; + res->fields[FIELD_Ra] = (instr & 0xF000)>>12; + res->fields_mask[FIELD_Ra >> 6] |= 1LL << (FIELD_Ra & 63); + char Ra_width = 4; + res->fields[FIELD_Rd] = (instr & 0xF00)>>8; + res->fields_mask[FIELD_Rd >> 6] |= 1LL << (FIELD_Rd & 63); + char Rd_width = 4; + res->fields[FIELD_Rm] = instr & 0xF; + res->fields_mask[FIELD_Rm >> 6] |= 1LL << (FIELD_Rm & 63); + char Rm_width = 4; + + static const instruction_format instr_formats[] = + { + { /* SMLAWT<c> <Rd>,<Rn>,<Rm>,<Ra> */ + "smlawt", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rd,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rn,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rm,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Ra,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 4 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_SMLAWT; + + /* pcode: M=1 */ + res->fields[FIELD_M] = 1; + res->fields_mask[FIELD_M >> 6] |= 1LL << (FIELD_M & 63); + /* pcode: if Ra == '1111' then SEE SMULWB, SMULWT */ + if((res->fields[FIELD_Ra]) == (0xF)) { + + return smulwb_smulwt(req, res); + } + /* pcode: d = UInt(Rd) */ + res->fields[FIELD_d] = (res->fields[FIELD_Rd]); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: n = UInt(Rn) */ + res->fields[FIELD_n] = (res->fields[FIELD_Rn]); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: m = UInt(Rm) */ + res->fields[FIELD_m] = (res->fields[FIELD_Rm]); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + /* pcode: a = UInt(Ra) */ + res->fields[FIELD_a] = (res->fields[FIELD_Ra]); + res->fields_mask[FIELD_a >> 6] |= 1LL << (FIELD_a & 63); + /* pcode: m_high = (M == '1') */ + res->fields[FIELD_m_high] = ((res->fields[FIELD_M]) == (0x1)); + res->fields_mask[FIELD_m_high >> 6] |= 1LL << (FIELD_m_high & 63); + /* pcode: if BadReg(d) || BadReg(n) || BadReg(m) || a == 13 then UNPREDICTABLE */ + if((((BadReg(res->fields[FIELD_d])) || (BadReg(res->fields[FIELD_n]))) || (BadReg(res->fields[FIELD_m]))) || ((res->fields[FIELD_a]) == (13))) { + res->flags |= FLAG_UNPREDICTABLE; + } + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: F673146C +int smlsd(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + /* Encoding T1 */ + /* pattern="11111,0110,100,Rn.4,Ra.4,Rd.4,000,0,Rm.4" width=32 stringency=16 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFFF000F0)==0xFB400000)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ARMv6T2) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_Rn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Rn >> 6] |= 1LL << (FIELD_Rn & 63); + char Rn_width = 4; + res->fields[FIELD_Ra] = (instr & 0xF000)>>12; + res->fields_mask[FIELD_Ra >> 6] |= 1LL << (FIELD_Ra & 63); + char Ra_width = 4; + res->fields[FIELD_Rd] = (instr & 0xF00)>>8; + res->fields_mask[FIELD_Rd >> 6] |= 1LL << (FIELD_Rd & 63); + char Rd_width = 4; + res->fields[FIELD_Rm] = instr & 0xF; + res->fields_mask[FIELD_Rm >> 6] |= 1LL << (FIELD_Rm & 63); + char Rm_width = 4; + + static const instruction_format instr_formats[] = + { + { /* SMLSD<c> <Rd>,<Rn>,<Rm>,<Ra> */ + "smlsd", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rd,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rn,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rm,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Ra,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 4 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_SMLSD; + + /* pcode: M=0 */ + res->fields[FIELD_M] = 0; + res->fields_mask[FIELD_M >> 6] |= 1LL << (FIELD_M & 63); + /* pcode: if Ra == '1111' then SEE SMUSD */ + if((res->fields[FIELD_Ra]) == (0xF)) { + + return smusd(req, res); + } + /* pcode: d = UInt(Rd) */ + res->fields[FIELD_d] = (res->fields[FIELD_Rd]); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: n = UInt(Rn) */ + res->fields[FIELD_n] = (res->fields[FIELD_Rn]); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: m = UInt(Rm) */ + res->fields[FIELD_m] = (res->fields[FIELD_Rm]); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + /* pcode: a = UInt(Ra) */ + res->fields[FIELD_a] = (res->fields[FIELD_Ra]); + res->fields_mask[FIELD_a >> 6] |= 1LL << (FIELD_a & 63); + /* pcode: m_swap = (M == '1') */ + res->fields[FIELD_m_swap] = ((res->fields[FIELD_M]) == (0x1)); + res->fields_mask[FIELD_m_swap >> 6] |= 1LL << (FIELD_m_swap & 63); + /* pcode: if BadReg(d) || BadReg(n) || BadReg(m) || a == 13 then UNPREDICTABLE */ + if((((BadReg(res->fields[FIELD_d])) || (BadReg(res->fields[FIELD_n]))) || (BadReg(res->fields[FIELD_m]))) || ((res->fields[FIELD_a]) == (13))) { + res->flags |= FLAG_UNPREDICTABLE; + } + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* Encoding T1 */ + /* pattern="11111,0110,100,Rn.4,Ra.4,Rd.4,000,1,Rm.4" width=32 stringency=16 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFFF000F0)==0xFB400010)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ARMv6T2) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_Rn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Rn >> 6] |= 1LL << (FIELD_Rn & 63); + char Rn_width = 4; + res->fields[FIELD_Ra] = (instr & 0xF000)>>12; + res->fields_mask[FIELD_Ra >> 6] |= 1LL << (FIELD_Ra & 63); + char Ra_width = 4; + res->fields[FIELD_Rd] = (instr & 0xF00)>>8; + res->fields_mask[FIELD_Rd >> 6] |= 1LL << (FIELD_Rd & 63); + char Rd_width = 4; + res->fields[FIELD_Rm] = instr & 0xF; + res->fields_mask[FIELD_Rm >> 6] |= 1LL << (FIELD_Rm & 63); + char Rm_width = 4; + + static const instruction_format instr_formats[] = + { + { /* SMLSDX<c> <Rd>,<Rn>,<Rm>,<Ra> */ + "smlsdx", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rd,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rn,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rm,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Ra,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 4 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_SMLSDX; + + /* pcode: M=1 */ + res->fields[FIELD_M] = 1; + res->fields_mask[FIELD_M >> 6] |= 1LL << (FIELD_M & 63); + /* pcode: if Ra == '1111' then SEE SMUSD */ + if((res->fields[FIELD_Ra]) == (0xF)) { + + return smusd(req, res); + } + /* pcode: d = UInt(Rd) */ + res->fields[FIELD_d] = (res->fields[FIELD_Rd]); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: n = UInt(Rn) */ + res->fields[FIELD_n] = (res->fields[FIELD_Rn]); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: m = UInt(Rm) */ + res->fields[FIELD_m] = (res->fields[FIELD_Rm]); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + /* pcode: a = UInt(Ra) */ + res->fields[FIELD_a] = (res->fields[FIELD_Ra]); + res->fields_mask[FIELD_a >> 6] |= 1LL << (FIELD_a & 63); + /* pcode: m_swap = (M == '1') */ + res->fields[FIELD_m_swap] = ((res->fields[FIELD_M]) == (0x1)); + res->fields_mask[FIELD_m_swap >> 6] |= 1LL << (FIELD_m_swap & 63); + /* pcode: if BadReg(d) || BadReg(n) || BadReg(m) || a == 13 then UNPREDICTABLE */ + if((((BadReg(res->fields[FIELD_d])) || (BadReg(res->fields[FIELD_n]))) || (BadReg(res->fields[FIELD_m]))) || ((res->fields[FIELD_a]) == (13))) { + res->flags |= FLAG_UNPREDICTABLE; + } + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: E8195C10 +int smlsld(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + /* Encoding T1 */ + /* pattern="11111,0111,1,01,Rn.4,RdLo.4,RdHi.4,110,0,Rm.4" width=32 stringency=16 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFFF000F0)==0xFBD000C0)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ARMv6T2) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_Rn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Rn >> 6] |= 1LL << (FIELD_Rn & 63); + char Rn_width = 4; + res->fields[FIELD_RdLo] = (instr & 0xF000)>>12; + res->fields_mask[FIELD_RdLo >> 6] |= 1LL << (FIELD_RdLo & 63); + char RdLo_width = 4; + res->fields[FIELD_RdHi] = (instr & 0xF00)>>8; + res->fields_mask[FIELD_RdHi >> 6] |= 1LL << (FIELD_RdHi & 63); + char RdHi_width = 4; + res->fields[FIELD_Rm] = instr & 0xF; + res->fields_mask[FIELD_Rm >> 6] |= 1LL << (FIELD_Rm & 63); + char Rm_width = 4; + + static const instruction_format instr_formats[] = + { + { /* SMLSLD<c> <RdLo>,<RdHi>,<Rn>,<Rm> */ + "smlsld", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_RdLo,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_RdHi,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rn,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rm,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 4 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_SMLSLD; + + /* pcode: M=0 */ + res->fields[FIELD_M] = 0; + res->fields_mask[FIELD_M >> 6] |= 1LL << (FIELD_M & 63); + /* pcode: dLo = UInt(RdLo) */ + res->fields[FIELD_dLo] = (res->fields[FIELD_RdLo]); + res->fields_mask[FIELD_dLo >> 6] |= 1LL << (FIELD_dLo & 63); + /* pcode: dHi = UInt(RdHi) */ + res->fields[FIELD_dHi] = (res->fields[FIELD_RdHi]); + res->fields_mask[FIELD_dHi >> 6] |= 1LL << (FIELD_dHi & 63); + /* pcode: n = UInt(Rn) */ + res->fields[FIELD_n] = (res->fields[FIELD_Rn]); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: m = UInt(Rm) */ + res->fields[FIELD_m] = (res->fields[FIELD_Rm]); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + /* pcode: m_swap = (M == '1') */ + res->fields[FIELD_m_swap] = ((res->fields[FIELD_M]) == (0x1)); + res->fields_mask[FIELD_m_swap >> 6] |= 1LL << (FIELD_m_swap & 63); + /* pcode: if BadReg(dLo) || BadReg(dHi) || BadReg(n) || BadReg(m) then UNPREDICTABLE */ + if((((BadReg(res->fields[FIELD_dLo])) || (BadReg(res->fields[FIELD_dHi]))) || (BadReg(res->fields[FIELD_n]))) || (BadReg(res->fields[FIELD_m]))) { + res->flags |= FLAG_UNPREDICTABLE; + } + /* pcode: if dHi == dLo then UNPREDICTABLE */ + if((res->fields[FIELD_dHi]) == (res->fields[FIELD_dLo])) { + res->flags |= FLAG_UNPREDICTABLE; + } + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* Encoding T1 */ + /* pattern="11111,0111,1,01,Rn.4,RdLo.4,RdHi.4,110,1,Rm.4" width=32 stringency=16 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFFF000F0)==0xFBD000D0)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ARMv6T2) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_Rn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Rn >> 6] |= 1LL << (FIELD_Rn & 63); + char Rn_width = 4; + res->fields[FIELD_RdLo] = (instr & 0xF000)>>12; + res->fields_mask[FIELD_RdLo >> 6] |= 1LL << (FIELD_RdLo & 63); + char RdLo_width = 4; + res->fields[FIELD_RdHi] = (instr & 0xF00)>>8; + res->fields_mask[FIELD_RdHi >> 6] |= 1LL << (FIELD_RdHi & 63); + char RdHi_width = 4; + res->fields[FIELD_Rm] = instr & 0xF; + res->fields_mask[FIELD_Rm >> 6] |= 1LL << (FIELD_Rm & 63); + char Rm_width = 4; + + static const instruction_format instr_formats[] = + { + { /* SMLSLDX<c> <RdLo>,<RdHi>,<Rn>,<Rm> */ + "smlsldx", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_RdLo,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_RdHi,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rn,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rm,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 4 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_SMLSLDX; + + /* pcode: M=1 */ + res->fields[FIELD_M] = 1; + res->fields_mask[FIELD_M >> 6] |= 1LL << (FIELD_M & 63); + /* pcode: dLo = UInt(RdLo) */ + res->fields[FIELD_dLo] = (res->fields[FIELD_RdLo]); + res->fields_mask[FIELD_dLo >> 6] |= 1LL << (FIELD_dLo & 63); + /* pcode: dHi = UInt(RdHi) */ + res->fields[FIELD_dHi] = (res->fields[FIELD_RdHi]); + res->fields_mask[FIELD_dHi >> 6] |= 1LL << (FIELD_dHi & 63); + /* pcode: n = UInt(Rn) */ + res->fields[FIELD_n] = (res->fields[FIELD_Rn]); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: m = UInt(Rm) */ + res->fields[FIELD_m] = (res->fields[FIELD_Rm]); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + /* pcode: m_swap = (M == '1') */ + res->fields[FIELD_m_swap] = ((res->fields[FIELD_M]) == (0x1)); + res->fields_mask[FIELD_m_swap >> 6] |= 1LL << (FIELD_m_swap & 63); + /* pcode: if BadReg(dLo) || BadReg(dHi) || BadReg(n) || BadReg(m) then UNPREDICTABLE */ + if((((BadReg(res->fields[FIELD_dLo])) || (BadReg(res->fields[FIELD_dHi]))) || (BadReg(res->fields[FIELD_n]))) || (BadReg(res->fields[FIELD_m]))) { + res->flags |= FLAG_UNPREDICTABLE; + } + /* pcode: if dHi == dLo then UNPREDICTABLE */ + if((res->fields[FIELD_dHi]) == (res->fields[FIELD_dLo])) { + res->flags |= FLAG_UNPREDICTABLE; + } + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: 75019B0D +int smmla(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + /* Encoding T1 */ + /* pattern="11111,0110,101,Rn.4,Ra.4,Rd.4,000,0,Rm.4" width=32 stringency=16 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFFF000F0)==0xFB500000)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ARMv6T2) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_Rn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Rn >> 6] |= 1LL << (FIELD_Rn & 63); + char Rn_width = 4; + res->fields[FIELD_Ra] = (instr & 0xF000)>>12; + res->fields_mask[FIELD_Ra >> 6] |= 1LL << (FIELD_Ra & 63); + char Ra_width = 4; + res->fields[FIELD_Rd] = (instr & 0xF00)>>8; + res->fields_mask[FIELD_Rd >> 6] |= 1LL << (FIELD_Rd & 63); + char Rd_width = 4; + res->fields[FIELD_Rm] = instr & 0xF; + res->fields_mask[FIELD_Rm >> 6] |= 1LL << (FIELD_Rm & 63); + char Rm_width = 4; + + static const instruction_format instr_formats[] = + { + { /* SMMLA<c> <Rd>,<Rn>,<Rm>,<Ra> */ + "smmla", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rd,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rn,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rm,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Ra,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 4 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_SMMLA; + + /* pcode: R=0 */ + res->fields[FIELD_R] = 0; + res->fields_mask[FIELD_R >> 6] |= 1LL << (FIELD_R & 63); + /* pcode: if Ra == '1111' then SEE SMMUL */ + if((res->fields[FIELD_Ra]) == (0xF)) { + + return smmul(req, res); + } + /* pcode: d = UInt(Rd) */ + res->fields[FIELD_d] = (res->fields[FIELD_Rd]); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: n = UInt(Rn) */ + res->fields[FIELD_n] = (res->fields[FIELD_Rn]); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: m = UInt(Rm) */ + res->fields[FIELD_m] = (res->fields[FIELD_Rm]); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + /* pcode: a = UInt(Ra) */ + res->fields[FIELD_a] = (res->fields[FIELD_Ra]); + res->fields_mask[FIELD_a >> 6] |= 1LL << (FIELD_a & 63); + /* pcode: round = (R == '1') */ + res->fields[FIELD_round] = ((res->fields[FIELD_R]) == (0x1)); + res->fields_mask[FIELD_round >> 6] |= 1LL << (FIELD_round & 63); + /* pcode: if BadReg(d) || BadReg(n) || BadReg(m) || a == 13 then UNPREDICTABLE */ + if((((BadReg(res->fields[FIELD_d])) || (BadReg(res->fields[FIELD_n]))) || (BadReg(res->fields[FIELD_m]))) || ((res->fields[FIELD_a]) == (13))) { + res->flags |= FLAG_UNPREDICTABLE; + } + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* Encoding T1 */ + /* pattern="11111,0110,101,Rn.4,Ra.4,Rd.4,000,1,Rm.4" width=32 stringency=16 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFFF000F0)==0xFB500010)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ARMv6T2) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_Rn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Rn >> 6] |= 1LL << (FIELD_Rn & 63); + char Rn_width = 4; + res->fields[FIELD_Ra] = (instr & 0xF000)>>12; + res->fields_mask[FIELD_Ra >> 6] |= 1LL << (FIELD_Ra & 63); + char Ra_width = 4; + res->fields[FIELD_Rd] = (instr & 0xF00)>>8; + res->fields_mask[FIELD_Rd >> 6] |= 1LL << (FIELD_Rd & 63); + char Rd_width = 4; + res->fields[FIELD_Rm] = instr & 0xF; + res->fields_mask[FIELD_Rm >> 6] |= 1LL << (FIELD_Rm & 63); + char Rm_width = 4; + + static const instruction_format instr_formats[] = + { + { /* SMMLAR<c> <Rd>,<Rn>,<Rm>,<Ra> */ + "smmlar", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rd,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rn,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rm,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Ra,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 4 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_SMMLAR; + + /* pcode: R=1 */ + res->fields[FIELD_R] = 1; + res->fields_mask[FIELD_R >> 6] |= 1LL << (FIELD_R & 63); + /* pcode: if Ra == '1111' then SEE SMMUL */ + if((res->fields[FIELD_Ra]) == (0xF)) { + + return smmul(req, res); + } + /* pcode: d = UInt(Rd) */ + res->fields[FIELD_d] = (res->fields[FIELD_Rd]); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: n = UInt(Rn) */ + res->fields[FIELD_n] = (res->fields[FIELD_Rn]); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: m = UInt(Rm) */ + res->fields[FIELD_m] = (res->fields[FIELD_Rm]); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + /* pcode: a = UInt(Ra) */ + res->fields[FIELD_a] = (res->fields[FIELD_Ra]); + res->fields_mask[FIELD_a >> 6] |= 1LL << (FIELD_a & 63); + /* pcode: round = (R == '1') */ + res->fields[FIELD_round] = ((res->fields[FIELD_R]) == (0x1)); + res->fields_mask[FIELD_round >> 6] |= 1LL << (FIELD_round & 63); + /* pcode: if BadReg(d) || BadReg(n) || BadReg(m) || a == 13 then UNPREDICTABLE */ + if((((BadReg(res->fields[FIELD_d])) || (BadReg(res->fields[FIELD_n]))) || (BadReg(res->fields[FIELD_m]))) || ((res->fields[FIELD_a]) == (13))) { + res->flags |= FLAG_UNPREDICTABLE; + } + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: 511A002F +int smmls(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + /* Encoding T1 */ + /* pattern="11111,0110,110,Rn.4,Ra.4,Rd.4,000,0,Rm.4" width=32 stringency=16 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFFF000F0)==0xFB600000)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ARMv6T2) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_Rn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Rn >> 6] |= 1LL << (FIELD_Rn & 63); + char Rn_width = 4; + res->fields[FIELD_Ra] = (instr & 0xF000)>>12; + res->fields_mask[FIELD_Ra >> 6] |= 1LL << (FIELD_Ra & 63); + char Ra_width = 4; + res->fields[FIELD_Rd] = (instr & 0xF00)>>8; + res->fields_mask[FIELD_Rd >> 6] |= 1LL << (FIELD_Rd & 63); + char Rd_width = 4; + res->fields[FIELD_Rm] = instr & 0xF; + res->fields_mask[FIELD_Rm >> 6] |= 1LL << (FIELD_Rm & 63); + char Rm_width = 4; + + static const instruction_format instr_formats[] = + { + { /* SMMLS<c> <Rd>,<Rn>,<Rm>,<Ra> */ + "smmls", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rd,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rn,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rm,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Ra,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 4 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_SMMLS; + + /* pcode: R=0 */ + res->fields[FIELD_R] = 0; + res->fields_mask[FIELD_R >> 6] |= 1LL << (FIELD_R & 63); + /* pcode: d = UInt(Rd) */ + res->fields[FIELD_d] = (res->fields[FIELD_Rd]); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: n = UInt(Rn) */ + res->fields[FIELD_n] = (res->fields[FIELD_Rn]); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: m = UInt(Rm) */ + res->fields[FIELD_m] = (res->fields[FIELD_Rm]); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + /* pcode: a = UInt(Ra) */ + res->fields[FIELD_a] = (res->fields[FIELD_Ra]); + res->fields_mask[FIELD_a >> 6] |= 1LL << (FIELD_a & 63); + /* pcode: round = (R == '1') */ + res->fields[FIELD_round] = ((res->fields[FIELD_R]) == (0x1)); + res->fields_mask[FIELD_round >> 6] |= 1LL << (FIELD_round & 63); + /* pcode: if BadReg(d) || BadReg(n) || BadReg(m) || BadReg(a) then UNPREDICTABLE */ + if((((BadReg(res->fields[FIELD_d])) || (BadReg(res->fields[FIELD_n]))) || (BadReg(res->fields[FIELD_m]))) || (BadReg(res->fields[FIELD_a]))) { + res->flags |= FLAG_UNPREDICTABLE; + } + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* Encoding T1 */ + /* pattern="11111,0110,110,Rn.4,Ra.4,Rd.4,000,1,Rm.4" width=32 stringency=16 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFFF000F0)==0xFB600010)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ARMv6T2) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_Rn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Rn >> 6] |= 1LL << (FIELD_Rn & 63); + char Rn_width = 4; + res->fields[FIELD_Ra] = (instr & 0xF000)>>12; + res->fields_mask[FIELD_Ra >> 6] |= 1LL << (FIELD_Ra & 63); + char Ra_width = 4; + res->fields[FIELD_Rd] = (instr & 0xF00)>>8; + res->fields_mask[FIELD_Rd >> 6] |= 1LL << (FIELD_Rd & 63); + char Rd_width = 4; + res->fields[FIELD_Rm] = instr & 0xF; + res->fields_mask[FIELD_Rm >> 6] |= 1LL << (FIELD_Rm & 63); + char Rm_width = 4; + + static const instruction_format instr_formats[] = + { + { /* SMMLSR<c> <Rd>,<Rn>,<Rm>,<Ra> */ + "smmlsr", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rd,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rn,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rm,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Ra,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 4 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_SMMLSR; + + /* pcode: R=1 */ + res->fields[FIELD_R] = 1; + res->fields_mask[FIELD_R >> 6] |= 1LL << (FIELD_R & 63); + /* pcode: d = UInt(Rd) */ + res->fields[FIELD_d] = (res->fields[FIELD_Rd]); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: n = UInt(Rn) */ + res->fields[FIELD_n] = (res->fields[FIELD_Rn]); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: m = UInt(Rm) */ + res->fields[FIELD_m] = (res->fields[FIELD_Rm]); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + /* pcode: a = UInt(Ra) */ + res->fields[FIELD_a] = (res->fields[FIELD_Ra]); + res->fields_mask[FIELD_a >> 6] |= 1LL << (FIELD_a & 63); + /* pcode: round = (R == '1') */ + res->fields[FIELD_round] = ((res->fields[FIELD_R]) == (0x1)); + res->fields_mask[FIELD_round >> 6] |= 1LL << (FIELD_round & 63); + /* pcode: if BadReg(d) || BadReg(n) || BadReg(m) || BadReg(a) then UNPREDICTABLE */ + if((((BadReg(res->fields[FIELD_d])) || (BadReg(res->fields[FIELD_n]))) || (BadReg(res->fields[FIELD_m]))) || (BadReg(res->fields[FIELD_a]))) { + res->flags |= FLAG_UNPREDICTABLE; + } + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: 6D33DDAF +int smmul(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + /* Encoding T1 */ + /* pattern="11111,0110,101,Rn.4,1111,Rd.4,000,0,Rm.4" width=32 stringency=20 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFFF0F0F0)==0xFB50F000)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ARMv6T2) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_Rn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Rn >> 6] |= 1LL << (FIELD_Rn & 63); + char Rn_width = 4; + res->fields[FIELD_Rd] = (instr & 0xF00)>>8; + res->fields_mask[FIELD_Rd >> 6] |= 1LL << (FIELD_Rd & 63); + char Rd_width = 4; + res->fields[FIELD_Rm] = instr & 0xF; + res->fields_mask[FIELD_Rm >> 6] |= 1LL << (FIELD_Rm & 63); + char Rm_width = 4; + + static const instruction_format instr_formats[] = + { + { /* SMMUL<c> <Rd>,<Rn>,<Rm> */ + "smmul", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rd,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rn,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rm,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_SMMUL; + + /* pcode: R=0 */ + res->fields[FIELD_R] = 0; + res->fields_mask[FIELD_R >> 6] |= 1LL << (FIELD_R & 63); + /* pcode: d = UInt(Rd) */ + res->fields[FIELD_d] = (res->fields[FIELD_Rd]); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: n = UInt(Rn) */ + res->fields[FIELD_n] = (res->fields[FIELD_Rn]); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: m = UInt(Rm) */ + res->fields[FIELD_m] = (res->fields[FIELD_Rm]); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + /* pcode: round = (R == '1') */ + res->fields[FIELD_round] = ((res->fields[FIELD_R]) == (0x1)); + res->fields_mask[FIELD_round >> 6] |= 1LL << (FIELD_round & 63); + /* pcode: if BadReg(d) || BadReg(n) || BadReg(m) then UNPREDICTABLE */ + if(((BadReg(res->fields[FIELD_d])) || (BadReg(res->fields[FIELD_n]))) || (BadReg(res->fields[FIELD_m]))) { + res->flags |= FLAG_UNPREDICTABLE; + } + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* Encoding T1 */ + /* pattern="11111,0110,101,Rn.4,1111,Rd.4,000,1,Rm.4" width=32 stringency=20 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFFF0F0F0)==0xFB50F010)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ARMv6T2) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_Rn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Rn >> 6] |= 1LL << (FIELD_Rn & 63); + char Rn_width = 4; + res->fields[FIELD_Rd] = (instr & 0xF00)>>8; + res->fields_mask[FIELD_Rd >> 6] |= 1LL << (FIELD_Rd & 63); + char Rd_width = 4; + res->fields[FIELD_Rm] = instr & 0xF; + res->fields_mask[FIELD_Rm >> 6] |= 1LL << (FIELD_Rm & 63); + char Rm_width = 4; + + static const instruction_format instr_formats[] = + { + { /* SMMULR<c> <Rd>,<Rn>,<Rm> */ + "smmulr", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rd,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rn,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rm,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_SMMULR; + + /* pcode: R=1 */ + res->fields[FIELD_R] = 1; + res->fields_mask[FIELD_R >> 6] |= 1LL << (FIELD_R & 63); + /* pcode: d = UInt(Rd) */ + res->fields[FIELD_d] = (res->fields[FIELD_Rd]); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: n = UInt(Rn) */ + res->fields[FIELD_n] = (res->fields[FIELD_Rn]); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: m = UInt(Rm) */ + res->fields[FIELD_m] = (res->fields[FIELD_Rm]); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + /* pcode: round = (R == '1') */ + res->fields[FIELD_round] = ((res->fields[FIELD_R]) == (0x1)); + res->fields_mask[FIELD_round >> 6] |= 1LL << (FIELD_round & 63); + /* pcode: if BadReg(d) || BadReg(n) || BadReg(m) then UNPREDICTABLE */ + if(((BadReg(res->fields[FIELD_d])) || (BadReg(res->fields[FIELD_n]))) || (BadReg(res->fields[FIELD_m]))) { + res->flags |= FLAG_UNPREDICTABLE; + } + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: 6BAA2824 +int smuad(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + /* Encoding T1 */ + /* pattern="11111,0110,010,Rn.4,1111,Rd.4,000,0,Rm.4" width=32 stringency=20 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFFF0F0F0)==0xFB20F000)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ARMv6T2) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_Rn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Rn >> 6] |= 1LL << (FIELD_Rn & 63); + char Rn_width = 4; + res->fields[FIELD_Rd] = (instr & 0xF00)>>8; + res->fields_mask[FIELD_Rd >> 6] |= 1LL << (FIELD_Rd & 63); + char Rd_width = 4; + res->fields[FIELD_Rm] = instr & 0xF; + res->fields_mask[FIELD_Rm >> 6] |= 1LL << (FIELD_Rm & 63); + char Rm_width = 4; + + static const instruction_format instr_formats[] = + { + { /* SMUAD<c> <Rd>,<Rn>,<Rm> */ + "smuad", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rd,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rn,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rm,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_SMUAD; + + /* pcode: M=0 */ + res->fields[FIELD_M] = 0; + res->fields_mask[FIELD_M >> 6] |= 1LL << (FIELD_M & 63); + /* pcode: d = UInt(Rd) */ + res->fields[FIELD_d] = (res->fields[FIELD_Rd]); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: n = UInt(Rn) */ + res->fields[FIELD_n] = (res->fields[FIELD_Rn]); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: m = UInt(Rm) */ + res->fields[FIELD_m] = (res->fields[FIELD_Rm]); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + /* pcode: m_swap = (M == '1') */ + res->fields[FIELD_m_swap] = ((res->fields[FIELD_M]) == (0x1)); + res->fields_mask[FIELD_m_swap >> 6] |= 1LL << (FIELD_m_swap & 63); + /* pcode: if BadReg(d) || BadReg(n) || BadReg(m) then UNPREDICTABLE */ + if(((BadReg(res->fields[FIELD_d])) || (BadReg(res->fields[FIELD_n]))) || (BadReg(res->fields[FIELD_m]))) { + res->flags |= FLAG_UNPREDICTABLE; + } + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* Encoding T1 */ + /* pattern="11111,0110,010,Rn.4,1111,Rd.4,000,1,Rm.4" width=32 stringency=20 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFFF0F0F0)==0xFB20F010)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ARMv6T2) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_Rn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Rn >> 6] |= 1LL << (FIELD_Rn & 63); + char Rn_width = 4; + res->fields[FIELD_Rd] = (instr & 0xF00)>>8; + res->fields_mask[FIELD_Rd >> 6] |= 1LL << (FIELD_Rd & 63); + char Rd_width = 4; + res->fields[FIELD_Rm] = instr & 0xF; + res->fields_mask[FIELD_Rm >> 6] |= 1LL << (FIELD_Rm & 63); + char Rm_width = 4; + + static const instruction_format instr_formats[] = + { + { /* SMUADX<c> <Rd>,<Rn>,<Rm> */ + "smuadx", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rd,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rn,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rm,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_SMUADX; + + /* pcode: M=1 */ + res->fields[FIELD_M] = 1; + res->fields_mask[FIELD_M >> 6] |= 1LL << (FIELD_M & 63); + /* pcode: d = UInt(Rd) */ + res->fields[FIELD_d] = (res->fields[FIELD_Rd]); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: n = UInt(Rn) */ + res->fields[FIELD_n] = (res->fields[FIELD_Rn]); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: m = UInt(Rm) */ + res->fields[FIELD_m] = (res->fields[FIELD_Rm]); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + /* pcode: m_swap = (M == '1') */ + res->fields[FIELD_m_swap] = ((res->fields[FIELD_M]) == (0x1)); + res->fields_mask[FIELD_m_swap >> 6] |= 1LL << (FIELD_m_swap & 63); + /* pcode: if BadReg(d) || BadReg(n) || BadReg(m) then UNPREDICTABLE */ + if(((BadReg(res->fields[FIELD_d])) || (BadReg(res->fields[FIELD_n]))) || (BadReg(res->fields[FIELD_m]))) { + res->flags |= FLAG_UNPREDICTABLE; + } + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: 6D9F522B +int smulbb_smulbt_smultb_smultt(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + /* Encoding T1 */ + /* pattern="11111,0110,001,Rn.4,1111,Rd.4,00,00,Rm.4" width=32 stringency=20 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFFF0F0F0)==0xFB10F000)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ARMv6T2) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_Rn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Rn >> 6] |= 1LL << (FIELD_Rn & 63); + char Rn_width = 4; + res->fields[FIELD_Rd] = (instr & 0xF00)>>8; + res->fields_mask[FIELD_Rd >> 6] |= 1LL << (FIELD_Rd & 63); + char Rd_width = 4; + res->fields[FIELD_Rm] = instr & 0xF; + res->fields_mask[FIELD_Rm >> 6] |= 1LL << (FIELD_Rm & 63); + char Rm_width = 4; + + static const instruction_format instr_formats[] = + { + { /* SMULBB<c> <Rd>,<Rn>,<Rm> */ + "smulbb", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rd,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rn,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rm,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_SMULBB; + + /* pcode: d = UInt(Rd) */ + res->fields[FIELD_d] = (res->fields[FIELD_Rd]); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: n = UInt(Rn) */ + res->fields[FIELD_n] = (res->fields[FIELD_Rn]); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: m = UInt(Rm) */ + res->fields[FIELD_m] = (res->fields[FIELD_Rm]); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + /* pcode: if BadReg(d) || BadReg(n) || BadReg(m) then UNPREDICTABLE */ + if(((BadReg(res->fields[FIELD_d])) || (BadReg(res->fields[FIELD_n]))) || (BadReg(res->fields[FIELD_m]))) { + res->flags |= FLAG_UNPREDICTABLE; + } + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* Encoding T1 */ + /* pattern="11111,0110,001,Rn.4,1111,Rd.4,00,01,Rm.4" width=32 stringency=20 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFFF0F0F0)==0xFB10F010)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ARMv6T2) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_Rn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Rn >> 6] |= 1LL << (FIELD_Rn & 63); + char Rn_width = 4; + res->fields[FIELD_Rd] = (instr & 0xF00)>>8; + res->fields_mask[FIELD_Rd >> 6] |= 1LL << (FIELD_Rd & 63); + char Rd_width = 4; + res->fields[FIELD_Rm] = instr & 0xF; + res->fields_mask[FIELD_Rm >> 6] |= 1LL << (FIELD_Rm & 63); + char Rm_width = 4; + + static const instruction_format instr_formats[] = + { + { /* SMULBT<c> <Rd>,<Rn>,<Rm> */ + "smulbt", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rd,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rn,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rm,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_SMULBT; + + /* pcode: d = UInt(Rd) */ + res->fields[FIELD_d] = (res->fields[FIELD_Rd]); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: n = UInt(Rn) */ + res->fields[FIELD_n] = (res->fields[FIELD_Rn]); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: m = UInt(Rm) */ + res->fields[FIELD_m] = (res->fields[FIELD_Rm]); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + /* pcode: if BadReg(d) || BadReg(n) || BadReg(m) then UNPREDICTABLE */ + if(((BadReg(res->fields[FIELD_d])) || (BadReg(res->fields[FIELD_n]))) || (BadReg(res->fields[FIELD_m]))) { + res->flags |= FLAG_UNPREDICTABLE; + } + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* Encoding T1 */ + /* pattern="11111,0110,001,Rn.4,1111,Rd.4,00,10,Rm.4" width=32 stringency=20 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFFF0F0F0)==0xFB10F020)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ARMv6T2) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_Rn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Rn >> 6] |= 1LL << (FIELD_Rn & 63); + char Rn_width = 4; + res->fields[FIELD_Rd] = (instr & 0xF00)>>8; + res->fields_mask[FIELD_Rd >> 6] |= 1LL << (FIELD_Rd & 63); + char Rd_width = 4; + res->fields[FIELD_Rm] = instr & 0xF; + res->fields_mask[FIELD_Rm >> 6] |= 1LL << (FIELD_Rm & 63); + char Rm_width = 4; + + static const instruction_format instr_formats[] = + { + { /* SMULTB<c> <Rd>,<Rn>,<Rm> */ + "smultb", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rd,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rn,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rm,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_SMULTB; + + /* pcode: d = UInt(Rd) */ + res->fields[FIELD_d] = (res->fields[FIELD_Rd]); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: n = UInt(Rn) */ + res->fields[FIELD_n] = (res->fields[FIELD_Rn]); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: m = UInt(Rm) */ + res->fields[FIELD_m] = (res->fields[FIELD_Rm]); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + /* pcode: if BadReg(d) || BadReg(n) || BadReg(m) then UNPREDICTABLE */ + if(((BadReg(res->fields[FIELD_d])) || (BadReg(res->fields[FIELD_n]))) || (BadReg(res->fields[FIELD_m]))) { + res->flags |= FLAG_UNPREDICTABLE; + } + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* Encoding T1 */ + /* pattern="11111,0110,001,Rn.4,1111,Rd.4,00,11,Rm.4" width=32 stringency=20 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFFF0F0F0)==0xFB10F030)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ARMv6T2) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_Rn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Rn >> 6] |= 1LL << (FIELD_Rn & 63); + char Rn_width = 4; + res->fields[FIELD_Rd] = (instr & 0xF00)>>8; + res->fields_mask[FIELD_Rd >> 6] |= 1LL << (FIELD_Rd & 63); + char Rd_width = 4; + res->fields[FIELD_Rm] = instr & 0xF; + res->fields_mask[FIELD_Rm >> 6] |= 1LL << (FIELD_Rm & 63); + char Rm_width = 4; + + static const instruction_format instr_formats[] = + { + { /* SMULTT<c> <Rd>,<Rn>,<Rm> */ + "smultt", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rd,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rn,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rm,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_SMULTT; + + /* pcode: d = UInt(Rd) */ + res->fields[FIELD_d] = (res->fields[FIELD_Rd]); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: n = UInt(Rn) */ + res->fields[FIELD_n] = (res->fields[FIELD_Rn]); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: m = UInt(Rm) */ + res->fields[FIELD_m] = (res->fields[FIELD_Rm]); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + /* pcode: if BadReg(d) || BadReg(n) || BadReg(m) then UNPREDICTABLE */ + if(((BadReg(res->fields[FIELD_d])) || (BadReg(res->fields[FIELD_n]))) || (BadReg(res->fields[FIELD_m]))) { + res->flags |= FLAG_UNPREDICTABLE; + } + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: F5CC98B3 +int smull(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + /* Encoding T1 */ + /* pattern="11111,0111,0,00,Rn.4,RdLo.4,RdHi.4,0000,Rm.4" width=32 stringency=16 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFFF000F0)==0xFB800000)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ARMv6T2) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_Rn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Rn >> 6] |= 1LL << (FIELD_Rn & 63); + char Rn_width = 4; + res->fields[FIELD_RdLo] = (instr & 0xF000)>>12; + res->fields_mask[FIELD_RdLo >> 6] |= 1LL << (FIELD_RdLo & 63); + char RdLo_width = 4; + res->fields[FIELD_RdHi] = (instr & 0xF00)>>8; + res->fields_mask[FIELD_RdHi >> 6] |= 1LL << (FIELD_RdHi & 63); + char RdHi_width = 4; + res->fields[FIELD_Rm] = instr & 0xF; + res->fields_mask[FIELD_Rm >> 6] |= 1LL << (FIELD_Rm & 63); + char Rm_width = 4; + + static const instruction_format instr_formats[] = + { + { /* SMULL<c> <RdLo>,<RdHi>,<Rn>,<Rm> */ + "smull", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_RdLo,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_RdHi,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rn,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rm,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 4 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_SMULL; + + /* pcode: dLo = UInt(RdLo) */ + res->fields[FIELD_dLo] = (res->fields[FIELD_RdLo]); + res->fields_mask[FIELD_dLo >> 6] |= 1LL << (FIELD_dLo & 63); + /* pcode: dHi = UInt(RdHi) */ + res->fields[FIELD_dHi] = (res->fields[FIELD_RdHi]); + res->fields_mask[FIELD_dHi >> 6] |= 1LL << (FIELD_dHi & 63); + /* pcode: n = UInt(Rn) */ + res->fields[FIELD_n] = (res->fields[FIELD_Rn]); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: m = UInt(Rm) */ + res->fields[FIELD_m] = (res->fields[FIELD_Rm]); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + /* pcode: setflags = FALSE */ + res->fields[FIELD_setflags] = 0; + res->fields_mask[FIELD_setflags >> 6] |= 1LL << (FIELD_setflags & 63); + /* pcode: if BadReg(dLo) || BadReg(dHi) || BadReg(n) || BadReg(m) then UNPREDICTABLE */ + if((((BadReg(res->fields[FIELD_dLo])) || (BadReg(res->fields[FIELD_dHi]))) || (BadReg(res->fields[FIELD_n]))) || (BadReg(res->fields[FIELD_m]))) { + res->flags |= FLAG_UNPREDICTABLE; + } + /* pcode: if dHi == dLo then UNPREDICTABLE */ + if((res->fields[FIELD_dHi]) == (res->fields[FIELD_dLo])) { + res->flags |= FLAG_UNPREDICTABLE; + } + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: 47107986 +int smulwb_smulwt(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + /* Encoding T1 */ + /* pattern="11111,0110,011,Rn.4,1111,Rd.4,000,0,Rm.4" width=32 stringency=20 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFFF0F0F0)==0xFB30F000)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ARMv6T2) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_Rn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Rn >> 6] |= 1LL << (FIELD_Rn & 63); + char Rn_width = 4; + res->fields[FIELD_Rd] = (instr & 0xF00)>>8; + res->fields_mask[FIELD_Rd >> 6] |= 1LL << (FIELD_Rd & 63); + char Rd_width = 4; + res->fields[FIELD_Rm] = instr & 0xF; + res->fields_mask[FIELD_Rm >> 6] |= 1LL << (FIELD_Rm & 63); + char Rm_width = 4; + + static const instruction_format instr_formats[] = + { + { /* SMULWB<c> <Rd>,<Rn>,<Rm> */ + "smulwb", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rd,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rn,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rm,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_SMULWB; + + /* pcode: M=0 */ + res->fields[FIELD_M] = 0; + res->fields_mask[FIELD_M >> 6] |= 1LL << (FIELD_M & 63); + /* pcode: d = UInt(Rd) */ + res->fields[FIELD_d] = (res->fields[FIELD_Rd]); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: n = UInt(Rn) */ + res->fields[FIELD_n] = (res->fields[FIELD_Rn]); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: m = UInt(Rm) */ + res->fields[FIELD_m] = (res->fields[FIELD_Rm]); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + /* pcode: m_high = (M == '1') */ + res->fields[FIELD_m_high] = ((res->fields[FIELD_M]) == (0x1)); + res->fields_mask[FIELD_m_high >> 6] |= 1LL << (FIELD_m_high & 63); + /* pcode: if BadReg(d) || BadReg(n) || BadReg(m) then UNPREDICTABLE */ + if(((BadReg(res->fields[FIELD_d])) || (BadReg(res->fields[FIELD_n]))) || (BadReg(res->fields[FIELD_m]))) { + res->flags |= FLAG_UNPREDICTABLE; + } + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* Encoding T1 */ + /* pattern="11111,0110,011,Rn.4,1111,Rd.4,000,1,Rm.4" width=32 stringency=20 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFFF0F0F0)==0xFB30F010)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ARMv6T2) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_Rn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Rn >> 6] |= 1LL << (FIELD_Rn & 63); + char Rn_width = 4; + res->fields[FIELD_Rd] = (instr & 0xF00)>>8; + res->fields_mask[FIELD_Rd >> 6] |= 1LL << (FIELD_Rd & 63); + char Rd_width = 4; + res->fields[FIELD_Rm] = instr & 0xF; + res->fields_mask[FIELD_Rm >> 6] |= 1LL << (FIELD_Rm & 63); + char Rm_width = 4; + + static const instruction_format instr_formats[] = + { + { /* SMULWT<c> <Rd>,<Rn>,<Rm> */ + "smulwt", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rd,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rn,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rm,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_SMULWT; + + /* pcode: M=1 */ + res->fields[FIELD_M] = 1; + res->fields_mask[FIELD_M >> 6] |= 1LL << (FIELD_M & 63); + /* pcode: d = UInt(Rd) */ + res->fields[FIELD_d] = (res->fields[FIELD_Rd]); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: n = UInt(Rn) */ + res->fields[FIELD_n] = (res->fields[FIELD_Rn]); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: m = UInt(Rm) */ + res->fields[FIELD_m] = (res->fields[FIELD_Rm]); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + /* pcode: m_high = (M == '1') */ + res->fields[FIELD_m_high] = ((res->fields[FIELD_M]) == (0x1)); + res->fields_mask[FIELD_m_high >> 6] |= 1LL << (FIELD_m_high & 63); + /* pcode: if BadReg(d) || BadReg(n) || BadReg(m) then UNPREDICTABLE */ + if(((BadReg(res->fields[FIELD_d])) || (BadReg(res->fields[FIELD_n]))) || (BadReg(res->fields[FIELD_m]))) { + res->flags |= FLAG_UNPREDICTABLE; + } + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: 19EFC9E9 +int smusd(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + /* Encoding T1 */ + /* pattern="11111,0110,100,Rn.4,1111,Rd.4,000,0,Rm.4" width=32 stringency=20 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFFF0F0F0)==0xFB40F000)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ARMv6T2) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_Rn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Rn >> 6] |= 1LL << (FIELD_Rn & 63); + char Rn_width = 4; + res->fields[FIELD_Rd] = (instr & 0xF00)>>8; + res->fields_mask[FIELD_Rd >> 6] |= 1LL << (FIELD_Rd & 63); + char Rd_width = 4; + res->fields[FIELD_Rm] = instr & 0xF; + res->fields_mask[FIELD_Rm >> 6] |= 1LL << (FIELD_Rm & 63); + char Rm_width = 4; + + static const instruction_format instr_formats[] = + { + { /* SMUSD<c> <Rd>,<Rn>,<Rm> */ + "smusd", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rd,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rn,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rm,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_SMUSD; + + /* pcode: M=0 */ + res->fields[FIELD_M] = 0; + res->fields_mask[FIELD_M >> 6] |= 1LL << (FIELD_M & 63); + /* pcode: d = UInt(Rd) */ + res->fields[FIELD_d] = (res->fields[FIELD_Rd]); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: n = UInt(Rn) */ + res->fields[FIELD_n] = (res->fields[FIELD_Rn]); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: m = UInt(Rm) */ + res->fields[FIELD_m] = (res->fields[FIELD_Rm]); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + /* pcode: m_swap = (M == '1') */ + res->fields[FIELD_m_swap] = ((res->fields[FIELD_M]) == (0x1)); + res->fields_mask[FIELD_m_swap >> 6] |= 1LL << (FIELD_m_swap & 63); + /* pcode: if BadReg(d) || BadReg(n) || BadReg(m) then UNPREDICTABLE */ + if(((BadReg(res->fields[FIELD_d])) || (BadReg(res->fields[FIELD_n]))) || (BadReg(res->fields[FIELD_m]))) { + res->flags |= FLAG_UNPREDICTABLE; + } + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* Encoding T1 */ + /* pattern="11111,0110,100,Rn.4,1111,Rd.4,000,1,Rm.4" width=32 stringency=20 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFFF0F0F0)==0xFB40F010)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ARMv6T2) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_Rn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Rn >> 6] |= 1LL << (FIELD_Rn & 63); + char Rn_width = 4; + res->fields[FIELD_Rd] = (instr & 0xF00)>>8; + res->fields_mask[FIELD_Rd >> 6] |= 1LL << (FIELD_Rd & 63); + char Rd_width = 4; + res->fields[FIELD_Rm] = instr & 0xF; + res->fields_mask[FIELD_Rm >> 6] |= 1LL << (FIELD_Rm & 63); + char Rm_width = 4; + + static const instruction_format instr_formats[] = + { + { /* SMUSDX<c> <Rd>,<Rn>,<Rm> */ + "smusdx", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rd,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rn,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rm,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_SMUSDX; + + /* pcode: M=1 */ + res->fields[FIELD_M] = 1; + res->fields_mask[FIELD_M >> 6] |= 1LL << (FIELD_M & 63); + /* pcode: d = UInt(Rd) */ + res->fields[FIELD_d] = (res->fields[FIELD_Rd]); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: n = UInt(Rn) */ + res->fields[FIELD_n] = (res->fields[FIELD_Rn]); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: m = UInt(Rm) */ + res->fields[FIELD_m] = (res->fields[FIELD_Rm]); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + /* pcode: m_swap = (M == '1') */ + res->fields[FIELD_m_swap] = ((res->fields[FIELD_M]) == (0x1)); + res->fields_mask[FIELD_m_swap >> 6] |= 1LL << (FIELD_m_swap & 63); + /* pcode: if BadReg(d) || BadReg(n) || BadReg(m) then UNPREDICTABLE */ + if(((BadReg(res->fields[FIELD_d])) || (BadReg(res->fields[FIELD_n]))) || (BadReg(res->fields[FIELD_m]))) { + res->flags |= FLAG_UNPREDICTABLE; + } + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: 950140FC +int spcl_data_branch_exch(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + uint16_t instr = req->instr_word16; + uint16_t Opcode = (instr & 0x3C0)>>6; + if(((Opcode & 0xF)==0x0)) return add_register(req, res); + if(((Opcode & 0xF)==0x1)) return add_register(req, res); + if(((Opcode & 0xF)==0x4)) return cmp_register(req, res); + if(((Opcode & 0xF)==0x5)) return cmp_register(req, res); + if(((Opcode & 0xF)==0x8)) return mov_register(req, res); + if(((Opcode & 0xF)==0x9)) return mov_register(req, res); + if(((Opcode & 0xE)==0x2)) return add_register(req, res); + if(((Opcode & 0xE)==0x6)) return cmp_register(req, res); + if(((Opcode & 0xE)==0xA)) return mov_register(req, res); + if(((Opcode & 0xE)==0xC)) return bx(req, res); + if(((Opcode & 0xE)==0xE)) return blx(req, res); + return undefined(req, res); +} + +// gen_crc: 1BC494F4 +int srs(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + /* Encoding T1 */ + /* pattern="11101,00,00,0,W.1,0,(1)(1)(0)(1),(1)(1),(0)(0)(0)(0)(0)(0)(0)(0)(0),mode.5" width=32 stringency=27 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFFD00000)==0xE8000000)) { + res->instrSize = 32; + if(!((instr & 0xFFFE0)==0xDC000)) { + res->flags |= FLAG_UNPREDICTABLE; + } + if(!(req->arch & ARCH_ARMv6T2) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_W] = (instr & 0x200000)>>21; + res->fields_mask[FIELD_W >> 6] |= 1LL << (FIELD_W & 63); + char W_width = 1; + res->fields[FIELD_mode] = instr & 0x1F; + res->fields_mask[FIELD_mode >> 6] |= 1LL << (FIELD_mode & 63); + char mode_width = 5; + + static const instruction_format instr_formats[] = + { + { /* SRSDB<c> SP{!},#<mode> */ + "srsdb", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_SP,FIELD_UNINIT,FIELD_UNINIT,"sp","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_IMM,FIELD_mode,FIELD_UNINIT,"#","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_SRSDB; + + /* pcode: wback = (W == '1') */ + res->fields[FIELD_wback] = ((res->fields[FIELD_W]) == (0x1)); + res->fields_mask[FIELD_wback >> 6] |= 1LL << (FIELD_wback & 63); + /* pcode: increment = FALSE */ + res->fields[FIELD_increment] = 0; + res->fields_mask[FIELD_increment >> 6] |= 1LL << (FIELD_increment & 63); + /* pcode: wordhigher = FALSE */ + res->fields[FIELD_wordhigher] = 0; + res->fields_mask[FIELD_wordhigher >> 6] |= 1LL << (FIELD_wordhigher & 63); + /* pcode: if !IsSecure() && mode == '10110' then UNPREDICTABLE */ + if(!((req->arch & ARCH_SECURITY_EXTENSIONS /* || SCR.NS=='0' || CPSR.M=='10110' */) && ((res->fields[FIELD_mode]) == (0x16)))) { + res->flags |= FLAG_UNPREDICTABLE; + } + /* pcode: if !IsSecure() && mode == '10001' && NSACR.RFR == '1' then UNPREDICTABLE */ + if(!(((req->arch & ARCH_SECURITY_EXTENSIONS /* || SCR.NS=='0' || CPSR.M=='10110' */) && ((res->fields[FIELD_mode]) == (0x11))) && ((res->fields[FIELD_NSACR_RFR]) == (0x1)))) { + res->flags |= FLAG_UNPREDICTABLE; + } + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* Encoding T2 */ + /* pattern="11101,00,11,0,W.1,0,(1)(1)(0)(1),(1)(1),(0)(0)(0)(0)(0)(0)(0)(0)(0),mode.5" width=32 stringency=27 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFFD00000)==0xE9800000)) { + res->instrSize = 32; + if(!((instr & 0xFFFE0)==0xDC000)) { + res->flags |= FLAG_UNPREDICTABLE; + } + if(!(req->arch & ARCH_ARMv6T2) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_W] = (instr & 0x200000)>>21; + res->fields_mask[FIELD_W >> 6] |= 1LL << (FIELD_W & 63); + char W_width = 1; + res->fields[FIELD_mode] = instr & 0x1F; + res->fields_mask[FIELD_mode >> 6] |= 1LL << (FIELD_mode & 63); + char mode_width = 5; + + static const instruction_format instr_formats[] = + { + { /* SRS{IA}<c> SP{!},#<mode> */ + "srs", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_INCREMENT_AFTER, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_SP,FIELD_UNINIT,FIELD_UNINIT,"sp","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_IMM,FIELD_mode,FIELD_UNINIT,"#","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_SRS; + + /* pcode: wback = (W == '1') */ + res->fields[FIELD_wback] = ((res->fields[FIELD_W]) == (0x1)); + res->fields_mask[FIELD_wback >> 6] |= 1LL << (FIELD_wback & 63); + /* pcode: increment = TRUE */ + res->fields[FIELD_increment] = 1; + res->fields_mask[FIELD_increment >> 6] |= 1LL << (FIELD_increment & 63); + /* pcode: wordhigher = FALSE */ + res->fields[FIELD_wordhigher] = 0; + res->fields_mask[FIELD_wordhigher >> 6] |= 1LL << (FIELD_wordhigher & 63); + /* pcode: if !IsSecure() && mode == '10110' then UNPREDICTABLE */ + if(!((req->arch & ARCH_SECURITY_EXTENSIONS /* || SCR.NS=='0' || CPSR.M=='10110' */) && ((res->fields[FIELD_mode]) == (0x16)))) { + res->flags |= FLAG_UNPREDICTABLE; + } + /* pcode: if !IsSecure() && mode == '10001' && NSACR.RFR == '1' then UNPREDICTABLE */ + if(!(((req->arch & ARCH_SECURITY_EXTENSIONS /* || SCR.NS=='0' || CPSR.M=='10110' */) && ((res->fields[FIELD_mode]) == (0x11))) && ((res->fields[FIELD_NSACR_RFR]) == (0x1)))) { + res->flags |= FLAG_UNPREDICTABLE; + } + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* Encoding A1 */ + /* pattern="1111,100,P.1,U.1,1,W.1,0,(1)(1)(0)(1),(0)(0)(0)(0),(0)(1)(0)(1),(0)(0)(0),mode.5" width=32 stringency=27 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFE500000)==0xF8400000)) { + res->instrSize = 32; + if(!((instr & 0xFFFE0)==0xD0500)) { + res->flags |= FLAG_UNPREDICTABLE; + } + if(!(req->arch & ARCH_ARMv6) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_P] = (instr & 0x1000000)>>24; + res->fields_mask[FIELD_P >> 6] |= 1LL << (FIELD_P & 63); + char P_width = 1; + res->fields[FIELD_U] = (instr & 0x800000)>>23; + res->fields_mask[FIELD_U >> 6] |= 1LL << (FIELD_U & 63); + char U_width = 1; + res->fields[FIELD_W] = (instr & 0x200000)>>21; + res->fields_mask[FIELD_W >> 6] |= 1LL << (FIELD_W & 63); + char W_width = 1; + res->fields[FIELD_mode] = instr & 0x1F; + res->fields_mask[FIELD_mode >> 6] |= 1LL << (FIELD_mode & 63); + char mode_width = 5; + + static const instruction_format instr_formats[] = + { + { /* SRS{<amode>} SP{!},#<mode> */ + "srs", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_AMODE, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_SP,FIELD_UNINIT,FIELD_UNINIT,"sp","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_IMM,FIELD_mode,FIELD_UNINIT,"#","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_SRS; + + /* pcode: wback = (W == '1') */ + res->fields[FIELD_wback] = ((res->fields[FIELD_W]) == (0x1)); + res->fields_mask[FIELD_wback >> 6] |= 1LL << (FIELD_wback & 63); + /* pcode: inc = (U == '1') */ + res->fields[FIELD_inc] = ((res->fields[FIELD_U]) == (0x1)); + res->fields_mask[FIELD_inc >> 6] |= 1LL << (FIELD_inc & 63); + /* pcode: wordhigher = (P == U) */ + res->fields[FIELD_wordhigher] = ((res->fields[FIELD_P]) == (res->fields[FIELD_U])); + res->fields_mask[FIELD_wordhigher >> 6] |= 1LL << (FIELD_wordhigher & 63); + /* pcode: if !IsSecure() && mode == '10110' then UNPREDICTABLE */ + if(!((req->arch & ARCH_SECURITY_EXTENSIONS /* || SCR.NS=='0' || CPSR.M=='10110' */) && ((res->fields[FIELD_mode]) == (0x16)))) { + res->flags |= FLAG_UNPREDICTABLE; + } + /* pcode: if !IsSecure() && mode == '10001' && NSACR.RFR == '1' then UNPREDICTABLE */ + if(!(((req->arch & ARCH_SECURITY_EXTENSIONS /* || SCR.NS=='0' || CPSR.M=='10110' */) && ((res->fields[FIELD_mode]) == (0x11))) && ((res->fields[FIELD_NSACR_RFR]) == (0x1)))) { + res->flags |= FLAG_UNPREDICTABLE; + } + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: 6A6D7C15 +int ssat(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + /* Encoding T1 */ + /* pattern="11110,(0),11,00,sh.1,0,Rn.4,0,imm3.3,Rd.4,imm2.2,(0),sat_imm.5" width=32 stringency=14 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFBD08000)==0xF3000000)) { + res->instrSize = 32; + if(!((instr & 0x4000020)==0x0)) { + res->flags |= FLAG_UNPREDICTABLE; + } + if(!(req->arch & ARCH_ARMv6T2) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_sh] = (instr & 0x200000)>>21; + res->fields_mask[FIELD_sh >> 6] |= 1LL << (FIELD_sh & 63); + char sh_width = 1; + res->fields[FIELD_Rn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Rn >> 6] |= 1LL << (FIELD_Rn & 63); + char Rn_width = 4; + res->fields[FIELD_imm3] = (instr & 0x7000)>>12; + res->fields_mask[FIELD_imm3 >> 6] |= 1LL << (FIELD_imm3 & 63); + char imm3_width = 3; + res->fields[FIELD_Rd] = (instr & 0xF00)>>8; + res->fields_mask[FIELD_Rd >> 6] |= 1LL << (FIELD_Rd & 63); + char Rd_width = 4; + res->fields[FIELD_imm2] = (instr & 0xC0)>>6; + res->fields_mask[FIELD_imm2 >> 6] |= 1LL << (FIELD_imm2 & 63); + char imm2_width = 2; + res->fields[FIELD_sat_imm] = instr & 0x1F; + res->fields_mask[FIELD_sat_imm >> 6] |= 1LL << (FIELD_sat_imm & 63); + char sat_imm_width = 5; + + static const instruction_format instr_formats[] = + { + { /* SSAT<c> <Rd>,#<saturate_to>,<Rn>{,<shift>} */ + "ssat", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rd,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_IMM,FIELD_saturate_to,FIELD_UNINIT,"#","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rn,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_SHIFT,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 4 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_SSAT; + + /* pcode: if sh == '1' && (imm3:imm2) == '00000' then SEE SSAT16 */ + if(((res->fields[FIELD_sh]) == (0x1)) && ((((res->fields[FIELD_imm3]<<2)|(res->fields[FIELD_imm2]))) == (0x0))) { + + return ssat16(req, res); + } + /* pcode: d = UInt(Rd) */ + res->fields[FIELD_d] = (res->fields[FIELD_Rd]); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: n = UInt(Rn) */ + res->fields[FIELD_n] = (res->fields[FIELD_Rn]); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: saturate_to = UInt(sat_imm)+1 */ + res->fields[FIELD_saturate_to] = ((res->fields[FIELD_sat_imm])) + (1); + res->fields_mask[FIELD_saturate_to >> 6] |= 1LL << (FIELD_saturate_to & 63); + /* pcode: (shift_t, shift_n) = DecodeImmShift(sh:'0', imm3:imm2) */ + res->fields[FIELD_shift_t] = DecodeImmShift_shift_t((res->fields[FIELD_sh]<<1)|(0x0), (res->fields[FIELD_imm3]<<2)|(res->fields[FIELD_imm2])); + res->fields_mask[FIELD_shift_t >> 6] |= 1LL << (FIELD_shift_t & 63); + res->fields[FIELD_shift_n] = DecodeImmShift_shift_n((res->fields[FIELD_sh]<<1)|(0x0), (res->fields[FIELD_imm3]<<2)|(res->fields[FIELD_imm2])); + res->fields_mask[FIELD_shift_n >> 6] |= 1LL << (FIELD_shift_n & 63); + /* pcode: if BadReg(d) || BadReg(n) then UNPREDICTABLE */ + if((BadReg(res->fields[FIELD_d])) || (BadReg(res->fields[FIELD_n]))) { + res->flags |= FLAG_UNPREDICTABLE; + } + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: F41867C9 +int ssat16(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + /* Encoding T1 */ + /* pattern="11110,(0),11,001,0,Rn.4,0,000,Rd.4,00,(0)(0),sat_imm.4" width=32 stringency=20 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFBF0F0C0)==0xF3200000)) { + res->instrSize = 32; + if(!((instr & 0x4000030)==0x0)) { + res->flags |= FLAG_UNPREDICTABLE; + } + if(!(req->arch & ARCH_ARMv6T2) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_Rn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Rn >> 6] |= 1LL << (FIELD_Rn & 63); + char Rn_width = 4; + res->fields[FIELD_Rd] = (instr & 0xF00)>>8; + res->fields_mask[FIELD_Rd >> 6] |= 1LL << (FIELD_Rd & 63); + char Rd_width = 4; + res->fields[FIELD_sat_imm] = instr & 0xF; + res->fields_mask[FIELD_sat_imm >> 6] |= 1LL << (FIELD_sat_imm & 63); + char sat_imm_width = 4; + + static const instruction_format instr_formats[] = + { + { /* SSAT16<c> <Rd>,#<saturate_to>,<Rn> */ + "ssat16", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rd,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_IMM,FIELD_saturate_to,FIELD_UNINIT,"#","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rn,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_SSAT16; + + /* pcode: d = UInt(Rd) */ + res->fields[FIELD_d] = (res->fields[FIELD_Rd]); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: n = UInt(Rn) */ + res->fields[FIELD_n] = (res->fields[FIELD_Rn]); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: saturate_to = UInt(sat_imm)+1 */ + res->fields[FIELD_saturate_to] = ((res->fields[FIELD_sat_imm])) + (1); + res->fields_mask[FIELD_saturate_to >> 6] |= 1LL << (FIELD_saturate_to & 63); + /* pcode: if BadReg(d) || BadReg(n) then UNPREDICTABLE */ + if((BadReg(res->fields[FIELD_d])) || (BadReg(res->fields[FIELD_n]))) { + res->flags |= FLAG_UNPREDICTABLE; + } + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: F7386282 +int ssax(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + /* Encoding T1 */ + /* pattern="11111,010,1,110,Rn.4,1111,Rd.4,0,000,Rm.4" width=32 stringency=20 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFFF0F0F0)==0xFAE0F000)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ARMv6T2) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_Rn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Rn >> 6] |= 1LL << (FIELD_Rn & 63); + char Rn_width = 4; + res->fields[FIELD_Rd] = (instr & 0xF00)>>8; + res->fields_mask[FIELD_Rd >> 6] |= 1LL << (FIELD_Rd & 63); + char Rd_width = 4; + res->fields[FIELD_Rm] = instr & 0xF; + res->fields_mask[FIELD_Rm >> 6] |= 1LL << (FIELD_Rm & 63); + char Rm_width = 4; + + static const instruction_format instr_formats[] = + { + { /* SSAX<c> <Rd>,<Rn>,<Rm> */ + "ssax", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rd,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rn,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rm,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_SSAX; + + /* pcode: d = UInt(Rd) */ + res->fields[FIELD_d] = (res->fields[FIELD_Rd]); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: n = UInt(Rn) */ + res->fields[FIELD_n] = (res->fields[FIELD_Rn]); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: m = UInt(Rm) */ + res->fields[FIELD_m] = (res->fields[FIELD_Rm]); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + /* pcode: if BadReg(d) || BadReg(n) || BadReg(m) then UNPREDICTABLE */ + if(((BadReg(res->fields[FIELD_d])) || (BadReg(res->fields[FIELD_n]))) || (BadReg(res->fields[FIELD_m]))) { + res->flags |= FLAG_UNPREDICTABLE; + } + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: 39554012 +int ssub16(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + /* Encoding T1 */ + /* pattern="11111,010,1,101,Rn.4,1111,Rd.4,0,000,Rm.4" width=32 stringency=20 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFFF0F0F0)==0xFAD0F000)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ARMv6T2) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_Rn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Rn >> 6] |= 1LL << (FIELD_Rn & 63); + char Rn_width = 4; + res->fields[FIELD_Rd] = (instr & 0xF00)>>8; + res->fields_mask[FIELD_Rd >> 6] |= 1LL << (FIELD_Rd & 63); + char Rd_width = 4; + res->fields[FIELD_Rm] = instr & 0xF; + res->fields_mask[FIELD_Rm >> 6] |= 1LL << (FIELD_Rm & 63); + char Rm_width = 4; + + static const instruction_format instr_formats[] = + { + { /* SSUB16<c> <Rd>,<Rn>,<Rm> */ + "ssub16", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rd,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rn,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rm,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_SSUB16; + + /* pcode: d = UInt(Rd) */ + res->fields[FIELD_d] = (res->fields[FIELD_Rd]); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: n = UInt(Rn) */ + res->fields[FIELD_n] = (res->fields[FIELD_Rn]); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: m = UInt(Rm) */ + res->fields[FIELD_m] = (res->fields[FIELD_Rm]); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + /* pcode: if BadReg(d) || BadReg(n) || BadReg(m) then UNPREDICTABLE */ + if(((BadReg(res->fields[FIELD_d])) || (BadReg(res->fields[FIELD_n]))) || (BadReg(res->fields[FIELD_m]))) { + res->flags |= FLAG_UNPREDICTABLE; + } + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: 9A2F8BD7 +int ssub8(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + /* Encoding T1 */ + /* pattern="11111,010,1,100,Rn.4,1111,Rd.4,0,000,Rm.4" width=32 stringency=20 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFFF0F0F0)==0xFAC0F000)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ARMv6T2) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_Rn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Rn >> 6] |= 1LL << (FIELD_Rn & 63); + char Rn_width = 4; + res->fields[FIELD_Rd] = (instr & 0xF00)>>8; + res->fields_mask[FIELD_Rd >> 6] |= 1LL << (FIELD_Rd & 63); + char Rd_width = 4; + res->fields[FIELD_Rm] = instr & 0xF; + res->fields_mask[FIELD_Rm >> 6] |= 1LL << (FIELD_Rm & 63); + char Rm_width = 4; + + static const instruction_format instr_formats[] = + { + { /* SSUB8<c> <Rd>,<Rn>,<Rm> */ + "ssub8", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rd,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rn,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rm,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_SSUB8; + + /* pcode: d = UInt(Rd) */ + res->fields[FIELD_d] = (res->fields[FIELD_Rd]); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: n = UInt(Rn) */ + res->fields[FIELD_n] = (res->fields[FIELD_Rn]); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: m = UInt(Rm) */ + res->fields[FIELD_m] = (res->fields[FIELD_Rm]); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + /* pcode: if BadReg(d) || BadReg(n) || BadReg(m) then UNPREDICTABLE */ + if(((BadReg(res->fields[FIELD_d])) || (BadReg(res->fields[FIELD_n]))) || (BadReg(res->fields[FIELD_m]))) { + res->flags |= FLAG_UNPREDICTABLE; + } + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: E681AD83 +int stc_stc2(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + /* Encoding T1 */ + /* pattern="1110,110,P.1,U.1,0,W.1,0,Rn.4,CRd.4,coproc.4,imm8.8" width=32 stringency=12 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFE500000)==0xEC000000)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ARMv6T2) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_P] = (instr & 0x1000000)>>24; + res->fields_mask[FIELD_P >> 6] |= 1LL << (FIELD_P & 63); + char P_width = 1; + res->fields[FIELD_U] = (instr & 0x800000)>>23; + res->fields_mask[FIELD_U >> 6] |= 1LL << (FIELD_U & 63); + char U_width = 1; + res->fields[FIELD_W] = (instr & 0x200000)>>21; + res->fields_mask[FIELD_W >> 6] |= 1LL << (FIELD_W & 63); + char W_width = 1; + res->fields[FIELD_Rn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Rn >> 6] |= 1LL << (FIELD_Rn & 63); + char Rn_width = 4; + res->fields[FIELD_CRd] = (instr & 0xF000)>>12; + res->fields_mask[FIELD_CRd >> 6] |= 1LL << (FIELD_CRd & 63); + char CRd_width = 4; + res->fields[FIELD_coproc] = (instr & 0xF00)>>8; + res->fields_mask[FIELD_coproc >> 6] |= 1LL << (FIELD_coproc & 63); + char coproc_width = 4; + res->fields[FIELD_imm8] = instr & 0xFF; + res->fields_mask[FIELD_imm8 >> 6] |= 1LL << (FIELD_imm8 & 63); + char imm8_width = 8; + + static const instruction_format instr_formats[] = + { + { /* STC<c> <coproc>,<CRd>,[<Rn>{,#<+/-><imm32>}] */ + "stc", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_COPROC,FIELD_coproc,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_COPROC_REG,FIELD_CRd,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_MEMORY_ONE_REG_OPTIONAL_ADD_IMM,FIELD_Rn,FIELD_imm32,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + { /* STC<c> <coproc>,<CRd>,[<Rn>,#<+/-><imm32>]! */ + "stc", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_COPROC,FIELD_coproc,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_COPROC_REG,FIELD_CRd,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_MEMORY_ONE_REG_ADD_IMM,FIELD_Rn,FIELD_imm32,"","",WRITEBACK_YES}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + { /* STC<c> <coproc>,<CRd>,[<Rn>],#<+/-><imm32> */ + "stc", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_COPROC,FIELD_coproc,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_COPROC_REG,FIELD_CRd,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_MEMORY_ONE_REG,FIELD_Rn,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_ADD_IMM,FIELD_imm32,FIELD_UNINIT,"#","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 4 /* .operandCount */ + }, + { /* STC<c> <coproc>,<CRd>,[<Rn>],<coproc_option> */ + "stc", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_COPROC,FIELD_coproc,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_COPROC_REG,FIELD_CRd,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_MEMORY_ONE_REG,FIELD_Rn,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_IMM,FIELD_imm8,FIELD_UNINIT,"{","}",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 4 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 4; + res->mnem = armv7::ARMV7_STC; + + /* pcode: D=0 */ + res->fields[FIELD_D] = 0; + res->fields_mask[FIELD_D >> 6] |= 1LL << (FIELD_D & 63); + /* pcode: if P == '0' && U == '0' && D == '0' && W == '0' then UNDEFINED */ + if(((((res->fields[FIELD_P]) == (0x0)) && ((res->fields[FIELD_U]) == (0x0))) && ((res->fields[FIELD_D]) == (0x0))) && ((res->fields[FIELD_W]) == (0x0))) { + res->status |= STATUS_UNDEFINED; + } + /* pcode: if P == '0' && U == '0' && D == '1' && W == '0' then SEE MCRR, MCRR2 */ + if(((((res->fields[FIELD_P]) == (0x0)) && ((res->fields[FIELD_U]) == (0x0))) && ((res->fields[FIELD_D]) == (0x1))) && ((res->fields[FIELD_W]) == (0x0))) { + + return mcrr_mcrr2(req, res); + } + /* pcode: if coproc == '1010' || coproc == '1011' then SEE "nop" */ + if(((res->fields[FIELD_coproc]) == (0xA)) || ((res->fields[FIELD_coproc]) == (0xB))) { + + return nop(req, res); + } + /* pcode: n = UInt(Rn) */ + res->fields[FIELD_n] = (res->fields[FIELD_Rn]); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: cp = UInt(coproc) */ + res->fields[FIELD_cp] = (res->fields[FIELD_coproc]); + res->fields_mask[FIELD_cp >> 6] |= 1LL << (FIELD_cp & 63); + /* pcode: imm32 = ZeroExtend(imm8:'00', 32) */ + res->fields[FIELD_imm32] = (res->fields[FIELD_imm8]<<2)|(0x0); + res->fields_mask[FIELD_imm32 >> 6] |= 1LL << (FIELD_imm32 & 63); + /* pcode: index = (P == '1') */ + res->fields[FIELD_index] = ((res->fields[FIELD_P]) == (0x1)); + res->fields_mask[FIELD_index >> 6] |= 1LL << (FIELD_index & 63); + /* pcode: add = (U == '1') */ + res->fields[FIELD_add] = ((res->fields[FIELD_U]) == (0x1)); + res->fields_mask[FIELD_add >> 6] |= 1LL << (FIELD_add & 63); + /* pcode: wback = (W == '1') */ + res->fields[FIELD_wback] = ((res->fields[FIELD_W]) == (0x1)); + res->fields_mask[FIELD_wback >> 6] |= 1LL << (FIELD_wback & 63); + /* pcode: if n == 15 && (wback || CurrentInstrSet() != InstrSet_ARM) then UNPREDICTABLE */ + if(((res->fields[FIELD_n]) == (15)) && (((res->fields[FIELD_wback]) || ((req->instrSet) != (res->fields[FIELD_InstrSet_ARM]))))) { + res->flags |= FLAG_UNPREDICTABLE; + } + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* Encoding T1 */ + /* pattern="1110,110,P.1,U.1,1,W.1,0,Rn.4,CRd.4,coproc.4,imm8.8" width=32 stringency=12 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFE500000)==0xEC400000)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ARMv6T2) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_P] = (instr & 0x1000000)>>24; + res->fields_mask[FIELD_P >> 6] |= 1LL << (FIELD_P & 63); + char P_width = 1; + res->fields[FIELD_U] = (instr & 0x800000)>>23; + res->fields_mask[FIELD_U >> 6] |= 1LL << (FIELD_U & 63); + char U_width = 1; + res->fields[FIELD_W] = (instr & 0x200000)>>21; + res->fields_mask[FIELD_W >> 6] |= 1LL << (FIELD_W & 63); + char W_width = 1; + res->fields[FIELD_Rn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Rn >> 6] |= 1LL << (FIELD_Rn & 63); + char Rn_width = 4; + res->fields[FIELD_CRd] = (instr & 0xF000)>>12; + res->fields_mask[FIELD_CRd >> 6] |= 1LL << (FIELD_CRd & 63); + char CRd_width = 4; + res->fields[FIELD_coproc] = (instr & 0xF00)>>8; + res->fields_mask[FIELD_coproc >> 6] |= 1LL << (FIELD_coproc & 63); + char coproc_width = 4; + res->fields[FIELD_imm8] = instr & 0xFF; + res->fields_mask[FIELD_imm8 >> 6] |= 1LL << (FIELD_imm8 & 63); + char imm8_width = 8; + + static const instruction_format instr_formats[] = + { + { /* STCL<c> <coproc>,<CRd>,[<Rn>{,#<+/-><imm32>}] */ + "stcl", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_COPROC,FIELD_coproc,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_COPROC_REG,FIELD_CRd,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_MEMORY_ONE_REG_OPTIONAL_ADD_IMM,FIELD_Rn,FIELD_imm32,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + { /* STCL<c> <coproc>,<CRd>,[<Rn>,#<+/-><imm32>]! */ + "stcl", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_COPROC,FIELD_coproc,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_COPROC_REG,FIELD_CRd,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_MEMORY_ONE_REG_ADD_IMM,FIELD_Rn,FIELD_imm32,"","",WRITEBACK_YES}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + { /* STCL<c> <coproc>,<CRd>,[<Rn>],#<+/-><imm32> */ + "stcl", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_COPROC,FIELD_coproc,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_COPROC_REG,FIELD_CRd,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_MEMORY_ONE_REG,FIELD_Rn,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_ADD_IMM,FIELD_imm32,FIELD_UNINIT,"#","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 4 /* .operandCount */ + }, + { /* STCL<c> <coproc>,<CRd>,[<Rn>],<coproc_option> */ + "stcl", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_COPROC,FIELD_coproc,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_COPROC_REG,FIELD_CRd,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_MEMORY_ONE_REG,FIELD_Rn,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_IMM,FIELD_imm8,FIELD_UNINIT,"{","}",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 4 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 4; + res->mnem = armv7::ARMV7_STCL; + + /* pcode: D=1 */ + res->fields[FIELD_D] = 1; + res->fields_mask[FIELD_D >> 6] |= 1LL << (FIELD_D & 63); + /* pcode: if P == '0' && U == '0' && D == '0' && W == '0' then UNDEFINED */ + if(((((res->fields[FIELD_P]) == (0x0)) && ((res->fields[FIELD_U]) == (0x0))) && ((res->fields[FIELD_D]) == (0x0))) && ((res->fields[FIELD_W]) == (0x0))) { + res->status |= STATUS_UNDEFINED; + } + /* pcode: if P == '0' && U == '0' && D == '1' && W == '0' then SEE MCRR, MCRR2 */ + if(((((res->fields[FIELD_P]) == (0x0)) && ((res->fields[FIELD_U]) == (0x0))) && ((res->fields[FIELD_D]) == (0x1))) && ((res->fields[FIELD_W]) == (0x0))) { + + return mcrr_mcrr2(req, res); + } + /* pcode: if coproc == '1010' || coproc == '1011' then SEE "nop" */ + if(((res->fields[FIELD_coproc]) == (0xA)) || ((res->fields[FIELD_coproc]) == (0xB))) { + + return nop(req, res); + } + /* pcode: n = UInt(Rn) */ + res->fields[FIELD_n] = (res->fields[FIELD_Rn]); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: cp = UInt(coproc) */ + res->fields[FIELD_cp] = (res->fields[FIELD_coproc]); + res->fields_mask[FIELD_cp >> 6] |= 1LL << (FIELD_cp & 63); + /* pcode: imm32 = ZeroExtend(imm8:'00', 32) */ + res->fields[FIELD_imm32] = (res->fields[FIELD_imm8]<<2)|(0x0); + res->fields_mask[FIELD_imm32 >> 6] |= 1LL << (FIELD_imm32 & 63); + /* pcode: index = (P == '1') */ + res->fields[FIELD_index] = ((res->fields[FIELD_P]) == (0x1)); + res->fields_mask[FIELD_index >> 6] |= 1LL << (FIELD_index & 63); + /* pcode: add = (U == '1') */ + res->fields[FIELD_add] = ((res->fields[FIELD_U]) == (0x1)); + res->fields_mask[FIELD_add >> 6] |= 1LL << (FIELD_add & 63); + /* pcode: wback = (W == '1') */ + res->fields[FIELD_wback] = ((res->fields[FIELD_W]) == (0x1)); + res->fields_mask[FIELD_wback >> 6] |= 1LL << (FIELD_wback & 63); + /* pcode: if n == 15 && (wback || CurrentInstrSet() != InstrSet_ARM) then UNPREDICTABLE */ + if(((res->fields[FIELD_n]) == (15)) && (((res->fields[FIELD_wback]) || ((req->instrSet) != (res->fields[FIELD_InstrSet_ARM]))))) { + res->flags |= FLAG_UNPREDICTABLE; + } + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* Encoding T2 */ + /* pattern="1111,110,P.1,U.1,0,W.1,0,Rn.4,CRd.4,coproc.4,imm8.8" width=32 stringency=12 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFE500000)==0xFC000000)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ARMv6T2) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_P] = (instr & 0x1000000)>>24; + res->fields_mask[FIELD_P >> 6] |= 1LL << (FIELD_P & 63); + char P_width = 1; + res->fields[FIELD_U] = (instr & 0x800000)>>23; + res->fields_mask[FIELD_U >> 6] |= 1LL << (FIELD_U & 63); + char U_width = 1; + res->fields[FIELD_W] = (instr & 0x200000)>>21; + res->fields_mask[FIELD_W >> 6] |= 1LL << (FIELD_W & 63); + char W_width = 1; + res->fields[FIELD_Rn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Rn >> 6] |= 1LL << (FIELD_Rn & 63); + char Rn_width = 4; + res->fields[FIELD_CRd] = (instr & 0xF000)>>12; + res->fields_mask[FIELD_CRd >> 6] |= 1LL << (FIELD_CRd & 63); + char CRd_width = 4; + res->fields[FIELD_coproc] = (instr & 0xF00)>>8; + res->fields_mask[FIELD_coproc >> 6] |= 1LL << (FIELD_coproc & 63); + char coproc_width = 4; + res->fields[FIELD_imm8] = instr & 0xFF; + res->fields_mask[FIELD_imm8 >> 6] |= 1LL << (FIELD_imm8 & 63); + char imm8_width = 8; + + static const instruction_format instr_formats[] = + { + { /* STC2<c> <coproc>,<CRd>,[<Rn>{,#<+/-><imm32>}] */ + "stc2", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_COPROC,FIELD_coproc,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_COPROC_REG,FIELD_CRd,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_MEMORY_ONE_REG_OPTIONAL_ADD_IMM,FIELD_Rn,FIELD_imm32,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + { /* STC2<c> <coproc>,<CRd>,[<Rn>,#<+/-><imm32>]! */ + "stc2", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_COPROC,FIELD_coproc,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_COPROC_REG,FIELD_CRd,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_MEMORY_ONE_REG_ADD_IMM,FIELD_Rn,FIELD_imm32,"","",WRITEBACK_YES}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + { /* STC2<c> <coproc>,<CRd>,[<Rn>],#<+/-><imm32> */ + "stc2", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_COPROC,FIELD_coproc,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_COPROC_REG,FIELD_CRd,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_MEMORY_ONE_REG,FIELD_Rn,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_ADD_IMM,FIELD_imm32,FIELD_UNINIT,"#","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 4 /* .operandCount */ + }, + { /* STC2<c> <coproc>,<CRd>,[<Rn>],<coproc_option> */ + "stc2", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_COPROC,FIELD_coproc,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_COPROC_REG,FIELD_CRd,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_MEMORY_ONE_REG,FIELD_Rn,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_IMM,FIELD_imm8,FIELD_UNINIT,"{","}",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 4 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 4; + res->mnem = armv7::ARMV7_STC2; + + /* pcode: D=0 */ + res->fields[FIELD_D] = 0; + res->fields_mask[FIELD_D >> 6] |= 1LL << (FIELD_D & 63); + /* pcode: if P == '0' && U == '0' && D == '0' && W == '0' then UNDEFINED */ + if(((((res->fields[FIELD_P]) == (0x0)) && ((res->fields[FIELD_U]) == (0x0))) && ((res->fields[FIELD_D]) == (0x0))) && ((res->fields[FIELD_W]) == (0x0))) { + res->status |= STATUS_UNDEFINED; + } + /* pcode: if P == '0' && U == '0' && D == '1' && W == '0' then SEE MCRR, MCRR2 */ + if(((((res->fields[FIELD_P]) == (0x0)) && ((res->fields[FIELD_U]) == (0x0))) && ((res->fields[FIELD_D]) == (0x1))) && ((res->fields[FIELD_W]) == (0x0))) { + + return mcrr_mcrr2(req, res); + } + /* pcode: n = UInt(Rn) */ + res->fields[FIELD_n] = (res->fields[FIELD_Rn]); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: cp = UInt(coproc) */ + res->fields[FIELD_cp] = (res->fields[FIELD_coproc]); + res->fields_mask[FIELD_cp >> 6] |= 1LL << (FIELD_cp & 63); + /* pcode: imm32 = ZeroExtend(imm8:'00', 32) */ + res->fields[FIELD_imm32] = (res->fields[FIELD_imm8]<<2)|(0x0); + res->fields_mask[FIELD_imm32 >> 6] |= 1LL << (FIELD_imm32 & 63); + /* pcode: index = (P == '1') */ + res->fields[FIELD_index] = ((res->fields[FIELD_P]) == (0x1)); + res->fields_mask[FIELD_index >> 6] |= 1LL << (FIELD_index & 63); + /* pcode: add = (U == '1') */ + res->fields[FIELD_add] = ((res->fields[FIELD_U]) == (0x1)); + res->fields_mask[FIELD_add >> 6] |= 1LL << (FIELD_add & 63); + /* pcode: wback = (W == '1') */ + res->fields[FIELD_wback] = ((res->fields[FIELD_W]) == (0x1)); + res->fields_mask[FIELD_wback >> 6] |= 1LL << (FIELD_wback & 63); + /* pcode: if n == 15 && (wback || CurrentInstrSet() != InstrSet_ARM) then UNPREDICTABLE */ + if(((res->fields[FIELD_n]) == (15)) && (((res->fields[FIELD_wback]) || ((req->instrSet) != (res->fields[FIELD_InstrSet_ARM]))))) { + res->flags |= FLAG_UNPREDICTABLE; + } + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* Encoding T2 */ + /* pattern="1111,110,P.1,U.1,D.1,W.1,0,Rn.4,CRd.4,coproc.4,imm8.8" width=32 stringency=12 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFE100000)==0xFC000000)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ARMv6T2) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_P] = (instr & 0x1000000)>>24; + res->fields_mask[FIELD_P >> 6] |= 1LL << (FIELD_P & 63); + char P_width = 1; + res->fields[FIELD_U] = (instr & 0x800000)>>23; + res->fields_mask[FIELD_U >> 6] |= 1LL << (FIELD_U & 63); + char U_width = 1; + res->fields[FIELD_D] = (instr & 0x400000)>>22; + res->fields_mask[FIELD_D >> 6] |= 1LL << (FIELD_D & 63); + char D_width = 1; + res->fields[FIELD_W] = (instr & 0x200000)>>21; + res->fields_mask[FIELD_W >> 6] |= 1LL << (FIELD_W & 63); + char W_width = 1; + res->fields[FIELD_Rn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Rn >> 6] |= 1LL << (FIELD_Rn & 63); + char Rn_width = 4; + res->fields[FIELD_CRd] = (instr & 0xF000)>>12; + res->fields_mask[FIELD_CRd >> 6] |= 1LL << (FIELD_CRd & 63); + char CRd_width = 4; + res->fields[FIELD_coproc] = (instr & 0xF00)>>8; + res->fields_mask[FIELD_coproc >> 6] |= 1LL << (FIELD_coproc & 63); + char coproc_width = 4; + res->fields[FIELD_imm8] = instr & 0xFF; + res->fields_mask[FIELD_imm8 >> 6] |= 1LL << (FIELD_imm8 & 63); + char imm8_width = 8; + + static const instruction_format instr_formats[] = + { + { /* STC2L<c> <coproc>,<CRd>,[<Rn>{,#<+/-><imm32>}] */ + "stc2l", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_COPROC,FIELD_coproc,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_COPROC_REG,FIELD_CRd,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_MEMORY_ONE_REG_OPTIONAL_ADD_IMM,FIELD_Rn,FIELD_imm32,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + { /* STC2L<c> <coproc>,<CRd>,[<Rn>,#<+/-><imm32>]! */ + "stc2l", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_COPROC,FIELD_coproc,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_COPROC_REG,FIELD_CRd,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_MEMORY_ONE_REG_ADD_IMM,FIELD_Rn,FIELD_imm32,"","",WRITEBACK_YES}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + { /* STC2L<c> <coproc>,<CRd>,[<Rn>],#<+/-><imm32> */ + "stc2l", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_COPROC,FIELD_coproc,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_COPROC_REG,FIELD_CRd,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_MEMORY_ONE_REG,FIELD_Rn,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_ADD_IMM,FIELD_imm32,FIELD_UNINIT,"#","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 4 /* .operandCount */ + }, + { /* STC2L<c> <coproc>,<CRd>,[<Rn>],<coproc_option> */ + "stc2l", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_COPROC,FIELD_coproc,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_COPROC_REG,FIELD_CRd,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_MEMORY_ONE_REG,FIELD_Rn,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_IMM,FIELD_imm8,FIELD_UNINIT,"{","}",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 4 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 4; + res->mnem = armv7::ARMV7_STC2L; + + /* pcode: D=1 */ + res->fields[FIELD_D] = 1; + res->fields_mask[FIELD_D >> 6] |= 1LL << (FIELD_D & 63); + /* pcode: if P == '0' && U == '0' && D == '0' && W == '0' then UNDEFINED */ + if(((((res->fields[FIELD_P]) == (0x0)) && ((res->fields[FIELD_U]) == (0x0))) && ((res->fields[FIELD_D]) == (0x0))) && ((res->fields[FIELD_W]) == (0x0))) { + res->status |= STATUS_UNDEFINED; + } + /* pcode: if P == '0' && U == '0' && D == '1' && W == '0' then SEE MCRR, MCRR2 */ + if(((((res->fields[FIELD_P]) == (0x0)) && ((res->fields[FIELD_U]) == (0x0))) && ((res->fields[FIELD_D]) == (0x1))) && ((res->fields[FIELD_W]) == (0x0))) { + + return mcrr_mcrr2(req, res); + } + /* pcode: n = UInt(Rn) */ + res->fields[FIELD_n] = (res->fields[FIELD_Rn]); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: cp = UInt(coproc) */ + res->fields[FIELD_cp] = (res->fields[FIELD_coproc]); + res->fields_mask[FIELD_cp >> 6] |= 1LL << (FIELD_cp & 63); + /* pcode: imm32 = ZeroExtend(imm8:'00', 32) */ + res->fields[FIELD_imm32] = (res->fields[FIELD_imm8]<<2)|(0x0); + res->fields_mask[FIELD_imm32 >> 6] |= 1LL << (FIELD_imm32 & 63); + /* pcode: index = (P == '1') */ + res->fields[FIELD_index] = ((res->fields[FIELD_P]) == (0x1)); + res->fields_mask[FIELD_index >> 6] |= 1LL << (FIELD_index & 63); + /* pcode: add = (U == '1') */ + res->fields[FIELD_add] = ((res->fields[FIELD_U]) == (0x1)); + res->fields_mask[FIELD_add >> 6] |= 1LL << (FIELD_add & 63); + /* pcode: wback = (W == '1') */ + res->fields[FIELD_wback] = ((res->fields[FIELD_W]) == (0x1)); + res->fields_mask[FIELD_wback >> 6] |= 1LL << (FIELD_wback & 63); + /* pcode: if n == 15 && (wback || CurrentInstrSet() != InstrSet_ARM) then UNPREDICTABLE */ + if(((res->fields[FIELD_n]) == (15)) && (((res->fields[FIELD_wback]) || ((req->instrSet) != (res->fields[FIELD_InstrSet_ARM]))))) { + res->flags |= FLAG_UNPREDICTABLE; + } + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: 87B9D464 +int stl(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + /* Encoding T1 */ + /* pattern="111,0100,01,1,00,Rn.4,Rt.4,(1)(1)(1)(1),1010,(1)(1)(1)(1)" width=32 stringency=24 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFFF000F0)==0xE8C000A0)) { + res->instrSize = 32; + if(!((instr & 0xF0F)==0xF0F)) { + res->flags |= FLAG_UNPREDICTABLE; + } + if(!(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_Rn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Rn >> 6] |= 1LL << (FIELD_Rn & 63); + char Rn_width = 4; + res->fields[FIELD_Rt] = (instr & 0xF000)>>12; + res->fields_mask[FIELD_Rt >> 6] |= 1LL << (FIELD_Rt & 63); + char Rt_width = 4; + + static const instruction_format instr_formats[] = + { + { /* STL<c> <Rt>,[<Rn>] */ + "stl", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rt,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_MEMORY_ONE_REG,FIELD_Rn,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_STL; + + /* pcode: t = UInt(Rt) */ + res->fields[FIELD_t] = (res->fields[FIELD_Rt]); + res->fields_mask[FIELD_t >> 6] |= 1LL << (FIELD_t & 63); + /* pcode: n = UInt(Rn) */ + res->fields[FIELD_n] = (res->fields[FIELD_Rn]); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: if BadReg(t) || n == 15 then UNPREDICTABLE */ + if((BadReg(res->fields[FIELD_t])) || ((res->fields[FIELD_n]) == (15))) { + res->flags |= FLAG_UNPREDICTABLE; + } + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: 01D8911F +int stlb(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + /* Encoding T1 */ + /* pattern="111,0100,01,1,00,Rn.4,Rt.4,(1)(1)(1)(1),1000,(1)(1)(1)(1)" width=32 stringency=24 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFFF000F0)==0xE8C00080)) { + res->instrSize = 32; + if(!((instr & 0xF0F)==0xF0F)) { + res->flags |= FLAG_UNPREDICTABLE; + } + if(!(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_Rn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Rn >> 6] |= 1LL << (FIELD_Rn & 63); + char Rn_width = 4; + res->fields[FIELD_Rt] = (instr & 0xF000)>>12; + res->fields_mask[FIELD_Rt >> 6] |= 1LL << (FIELD_Rt & 63); + char Rt_width = 4; + + static const instruction_format instr_formats[] = + { + { /* STLB<c> <Rt>,[<Rn>] */ + "stlb", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rt,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_MEMORY_ONE_REG,FIELD_Rn,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_STLB; + + /* pcode: t = UInt(Rt) */ + res->fields[FIELD_t] = (res->fields[FIELD_Rt]); + res->fields_mask[FIELD_t >> 6] |= 1LL << (FIELD_t & 63); + /* pcode: n = UInt(Rn) */ + res->fields[FIELD_n] = (res->fields[FIELD_Rn]); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: if BadReg(t) || n == 15 then UNPREDICTABLE */ + if((BadReg(res->fields[FIELD_t])) || ((res->fields[FIELD_n]) == (15))) { + res->flags |= FLAG_UNPREDICTABLE; + } + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: 41D684D6 +int stlex(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + /* Encoding T1 */ + /* pattern="111,0100,01,1,00,Rn.4,Rt.4,(1)(1)(1)(1),1110,Rd.4" width=32 stringency=20 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFFF000F0)==0xE8C000E0)) { + res->instrSize = 32; + if(!((instr & 0xF00)==0xF00)) { + res->flags |= FLAG_UNPREDICTABLE; + } + if(!(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_Rn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Rn >> 6] |= 1LL << (FIELD_Rn & 63); + char Rn_width = 4; + res->fields[FIELD_Rt] = (instr & 0xF000)>>12; + res->fields_mask[FIELD_Rt >> 6] |= 1LL << (FIELD_Rt & 63); + char Rt_width = 4; + res->fields[FIELD_Rd] = instr & 0xF; + res->fields_mask[FIELD_Rd >> 6] |= 1LL << (FIELD_Rd & 63); + char Rd_width = 4; + + static const instruction_format instr_formats[] = + { + { /* STLEX<c> <Rd>,<Rt>,[<Rn>] */ + "stlex", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rd,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rt,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_MEMORY_ONE_REG,FIELD_Rn,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_STLEX; + + /* pcode: d = UInt(Rd) */ + res->fields[FIELD_d] = (res->fields[FIELD_Rd]); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: t = UInt(Rt) */ + res->fields[FIELD_t] = (res->fields[FIELD_Rt]); + res->fields_mask[FIELD_t >> 6] |= 1LL << (FIELD_t & 63); + /* pcode: n = UInt(Rn) */ + res->fields[FIELD_n] = (res->fields[FIELD_Rn]); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: if BadReg(d) || BadReg(t) || n == 15 then UNPREDICTABLE */ + if(((BadReg(res->fields[FIELD_d])) || (BadReg(res->fields[FIELD_t]))) || ((res->fields[FIELD_n]) == (15))) { + res->flags |= FLAG_UNPREDICTABLE; + } + /* pcode: if d == n || d == t then UNPREDICTABLE */ + if(((res->fields[FIELD_d]) == (res->fields[FIELD_n])) || ((res->fields[FIELD_d]) == (res->fields[FIELD_t]))) { + res->flags |= FLAG_UNPREDICTABLE; + } + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: B856BAB1 +int stlexb(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + /* Encoding T1 */ + /* pattern="111,0100,01,1,00,Rn.4,Rt.4,(1)(1)(1)(1),1100,Rd.4" width=32 stringency=20 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFFF000F0)==0xE8C000C0)) { + res->instrSize = 32; + if(!((instr & 0xF00)==0xF00)) { + res->flags |= FLAG_UNPREDICTABLE; + } + if(!(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_Rn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Rn >> 6] |= 1LL << (FIELD_Rn & 63); + char Rn_width = 4; + res->fields[FIELD_Rt] = (instr & 0xF000)>>12; + res->fields_mask[FIELD_Rt >> 6] |= 1LL << (FIELD_Rt & 63); + char Rt_width = 4; + res->fields[FIELD_Rd] = instr & 0xF; + res->fields_mask[FIELD_Rd >> 6] |= 1LL << (FIELD_Rd & 63); + char Rd_width = 4; + + static const instruction_format instr_formats[] = + { + { /* STLEXB<c> <Rd>,<Rt>,[<Rn>] */ + "stlexb", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rd,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rt,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_MEMORY_ONE_REG,FIELD_Rn,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_STLEXB; + + /* pcode: d = UInt(Rd) */ + res->fields[FIELD_d] = (res->fields[FIELD_Rd]); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: t = UInt(Rt) */ + res->fields[FIELD_t] = (res->fields[FIELD_Rt]); + res->fields_mask[FIELD_t >> 6] |= 1LL << (FIELD_t & 63); + /* pcode: n = UInt(Rn) */ + res->fields[FIELD_n] = (res->fields[FIELD_Rn]); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: if BadReg(d) || BadReg(t) || n == 15 then UNPREDICTABLE */ + if(((BadReg(res->fields[FIELD_d])) || (BadReg(res->fields[FIELD_t]))) || ((res->fields[FIELD_n]) == (15))) { + res->flags |= FLAG_UNPREDICTABLE; + } + /* pcode: if d == n || d == t then UNPREDICTABLE */ + if(((res->fields[FIELD_d]) == (res->fields[FIELD_n])) || ((res->fields[FIELD_d]) == (res->fields[FIELD_t]))) { + res->flags |= FLAG_UNPREDICTABLE; + } + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: D1A095EF +int stlexh(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + /* Encoding T1 */ + /* pattern="111,0100,01,1,00,Rn.4,Rt.4,(1)(1)(1)(1),1101,Rd.4" width=32 stringency=20 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFFF000F0)==0xE8C000D0)) { + res->instrSize = 32; + if(!((instr & 0xF00)==0xF00)) { + res->flags |= FLAG_UNPREDICTABLE; + } + if(!(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_Rn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Rn >> 6] |= 1LL << (FIELD_Rn & 63); + char Rn_width = 4; + res->fields[FIELD_Rt] = (instr & 0xF000)>>12; + res->fields_mask[FIELD_Rt >> 6] |= 1LL << (FIELD_Rt & 63); + char Rt_width = 4; + res->fields[FIELD_Rd] = instr & 0xF; + res->fields_mask[FIELD_Rd >> 6] |= 1LL << (FIELD_Rd & 63); + char Rd_width = 4; + + static const instruction_format instr_formats[] = + { + { /* STLEXH<c> <Rd>,<Rt>,[<Rn>] */ + "stlexh", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rd,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rt,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_MEMORY_ONE_REG,FIELD_Rn,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_STLEXH; + + /* pcode: d = UInt(Rd) */ + res->fields[FIELD_d] = (res->fields[FIELD_Rd]); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: t = UInt(Rt) */ + res->fields[FIELD_t] = (res->fields[FIELD_Rt]); + res->fields_mask[FIELD_t >> 6] |= 1LL << (FIELD_t & 63); + /* pcode: n = UInt(Rn) */ + res->fields[FIELD_n] = (res->fields[FIELD_Rn]); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: if BadReg(d) || BadReg(t) || n == 15 then UNPREDICTABLE */ + if(((BadReg(res->fields[FIELD_d])) || (BadReg(res->fields[FIELD_t]))) || ((res->fields[FIELD_n]) == (15))) { + res->flags |= FLAG_UNPREDICTABLE; + } + /* pcode: if d == n || d == t then UNPREDICTABLE */ + if(((res->fields[FIELD_d]) == (res->fields[FIELD_n])) || ((res->fields[FIELD_d]) == (res->fields[FIELD_t]))) { + res->flags |= FLAG_UNPREDICTABLE; + } + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: AB3D4D00 +int stlh(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + /* Encoding T1 */ + /* pattern="111,0100,01,1,00,Rn.4,Rt.4,(1)(1)(1)(1),1001,(1)(1)(1)(1)" width=32 stringency=24 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFFF000F0)==0xE8C00090)) { + res->instrSize = 32; + if(!((instr & 0xF0F)==0xF0F)) { + res->flags |= FLAG_UNPREDICTABLE; + } + if(!(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_Rn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Rn >> 6] |= 1LL << (FIELD_Rn & 63); + char Rn_width = 4; + res->fields[FIELD_Rt] = (instr & 0xF000)>>12; + res->fields_mask[FIELD_Rt >> 6] |= 1LL << (FIELD_Rt & 63); + char Rt_width = 4; + + static const instruction_format instr_formats[] = + { + { /* STLH<c> <Rt>,[<Rn>] */ + "stlh", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rt,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_MEMORY_ONE_REG,FIELD_Rn,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_STLH; + + /* pcode: t = UInt(Rt) */ + res->fields[FIELD_t] = (res->fields[FIELD_Rt]); + res->fields_mask[FIELD_t >> 6] |= 1LL << (FIELD_t & 63); + /* pcode: n = UInt(Rn) */ + res->fields[FIELD_n] = (res->fields[FIELD_Rn]); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: if BadReg(t) || n == 15 then UNPREDICTABLE */ + if((BadReg(res->fields[FIELD_t])) || ((res->fields[FIELD_n]) == (15))) { + res->flags |= FLAG_UNPREDICTABLE; + } + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: 2463F06A +int stm(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + /* Encoding T1 */ + /* pattern="1100,0,Rn.3,register_list.8" width=16 stringency=5 */ + { + uint16_t instr = req->instr_word16; + if(((instr & 0xF800)==0xC000)) { + res->instrSize = 16; + if(!(req->arch & ARCH_ARMv4T) && !(req->arch & ARCH_ARMv5T) && !(req->arch & ARCH_ARMv6) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_Rn] = (instr & 0x700)>>8; + res->fields_mask[FIELD_Rn >> 6] |= 1LL << (FIELD_Rn & 63); + char Rn_width = 3; + res->fields[FIELD_register_list] = instr & 0xFF; + res->fields_mask[FIELD_register_list >> 6] |= 1LL << (FIELD_register_list & 63); + char register_list_width = 8; + + static const instruction_format instr_formats[] = + { + { /* STM<c> <Rn>!,<registers> */ + "stm", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rn,FIELD_UNINIT,"","",WRITEBACK_YES}, + {OPERAND_FORMAT_REGISTERS,FIELD_registers,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_STM; + + /* pcode: n = UInt(Rn) */ + res->fields[FIELD_n] = (res->fields[FIELD_Rn]); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: registers = '00000000':register_list */ + res->fields[FIELD_registers] = (0x0<<register_list_width)|(res->fields[FIELD_register_list]); + res->fields_mask[FIELD_registers >> 6] |= 1LL << (FIELD_registers & 63); + /* pcode: wback = TRUE */ + res->fields[FIELD_wback] = 1; + res->fields_mask[FIELD_wback >> 6] |= 1LL << (FIELD_wback & 63); + /* pcode: if BitCount(registers) < 1 then UNPREDICTABLE */ + if((BitCount(res->fields[FIELD_registers])) < (1)) { + res->flags |= FLAG_UNPREDICTABLE; + } + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* Encoding T2 */ + /* pattern="11101,00,010,W.1,0,Rn.4,(0),M.1,register_list.14" width=32 stringency=15 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFFD00000)==0xE8800000)) { + res->instrSize = 32; + if(!((instr & 0x8000)==0x0)) { + res->flags |= FLAG_UNPREDICTABLE; + } + if(!(req->arch & ARCH_ARMv6T2) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_W] = (instr & 0x200000)>>21; + res->fields_mask[FIELD_W >> 6] |= 1LL << (FIELD_W & 63); + char W_width = 1; + res->fields[FIELD_Rn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Rn >> 6] |= 1LL << (FIELD_Rn & 63); + char Rn_width = 4; + res->fields[FIELD_M] = (instr & 0x4000)>>14; + res->fields_mask[FIELD_M >> 6] |= 1LL << (FIELD_M & 63); + char M_width = 1; + res->fields[FIELD_register_list] = instr & 0x3FFF; + res->fields_mask[FIELD_register_list >> 6] |= 1LL << (FIELD_register_list & 63); + char register_list_width = 14; + + static const instruction_format instr_formats[] = + { + { /* STM<c> <Rn>{!},<registers> */ + "stm", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rn,FIELD_UNINIT,"","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REGISTERS,FIELD_registers,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_STM; + + /* pcode: n = UInt(Rn) */ + res->fields[FIELD_n] = (res->fields[FIELD_Rn]); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: registers = '0':M:register_list */ + res->fields[FIELD_registers] = (0x0<<(register_list_width+M_width))|(res->fields[FIELD_M]<<register_list_width)|(res->fields[FIELD_register_list]); + res->fields_mask[FIELD_registers >> 6] |= 1LL << (FIELD_registers & 63); + /* pcode: wback = (W == '1') */ + res->fields[FIELD_wback] = ((res->fields[FIELD_W]) == (0x1)); + res->fields_mask[FIELD_wback >> 6] |= 1LL << (FIELD_wback & 63); + /* pcode: if n == 15 || BitCount(registers) < 2 then UNPREDICTABLE */ + if(((res->fields[FIELD_n]) == (15)) || ((BitCount(res->fields[FIELD_registers])) < (2))) { + res->flags |= FLAG_UNPREDICTABLE; + } + /* pcode: if wback && registers<n> == '1' then UNPREDICTABLE */ + if((res->fields[FIELD_wback]) && (((res->fields[FIELD_registers] & (1<<res->fields[FIELD_n])) >> res->fields[FIELD_n]) == (0x1))) { + res->flags |= FLAG_UNPREDICTABLE; + } + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: 1C8B82A7 +int stmdb(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + /* Encoding T1 */ + /* pattern="11101,00,100,W.1,0,Rn.4,(0),M.1,register_list.14" width=32 stringency=15 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFFD00000)==0xE9000000)) { + res->instrSize = 32; + if(!((instr & 0x8000)==0x0)) { + res->flags |= FLAG_UNPREDICTABLE; + } + if(!(req->arch & ARCH_ARMv6T2) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_W] = (instr & 0x200000)>>21; + res->fields_mask[FIELD_W >> 6] |= 1LL << (FIELD_W & 63); + char W_width = 1; + res->fields[FIELD_Rn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Rn >> 6] |= 1LL << (FIELD_Rn & 63); + char Rn_width = 4; + res->fields[FIELD_M] = (instr & 0x4000)>>14; + res->fields_mask[FIELD_M >> 6] |= 1LL << (FIELD_M & 63); + char M_width = 1; + res->fields[FIELD_register_list] = instr & 0x3FFF; + res->fields_mask[FIELD_register_list >> 6] |= 1LL << (FIELD_register_list & 63); + char register_list_width = 14; + + static const instruction_format instr_formats[] = + { + { /* STMDB<c> <Rn>{!},<registers> */ + "stmdb", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rn,FIELD_UNINIT,"","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REGISTERS,FIELD_registers,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_STMDB; + + /* pcode: if W == '1' && Rn == '1101' then SEE PUSH */ + if(((res->fields[FIELD_W]) == (0x1)) && ((res->fields[FIELD_Rn]) == (0xD))) { + + return push(req, res); + } + /* pcode: n = UInt(Rn) */ + res->fields[FIELD_n] = (res->fields[FIELD_Rn]); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: registers = '0':M:register_list */ + res->fields[FIELD_registers] = (0x0<<(register_list_width+M_width))|(res->fields[FIELD_M]<<register_list_width)|(res->fields[FIELD_register_list]); + res->fields_mask[FIELD_registers >> 6] |= 1LL << (FIELD_registers & 63); + /* pcode: wback = (W == '1') */ + res->fields[FIELD_wback] = ((res->fields[FIELD_W]) == (0x1)); + res->fields_mask[FIELD_wback >> 6] |= 1LL << (FIELD_wback & 63); + /* pcode: if n == 15 || BitCount(registers) < 2 then UNPREDICTABLE */ + if(((res->fields[FIELD_n]) == (15)) || ((BitCount(res->fields[FIELD_registers])) < (2))) { + res->flags |= FLAG_UNPREDICTABLE; + } + /* pcode: if wback && registers<n> == '1' then UNPREDICTABLE */ + if((res->fields[FIELD_wback]) && (((res->fields[FIELD_registers] & (1<<res->fields[FIELD_n])) >> res->fields[FIELD_n]) == (0x1))) { + res->flags |= FLAG_UNPREDICTABLE; + } + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: 8805FBA7 +int store_single_data_item(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + uint32_t instr = req->instr_word32; + uint32_t op1 = (instr & 0xE00000)>>21; + uint32_t op2 = (instr & 0xFC0)>>6; + if(((op1 & 0x7)==0x0) && ((op2 & 0x3C)==0x30)) return strb_immediate(req, res); + if(((op1 & 0x7)==0x0) && ((op2 & 0x3C)==0x38)) return strbt(req, res); + if(((op1 & 0x7)==0x1) && ((op2 & 0x3C)==0x30)) return strh_immediate(req, res); + if(((op1 & 0x7)==0x1) && ((op2 & 0x3C)==0x38)) return strht(req, res); + if(((op1 & 0x7)==0x2) && ((op2 & 0x3C)==0x30)) return str_immediate(req, res); + if(((op1 & 0x7)==0x2) && ((op2 & 0x3C)==0x38)) return strt(req, res); + if(((op1 & 0x7)==0x0) && ((op2 & 0x24)==0x24)) return strb_immediate(req, res); + if(((op1 & 0x7)==0x1) && ((op2 & 0x24)==0x24)) return strh_immediate(req, res); + if(((op1 & 0x7)==0x2) && ((op2 & 0x24)==0x24)) return str_immediate(req, res); + if(((op1 & 0x7)==0x0) && ((op2 & 0x20)==0x0)) return strb_register(req, res); + if(((op1 & 0x7)==0x1) && ((op2 & 0x20)==0x0)) return strh_register(req, res); + if(((op1 & 0x7)==0x2) && ((op2 & 0x20)==0x0)) return str_register(req, res); + if(((op1 & 0x7)==0x4) && 1) return strb_immediate(req, res); + if(((op1 & 0x7)==0x5) && 1) return strh_immediate(req, res); + if(((op1 & 0x7)==0x6) && 1) return str_immediate(req, res); + return undefined(req, res); +} + +// gen_crc: B0EFC0F2 +int str_immediate(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + /* Encoding T1 */ + /* pattern="011,0,0,imm5.5,Rn.3,Rt.3" width=16 stringency=5 */ + { + uint16_t instr = req->instr_word16; + if(((instr & 0xF800)==0x6000)) { + res->instrSize = 16; + if(!(req->arch & ARCH_ARMv4T) && !(req->arch & ARCH_ARMv5T) && !(req->arch & ARCH_ARMv6) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_imm5] = (instr & 0x7C0)>>6; + res->fields_mask[FIELD_imm5 >> 6] |= 1LL << (FIELD_imm5 & 63); + char imm5_width = 5; + res->fields[FIELD_Rn] = (instr & 0x38)>>3; + res->fields_mask[FIELD_Rn >> 6] |= 1LL << (FIELD_Rn & 63); + char Rn_width = 3; + res->fields[FIELD_Rt] = instr & 0x7; + res->fields_mask[FIELD_Rt >> 6] |= 1LL << (FIELD_Rt & 63); + char Rt_width = 3; + + static const instruction_format instr_formats[] = + { + { /* STR<c> <Rt>,[<Rn>{,#<imm32>}] */ + "str", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rt,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_MEMORY_ONE_REG_OPTIONAL_IMM,FIELD_Rn,FIELD_imm32,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_STR; + + /* pcode: t = UInt(Rt) */ + res->fields[FIELD_t] = (res->fields[FIELD_Rt]); + res->fields_mask[FIELD_t >> 6] |= 1LL << (FIELD_t & 63); + /* pcode: n = UInt(Rn) */ + res->fields[FIELD_n] = (res->fields[FIELD_Rn]); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: imm32 = ZeroExtend(imm5:'00', 32) */ + res->fields[FIELD_imm32] = (res->fields[FIELD_imm5]<<2)|(0x0); + res->fields_mask[FIELD_imm32 >> 6] |= 1LL << (FIELD_imm32 & 63); + /* pcode: index = TRUE */ + res->fields[FIELD_index] = 1; + res->fields_mask[FIELD_index >> 6] |= 1LL << (FIELD_index & 63); + /* pcode: add = TRUE */ + res->fields[FIELD_add] = 1; + res->fields_mask[FIELD_add >> 6] |= 1LL << (FIELD_add & 63); + /* pcode: wback = FALSE */ + res->fields[FIELD_wback] = 0; + res->fields_mask[FIELD_wback >> 6] |= 1LL << (FIELD_wback & 63); + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* Encoding T2 */ + /* pattern="1001,0,Rt.3,imm8.8" width=16 stringency=5 */ + { + uint16_t instr = req->instr_word16; + if(((instr & 0xF800)==0x9000)) { + res->instrSize = 16; + if(!(req->arch & ARCH_ARMv4T) && !(req->arch & ARCH_ARMv5T) && !(req->arch & ARCH_ARMv6) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_Rt] = (instr & 0x700)>>8; + res->fields_mask[FIELD_Rt >> 6] |= 1LL << (FIELD_Rt & 63); + char Rt_width = 3; + res->fields[FIELD_imm8] = instr & 0xFF; + res->fields_mask[FIELD_imm8 >> 6] |= 1LL << (FIELD_imm8 & 63); + char imm8_width = 8; + + static const instruction_format instr_formats[] = + { + { /* STR<c> <Rt>,[SP,#<imm32>] */ + "str", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rt,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_MEMORY_SP_IMM,FIELD_imm32,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_STR; + + /* pcode: t = UInt(Rt) */ + res->fields[FIELD_t] = (res->fields[FIELD_Rt]); + res->fields_mask[FIELD_t >> 6] |= 1LL << (FIELD_t & 63); + /* pcode: n = 13 */ + res->fields[FIELD_n] = 13; + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: imm32 = ZeroExtend(imm8:'00', 32) */ + res->fields[FIELD_imm32] = (res->fields[FIELD_imm8]<<2)|(0x0); + res->fields_mask[FIELD_imm32 >> 6] |= 1LL << (FIELD_imm32 & 63); + /* pcode: index = TRUE */ + res->fields[FIELD_index] = 1; + res->fields_mask[FIELD_index >> 6] |= 1LL << (FIELD_index & 63); + /* pcode: add = TRUE */ + res->fields[FIELD_add] = 1; + res->fields_mask[FIELD_add >> 6] |= 1LL << (FIELD_add & 63); + /* pcode: wback = FALSE */ + res->fields[FIELD_wback] = 0; + res->fields_mask[FIELD_wback >> 6] |= 1LL << (FIELD_wback & 63); + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* Encoding T3 */ + /* pattern="11111,00,0,1,10,0,Rn.4,Rt.4,imm12.12" width=32 stringency=14 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFFF00000)==0xF8C00000)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ARMv6T2) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_Rn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Rn >> 6] |= 1LL << (FIELD_Rn & 63); + char Rn_width = 4; + res->fields[FIELD_Rt] = (instr & 0xF000)>>12; + res->fields_mask[FIELD_Rt >> 6] |= 1LL << (FIELD_Rt & 63); + char Rt_width = 4; + res->fields[FIELD_imm12] = instr & 0xFFF; + res->fields_mask[FIELD_imm12 >> 6] |= 1LL << (FIELD_imm12 & 63); + char imm12_width = 12; + + static const instruction_format instr_formats[] = + { + { /* STR<c> <Rt>,[<Rn>,#<imm32>] */ + "str", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rt,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_MEMORY_ONE_REG_IMM,FIELD_Rn,FIELD_imm32,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_STR; + + /* pcode: if Rn == '1111' then UNDEFINED */ + if((res->fields[FIELD_Rn]) == (0xF)) { + res->status |= STATUS_UNDEFINED; + } + /* pcode: t = UInt(Rt) */ + res->fields[FIELD_t] = (res->fields[FIELD_Rt]); + res->fields_mask[FIELD_t >> 6] |= 1LL << (FIELD_t & 63); + /* pcode: n = UInt(Rn) */ + res->fields[FIELD_n] = (res->fields[FIELD_Rn]); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: imm32 = ZeroExtend(imm12, 32) */ + res->fields[FIELD_imm32] = res->fields[FIELD_imm12]; + res->fields_mask[FIELD_imm32 >> 6] |= 1LL << (FIELD_imm32 & 63); + /* pcode: index = TRUE */ + res->fields[FIELD_index] = 1; + res->fields_mask[FIELD_index >> 6] |= 1LL << (FIELD_index & 63); + /* pcode: add = TRUE */ + res->fields[FIELD_add] = 1; + res->fields_mask[FIELD_add >> 6] |= 1LL << (FIELD_add & 63); + /* pcode: wback = FALSE */ + res->fields[FIELD_wback] = 0; + res->fields_mask[FIELD_wback >> 6] |= 1LL << (FIELD_wback & 63); + /* pcode: if t == 15 then UNPREDICTABLE */ + if((res->fields[FIELD_t]) == (15)) { + res->flags |= FLAG_UNPREDICTABLE; + } + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* Encoding T4 */ + /* pattern="11111,00,0,0,10,0,Rn.4,Rt.4,1,P.1,U.1,W.1,imm8.8" width=32 stringency=16 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFFF00800)==0xF8400800)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ARMv6T2) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_Rn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Rn >> 6] |= 1LL << (FIELD_Rn & 63); + char Rn_width = 4; + res->fields[FIELD_Rt] = (instr & 0xF000)>>12; + res->fields_mask[FIELD_Rt >> 6] |= 1LL << (FIELD_Rt & 63); + char Rt_width = 4; + res->fields[FIELD_P] = (instr & 0x400)>>10; + res->fields_mask[FIELD_P >> 6] |= 1LL << (FIELD_P & 63); + char P_width = 1; + res->fields[FIELD_U] = (instr & 0x200)>>9; + res->fields_mask[FIELD_U >> 6] |= 1LL << (FIELD_U & 63); + char U_width = 1; + res->fields[FIELD_W] = (instr & 0x100)>>8; + res->fields_mask[FIELD_W >> 6] |= 1LL << (FIELD_W & 63); + char W_width = 1; + res->fields[FIELD_imm8] = instr & 0xFF; + res->fields_mask[FIELD_imm8 >> 6] |= 1LL << (FIELD_imm8 & 63); + char imm8_width = 8; + + static const instruction_format instr_formats[] = + { + { /* STR<c> <Rt>,[<Rn>,#-<imm8>] */ + "str", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rt,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_MEMORY_ONE_REG_NEG_IMM,FIELD_Rn,FIELD_imm8,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + { /* STR<c> <Rt>,[<Rn>,#<+/-><imm32>]! */ + "str", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rt,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_MEMORY_ONE_REG_ADD_IMM,FIELD_Rn,FIELD_imm32,"","",WRITEBACK_YES}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + { /* STR<c> <Rt>,[<Rn>],#<+/-><imm32> */ + "str", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rt,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_MEMORY_ONE_REG,FIELD_Rn,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_ADD_IMM,FIELD_imm32,FIELD_UNINIT,"#","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 3; + res->mnem = armv7::ARMV7_STR; + + /* pcode: if P == '1' && U == '1' && W == '0' then SEE STRT */ + if((((res->fields[FIELD_P]) == (0x1)) && ((res->fields[FIELD_U]) == (0x1))) && ((res->fields[FIELD_W]) == (0x0))) { + + return strt(req, res); + } + /* pcode: if Rn == '1101' && P == '1' && U == '0' && W == '1' && imm8 == '00000100' then SEE PUSH */ + if((((((res->fields[FIELD_Rn]) == (0xD)) && ((res->fields[FIELD_P]) == (0x1))) && ((res->fields[FIELD_U]) == (0x0))) && ((res->fields[FIELD_W]) == (0x1))) && ((res->fields[FIELD_imm8]) == (0x4))) { + + return push(req, res); + } + /* pcode: if Rn == '1111' || (P == '0' && W == '0') then UNDEFINED */ + if(((res->fields[FIELD_Rn]) == (0xF)) || ((((res->fields[FIELD_P]) == (0x0)) && ((res->fields[FIELD_W]) == (0x0))))) { + res->status |= STATUS_UNDEFINED; + } + /* pcode: t = UInt(Rt) */ + res->fields[FIELD_t] = (res->fields[FIELD_Rt]); + res->fields_mask[FIELD_t >> 6] |= 1LL << (FIELD_t & 63); + /* pcode: n = UInt(Rn) */ + res->fields[FIELD_n] = (res->fields[FIELD_Rn]); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: imm32 = ZeroExtend(imm8, 32) */ + res->fields[FIELD_imm32] = res->fields[FIELD_imm8]; + res->fields_mask[FIELD_imm32 >> 6] |= 1LL << (FIELD_imm32 & 63); + /* pcode: index = (P == '1') */ + res->fields[FIELD_index] = ((res->fields[FIELD_P]) == (0x1)); + res->fields_mask[FIELD_index >> 6] |= 1LL << (FIELD_index & 63); + /* pcode: add = (U == '1') */ + res->fields[FIELD_add] = ((res->fields[FIELD_U]) == (0x1)); + res->fields_mask[FIELD_add >> 6] |= 1LL << (FIELD_add & 63); + /* pcode: wback = (W == '1') */ + res->fields[FIELD_wback] = ((res->fields[FIELD_W]) == (0x1)); + res->fields_mask[FIELD_wback >> 6] |= 1LL << (FIELD_wback & 63); + /* pcode: if t == 15 || (wback && n == t) then UNPREDICTABLE */ + if(((res->fields[FIELD_t]) == (15)) || (((res->fields[FIELD_wback]) && ((res->fields[FIELD_n]) == (res->fields[FIELD_t]))))) { + res->flags |= FLAG_UNPREDICTABLE; + } + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: 1253D8EB +int str_register(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + /* Encoding T1 */ + /* pattern="0101,000,Rm.3,Rn.3,Rt.3" width=16 stringency=7 */ + { + uint16_t instr = req->instr_word16; + if(((instr & 0xFE00)==0x5000)) { + res->instrSize = 16; + if(!(req->arch & ARCH_ARMv4T) && !(req->arch & ARCH_ARMv5T) && !(req->arch & ARCH_ARMv6) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_Rm] = (instr & 0x1C0)>>6; + res->fields_mask[FIELD_Rm >> 6] |= 1LL << (FIELD_Rm & 63); + char Rm_width = 3; + res->fields[FIELD_Rn] = (instr & 0x38)>>3; + res->fields_mask[FIELD_Rn >> 6] |= 1LL << (FIELD_Rn & 63); + char Rn_width = 3; + res->fields[FIELD_Rt] = instr & 0x7; + res->fields_mask[FIELD_Rt >> 6] |= 1LL << (FIELD_Rt & 63); + char Rt_width = 3; + + static const instruction_format instr_formats[] = + { + { /* STR<c> <Rt>,[<Rn>,<Rm>] */ + "str", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rt,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_MEMORY_TWO_REG,FIELD_Rn,FIELD_Rm,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_STR; + + /* pcode: t = UInt(Rt) */ + res->fields[FIELD_t] = (res->fields[FIELD_Rt]); + res->fields_mask[FIELD_t >> 6] |= 1LL << (FIELD_t & 63); + /* pcode: n = UInt(Rn) */ + res->fields[FIELD_n] = (res->fields[FIELD_Rn]); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: m = UInt(Rm) */ + res->fields[FIELD_m] = (res->fields[FIELD_Rm]); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + /* pcode: index = TRUE */ + res->fields[FIELD_index] = 1; + res->fields_mask[FIELD_index >> 6] |= 1LL << (FIELD_index & 63); + /* pcode: add = TRUE */ + res->fields[FIELD_add] = 1; + res->fields_mask[FIELD_add >> 6] |= 1LL << (FIELD_add & 63); + /* pcode: wback = FALSE */ + res->fields[FIELD_wback] = 0; + res->fields_mask[FIELD_wback >> 6] |= 1LL << (FIELD_wback & 63); + /* pcode: (shift_t, shift_n) = (SRType_LSL, 0) */ + res->fields[FIELD_shift_t] = 0; + res->fields_mask[FIELD_shift_t >> 6] |= 1LL << (FIELD_shift_t & 63); + res->fields[FIELD_shift_n] = 0; + res->fields_mask[FIELD_shift_n >> 6] |= 1LL << (FIELD_shift_n & 63); + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* Encoding T2 */ + /* pattern="11111,00,0,0,10,0,Rn.4,Rt.4,0,00000,imm2.2,Rm.4" width=32 stringency=18 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFFF00FC0)==0xF8400000)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ARMv6T2) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_Rn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Rn >> 6] |= 1LL << (FIELD_Rn & 63); + char Rn_width = 4; + res->fields[FIELD_Rt] = (instr & 0xF000)>>12; + res->fields_mask[FIELD_Rt >> 6] |= 1LL << (FIELD_Rt & 63); + char Rt_width = 4; + res->fields[FIELD_imm2] = (instr & 0x30)>>4; + res->fields_mask[FIELD_imm2 >> 6] |= 1LL << (FIELD_imm2 & 63); + char imm2_width = 2; + res->fields[FIELD_Rm] = instr & 0xF; + res->fields_mask[FIELD_Rm >> 6] |= 1LL << (FIELD_Rm & 63); + char Rm_width = 4; + + static const instruction_format instr_formats[] = + { + { /* STR<c> <Rt>,[<Rn>,<Rm>{,<shift>}] */ + "str", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rt,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_MEMORY_TWO_REG_SHIFT,FIELD_Rn,FIELD_Rm,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_STR; + + /* pcode: if Rn == '1111' then UNDEFINED */ + if((res->fields[FIELD_Rn]) == (0xF)) { + res->status |= STATUS_UNDEFINED; + } + /* pcode: t = UInt(Rt) */ + res->fields[FIELD_t] = (res->fields[FIELD_Rt]); + res->fields_mask[FIELD_t >> 6] |= 1LL << (FIELD_t & 63); + /* pcode: n = UInt(Rn) */ + res->fields[FIELD_n] = (res->fields[FIELD_Rn]); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: m = UInt(Rm) */ + res->fields[FIELD_m] = (res->fields[FIELD_Rm]); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + /* pcode: index = TRUE */ + res->fields[FIELD_index] = 1; + res->fields_mask[FIELD_index >> 6] |= 1LL << (FIELD_index & 63); + /* pcode: add = TRUE */ + res->fields[FIELD_add] = 1; + res->fields_mask[FIELD_add >> 6] |= 1LL << (FIELD_add & 63); + /* pcode: wback = FALSE */ + res->fields[FIELD_wback] = 0; + res->fields_mask[FIELD_wback >> 6] |= 1LL << (FIELD_wback & 63); + /* pcode: (shift_t, shift_n) = (SRType_LSL, UInt(imm2)) */ + res->fields[FIELD_shift_t] = 0; + res->fields_mask[FIELD_shift_t >> 6] |= 1LL << (FIELD_shift_t & 63); + res->fields[FIELD_shift_n] = (res->fields[FIELD_imm2]); + res->fields_mask[FIELD_shift_n >> 6] |= 1LL << (FIELD_shift_n & 63); + /* pcode: if t == 15 || BadReg(m) then UNPREDICTABLE */ + if(((res->fields[FIELD_t]) == (15)) || (BadReg(res->fields[FIELD_m]))) { + res->flags |= FLAG_UNPREDICTABLE; + } + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: EC0C0EE9 +int strb_immediate(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + /* Encoding T1 */ + /* pattern="011,1,0,imm5.5,Rn.3,Rt.3" width=16 stringency=5 */ + { + uint16_t instr = req->instr_word16; + if(((instr & 0xF800)==0x7000)) { + res->instrSize = 16; + if(!(req->arch & ARCH_ARMv4T) && !(req->arch & ARCH_ARMv5T) && !(req->arch & ARCH_ARMv6) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_imm5] = (instr & 0x7C0)>>6; + res->fields_mask[FIELD_imm5 >> 6] |= 1LL << (FIELD_imm5 & 63); + char imm5_width = 5; + res->fields[FIELD_Rn] = (instr & 0x38)>>3; + res->fields_mask[FIELD_Rn >> 6] |= 1LL << (FIELD_Rn & 63); + char Rn_width = 3; + res->fields[FIELD_Rt] = instr & 0x7; + res->fields_mask[FIELD_Rt >> 6] |= 1LL << (FIELD_Rt & 63); + char Rt_width = 3; + + static const instruction_format instr_formats[] = + { + { /* STRB<c> <Rt>,[<Rn>,#<imm5>] */ + "strb", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rt,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_MEMORY_ONE_REG_IMM,FIELD_Rn,FIELD_imm5,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_STRB; + + /* pcode: t = UInt(Rt) */ + res->fields[FIELD_t] = (res->fields[FIELD_Rt]); + res->fields_mask[FIELD_t >> 6] |= 1LL << (FIELD_t & 63); + /* pcode: n = UInt(Rn) */ + res->fields[FIELD_n] = (res->fields[FIELD_Rn]); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: imm32 = ZeroExtend(imm5, 32) */ + res->fields[FIELD_imm32] = res->fields[FIELD_imm5]; + res->fields_mask[FIELD_imm32 >> 6] |= 1LL << (FIELD_imm32 & 63); + /* pcode: index = TRUE */ + res->fields[FIELD_index] = 1; + res->fields_mask[FIELD_index >> 6] |= 1LL << (FIELD_index & 63); + /* pcode: add = TRUE */ + res->fields[FIELD_add] = 1; + res->fields_mask[FIELD_add >> 6] |= 1LL << (FIELD_add & 63); + /* pcode: wback = FALSE */ + res->fields[FIELD_wback] = 0; + res->fields_mask[FIELD_wback >> 6] |= 1LL << (FIELD_wback & 63); + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* Encoding T2 */ + /* pattern="11111,00,0,1,00,0,Rn.4,Rt.4,imm12.12" width=32 stringency=14 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFFF00000)==0xF8800000)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ARMv6T2) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_Rn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Rn >> 6] |= 1LL << (FIELD_Rn & 63); + char Rn_width = 4; + res->fields[FIELD_Rt] = (instr & 0xF000)>>12; + res->fields_mask[FIELD_Rt >> 6] |= 1LL << (FIELD_Rt & 63); + char Rt_width = 4; + res->fields[FIELD_imm12] = instr & 0xFFF; + res->fields_mask[FIELD_imm12 >> 6] |= 1LL << (FIELD_imm12 & 63); + char imm12_width = 12; + + static const instruction_format instr_formats[] = + { + { /* STRB<c> <Rt>,[<Rn>,#<imm12>] */ + "strb", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rt,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_MEMORY_ONE_REG_IMM,FIELD_Rn,FIELD_imm12,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_STRB; + + /* pcode: if Rn == '1111' then UNDEFINED */ + if((res->fields[FIELD_Rn]) == (0xF)) { + res->status |= STATUS_UNDEFINED; + } + /* pcode: t = UInt(Rt) */ + res->fields[FIELD_t] = (res->fields[FIELD_Rt]); + res->fields_mask[FIELD_t >> 6] |= 1LL << (FIELD_t & 63); + /* pcode: n = UInt(Rn) */ + res->fields[FIELD_n] = (res->fields[FIELD_Rn]); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: imm32 = ZeroExtend(imm12, 32) */ + res->fields[FIELD_imm32] = res->fields[FIELD_imm12]; + res->fields_mask[FIELD_imm32 >> 6] |= 1LL << (FIELD_imm32 & 63); + /* pcode: index = TRUE */ + res->fields[FIELD_index] = 1; + res->fields_mask[FIELD_index >> 6] |= 1LL << (FIELD_index & 63); + /* pcode: add = TRUE */ + res->fields[FIELD_add] = 1; + res->fields_mask[FIELD_add >> 6] |= 1LL << (FIELD_add & 63); + /* pcode: wback = FALSE */ + res->fields[FIELD_wback] = 0; + res->fields_mask[FIELD_wback >> 6] |= 1LL << (FIELD_wback & 63); + /* pcode: if BadReg(t) then UNPREDICTABLE */ + if(BadReg(res->fields[FIELD_t])) { + res->flags |= FLAG_UNPREDICTABLE; + } + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* Encoding T3 */ + /* pattern="11111,00,0,0,00,0,Rn.4,Rt.4,1,P.1,U.1,W.1,imm8.8" width=32 stringency=16 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFFF00800)==0xF8000800)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ARMv6T2) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_Rn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Rn >> 6] |= 1LL << (FIELD_Rn & 63); + char Rn_width = 4; + res->fields[FIELD_Rt] = (instr & 0xF000)>>12; + res->fields_mask[FIELD_Rt >> 6] |= 1LL << (FIELD_Rt & 63); + char Rt_width = 4; + res->fields[FIELD_P] = (instr & 0x400)>>10; + res->fields_mask[FIELD_P >> 6] |= 1LL << (FIELD_P & 63); + char P_width = 1; + res->fields[FIELD_U] = (instr & 0x200)>>9; + res->fields_mask[FIELD_U >> 6] |= 1LL << (FIELD_U & 63); + char U_width = 1; + res->fields[FIELD_W] = (instr & 0x100)>>8; + res->fields_mask[FIELD_W >> 6] |= 1LL << (FIELD_W & 63); + char W_width = 1; + res->fields[FIELD_imm8] = instr & 0xFF; + res->fields_mask[FIELD_imm8 >> 6] |= 1LL << (FIELD_imm8 & 63); + char imm8_width = 8; + + static const instruction_format instr_formats[] = + { + { /* STRB<c> <Rt>,[<Rn>,#-<imm8>] */ + "strb", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rt,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_MEMORY_ONE_REG_NEG_IMM,FIELD_Rn,FIELD_imm8,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + { /* STRB<c> <Rt>,[<Rn>,#<+/-><imm32>]! */ + "strb", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rt,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_MEMORY_ONE_REG_ADD_IMM,FIELD_Rn,FIELD_imm32,"","",WRITEBACK_YES}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + { /* STRB<c> <Rt>,[<Rn>],#<+/-><imm32> */ + "strb", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rt,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_MEMORY_ONE_REG,FIELD_Rn,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_ADD_IMM,FIELD_imm32,FIELD_UNINIT,"#","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 3; + res->mnem = armv7::ARMV7_STRB; + + /* pcode: if P == '1' && U == '1' && W == '0' then SEE STRBT */ + if((((res->fields[FIELD_P]) == (0x1)) && ((res->fields[FIELD_U]) == (0x1))) && ((res->fields[FIELD_W]) == (0x0))) { + + return strbt(req, res); + } + /* pcode: if Rn == '1111' || (P == '0' && W == '0') then UNDEFINED */ + if(((res->fields[FIELD_Rn]) == (0xF)) || ((((res->fields[FIELD_P]) == (0x0)) && ((res->fields[FIELD_W]) == (0x0))))) { + res->status |= STATUS_UNDEFINED; + } + /* pcode: t = UInt(Rt) */ + res->fields[FIELD_t] = (res->fields[FIELD_Rt]); + res->fields_mask[FIELD_t >> 6] |= 1LL << (FIELD_t & 63); + /* pcode: n = UInt(Rn) */ + res->fields[FIELD_n] = (res->fields[FIELD_Rn]); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: imm32 = ZeroExtend(imm8, 32) */ + res->fields[FIELD_imm32] = res->fields[FIELD_imm8]; + res->fields_mask[FIELD_imm32 >> 6] |= 1LL << (FIELD_imm32 & 63); + /* pcode: index = (P == '1') */ + res->fields[FIELD_index] = ((res->fields[FIELD_P]) == (0x1)); + res->fields_mask[FIELD_index >> 6] |= 1LL << (FIELD_index & 63); + /* pcode: add = (U == '1') */ + res->fields[FIELD_add] = ((res->fields[FIELD_U]) == (0x1)); + res->fields_mask[FIELD_add >> 6] |= 1LL << (FIELD_add & 63); + /* pcode: wback = (W == '1') */ + res->fields[FIELD_wback] = ((res->fields[FIELD_W]) == (0x1)); + res->fields_mask[FIELD_wback >> 6] |= 1LL << (FIELD_wback & 63); + /* pcode: if BadReg(t) || (wback && n == t) then UNPREDICTABLE */ + if((BadReg(res->fields[FIELD_t])) || (((res->fields[FIELD_wback]) && ((res->fields[FIELD_n]) == (res->fields[FIELD_t]))))) { + res->flags |= FLAG_UNPREDICTABLE; + } + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: FCC2E8EE +int strb_register(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + /* Encoding T1 */ + /* pattern="0101,010,Rm.3,Rn.3,Rt.3" width=16 stringency=7 */ + { + uint16_t instr = req->instr_word16; + if(((instr & 0xFE00)==0x5400)) { + res->instrSize = 16; + if(!(req->arch & ARCH_ARMv4T) && !(req->arch & ARCH_ARMv5T) && !(req->arch & ARCH_ARMv6) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_Rm] = (instr & 0x1C0)>>6; + res->fields_mask[FIELD_Rm >> 6] |= 1LL << (FIELD_Rm & 63); + char Rm_width = 3; + res->fields[FIELD_Rn] = (instr & 0x38)>>3; + res->fields_mask[FIELD_Rn >> 6] |= 1LL << (FIELD_Rn & 63); + char Rn_width = 3; + res->fields[FIELD_Rt] = instr & 0x7; + res->fields_mask[FIELD_Rt >> 6] |= 1LL << (FIELD_Rt & 63); + char Rt_width = 3; + + static const instruction_format instr_formats[] = + { + { /* STRB<c> <Rt>,[<Rn>,<Rm>] */ + "strb", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rt,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_MEMORY_TWO_REG,FIELD_Rn,FIELD_Rm,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_STRB; + + /* pcode: t = UInt(Rt) */ + res->fields[FIELD_t] = (res->fields[FIELD_Rt]); + res->fields_mask[FIELD_t >> 6] |= 1LL << (FIELD_t & 63); + /* pcode: n = UInt(Rn) */ + res->fields[FIELD_n] = (res->fields[FIELD_Rn]); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: m = UInt(Rm) */ + res->fields[FIELD_m] = (res->fields[FIELD_Rm]); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + /* pcode: index = TRUE */ + res->fields[FIELD_index] = 1; + res->fields_mask[FIELD_index >> 6] |= 1LL << (FIELD_index & 63); + /* pcode: add = TRUE */ + res->fields[FIELD_add] = 1; + res->fields_mask[FIELD_add >> 6] |= 1LL << (FIELD_add & 63); + /* pcode: wback = FALSE */ + res->fields[FIELD_wback] = 0; + res->fields_mask[FIELD_wback >> 6] |= 1LL << (FIELD_wback & 63); + /* pcode: (shift_t, shift_n) = (SRType_LSL, 0) */ + res->fields[FIELD_shift_t] = 0; + res->fields_mask[FIELD_shift_t >> 6] |= 1LL << (FIELD_shift_t & 63); + res->fields[FIELD_shift_n] = 0; + res->fields_mask[FIELD_shift_n >> 6] |= 1LL << (FIELD_shift_n & 63); + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* Encoding T2 */ + /* pattern="11111,00,0,0,00,0,Rn.4,Rt.4,0,00000,imm2.2,Rm.4" width=32 stringency=18 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFFF00FC0)==0xF8000000)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ARMv6T2) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_Rn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Rn >> 6] |= 1LL << (FIELD_Rn & 63); + char Rn_width = 4; + res->fields[FIELD_Rt] = (instr & 0xF000)>>12; + res->fields_mask[FIELD_Rt >> 6] |= 1LL << (FIELD_Rt & 63); + char Rt_width = 4; + res->fields[FIELD_imm2] = (instr & 0x30)>>4; + res->fields_mask[FIELD_imm2 >> 6] |= 1LL << (FIELD_imm2 & 63); + char imm2_width = 2; + res->fields[FIELD_Rm] = instr & 0xF; + res->fields_mask[FIELD_Rm >> 6] |= 1LL << (FIELD_Rm & 63); + char Rm_width = 4; + + static const instruction_format instr_formats[] = + { + { /* STRB<c> <Rt>,[<Rn>,<Rm>{,<shift>}] */ + "strb", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rt,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_MEMORY_TWO_REG_SHIFT,FIELD_Rn,FIELD_Rm,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_STRB; + + /* pcode: if Rn == '1111' then UNDEFINED */ + if((res->fields[FIELD_Rn]) == (0xF)) { + res->status |= STATUS_UNDEFINED; + } + /* pcode: t = UInt(Rt) */ + res->fields[FIELD_t] = (res->fields[FIELD_Rt]); + res->fields_mask[FIELD_t >> 6] |= 1LL << (FIELD_t & 63); + /* pcode: n = UInt(Rn) */ + res->fields[FIELD_n] = (res->fields[FIELD_Rn]); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: m = UInt(Rm) */ + res->fields[FIELD_m] = (res->fields[FIELD_Rm]); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + /* pcode: index = TRUE */ + res->fields[FIELD_index] = 1; + res->fields_mask[FIELD_index >> 6] |= 1LL << (FIELD_index & 63); + /* pcode: add = TRUE */ + res->fields[FIELD_add] = 1; + res->fields_mask[FIELD_add >> 6] |= 1LL << (FIELD_add & 63); + /* pcode: wback = FALSE */ + res->fields[FIELD_wback] = 0; + res->fields_mask[FIELD_wback >> 6] |= 1LL << (FIELD_wback & 63); + /* pcode: (shift_t, shift_n) = (SRType_LSL, UInt(imm2)) */ + res->fields[FIELD_shift_t] = 0; + res->fields_mask[FIELD_shift_t >> 6] |= 1LL << (FIELD_shift_t & 63); + res->fields[FIELD_shift_n] = (res->fields[FIELD_imm2]); + res->fields_mask[FIELD_shift_n >> 6] |= 1LL << (FIELD_shift_n & 63); + /* pcode: if BadReg(t) || BadReg(m) then UNPREDICTABLE */ + if((BadReg(res->fields[FIELD_t])) || (BadReg(res->fields[FIELD_m]))) { + res->flags |= FLAG_UNPREDICTABLE; + } + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: BC118CCF +int strbt(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + /* Encoding T1 */ + /* pattern="11111,00,0,0,00,0,Rn.4,Rt.4,1,110,imm8.8" width=32 stringency=16 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFFF00F00)==0xF8000E00)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ARMv6T2) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_Rn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Rn >> 6] |= 1LL << (FIELD_Rn & 63); + char Rn_width = 4; + res->fields[FIELD_Rt] = (instr & 0xF000)>>12; + res->fields_mask[FIELD_Rt >> 6] |= 1LL << (FIELD_Rt & 63); + char Rt_width = 4; + res->fields[FIELD_imm8] = instr & 0xFF; + res->fields_mask[FIELD_imm8 >> 6] |= 1LL << (FIELD_imm8 & 63); + char imm8_width = 8; + + static const instruction_format instr_formats[] = + { + { /* STRBT<c> <Rt>,[<Rn>,#<imm8>] */ + "strbt", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rt,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_MEMORY_ONE_REG_IMM,FIELD_Rn,FIELD_imm8,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_STRBT; + + /* pcode: if Rn == '1111' then UNDEFINED */ + if((res->fields[FIELD_Rn]) == (0xF)) { + res->status |= STATUS_UNDEFINED; + } + /* pcode: t = UInt(Rt) */ + res->fields[FIELD_t] = (res->fields[FIELD_Rt]); + res->fields_mask[FIELD_t >> 6] |= 1LL << (FIELD_t & 63); + /* pcode: n = UInt(Rn) */ + res->fields[FIELD_n] = (res->fields[FIELD_Rn]); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: postindex = FALSE */ + res->fields[FIELD_postindex] = 0; + res->fields_mask[FIELD_postindex >> 6] |= 1LL << (FIELD_postindex & 63); + /* pcode: add = TRUE */ + res->fields[FIELD_add] = 1; + res->fields_mask[FIELD_add >> 6] |= 1LL << (FIELD_add & 63); + /* pcode: register_form = FALSE */ + res->fields[FIELD_register_form] = 0; + res->fields_mask[FIELD_register_form >> 6] |= 1LL << (FIELD_register_form & 63); + /* pcode: imm32 = ZeroExtend(imm8, 32) */ + res->fields[FIELD_imm32] = res->fields[FIELD_imm8]; + res->fields_mask[FIELD_imm32 >> 6] |= 1LL << (FIELD_imm32 & 63); + /* pcode: if BadReg(t) then UNPREDICTABLE */ + if(BadReg(res->fields[FIELD_t])) { + res->flags |= FLAG_UNPREDICTABLE; + } + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: DD5C904B +int strd_immediate(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + /* Encoding T1 */ + /* pattern="11101,00,P.1,U.1,1,W.1,0,Rn.4,Rt.4,Rt2.4,imm8.8" width=32 stringency=12 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFE500000)==0xE8400000)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ARMv6T2) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_P] = (instr & 0x1000000)>>24; + res->fields_mask[FIELD_P >> 6] |= 1LL << (FIELD_P & 63); + char P_width = 1; + res->fields[FIELD_U] = (instr & 0x800000)>>23; + res->fields_mask[FIELD_U >> 6] |= 1LL << (FIELD_U & 63); + char U_width = 1; + res->fields[FIELD_W] = (instr & 0x200000)>>21; + res->fields_mask[FIELD_W >> 6] |= 1LL << (FIELD_W & 63); + char W_width = 1; + res->fields[FIELD_Rn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Rn >> 6] |= 1LL << (FIELD_Rn & 63); + char Rn_width = 4; + res->fields[FIELD_Rt] = (instr & 0xF000)>>12; + res->fields_mask[FIELD_Rt >> 6] |= 1LL << (FIELD_Rt & 63); + char Rt_width = 4; + res->fields[FIELD_Rt2] = (instr & 0xF00)>>8; + res->fields_mask[FIELD_Rt2 >> 6] |= 1LL << (FIELD_Rt2 & 63); + char Rt2_width = 4; + res->fields[FIELD_imm8] = instr & 0xFF; + res->fields_mask[FIELD_imm8 >> 6] |= 1LL << (FIELD_imm8 & 63); + char imm8_width = 8; + + static const instruction_format instr_formats[] = + { + { /* STRD<c> <Rt>,<Rt2>,[<Rn>{,#<+/-><imm32>}] */ + "strd", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rt,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rt2,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_MEMORY_ONE_REG_OPTIONAL_ADD_IMM,FIELD_Rn,FIELD_imm32,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + { /* STRD<c> <Rt>,<Rt2>,[<Rn>,#<+/-><imm32>]! */ + "strd", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rt,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rt2,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_MEMORY_ONE_REG_ADD_IMM,FIELD_Rn,FIELD_imm32,"","",WRITEBACK_YES}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + { /* STRD<c> <Rt>,<Rt2>,[<Rn>],#<+/-><imm32> */ + "strd", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rt,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rt2,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_MEMORY_ONE_REG,FIELD_Rn,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_ADD_IMM,FIELD_imm32,FIELD_UNINIT,"#","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 4 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 3; + res->mnem = armv7::ARMV7_STRD; + + /* pcode: t = UInt(Rt) */ + res->fields[FIELD_t] = (res->fields[FIELD_Rt]); + res->fields_mask[FIELD_t >> 6] |= 1LL << (FIELD_t & 63); + /* pcode: t2 = UInt(Rt2) */ + res->fields[FIELD_t2] = (res->fields[FIELD_Rt2]); + res->fields_mask[FIELD_t2 >> 6] |= 1LL << (FIELD_t2 & 63); + /* pcode: n = UInt(Rn) */ + res->fields[FIELD_n] = (res->fields[FIELD_Rn]); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: imm32 = ZeroExtend(imm8:'00', 32) */ + res->fields[FIELD_imm32] = (res->fields[FIELD_imm8]<<2)|(0x0); + res->fields_mask[FIELD_imm32 >> 6] |= 1LL << (FIELD_imm32 & 63); + /* pcode: index = (P == '1') */ + res->fields[FIELD_index] = ((res->fields[FIELD_P]) == (0x1)); + res->fields_mask[FIELD_index >> 6] |= 1LL << (FIELD_index & 63); + /* pcode: add = (U == '1') */ + res->fields[FIELD_add] = ((res->fields[FIELD_U]) == (0x1)); + res->fields_mask[FIELD_add >> 6] |= 1LL << (FIELD_add & 63); + /* pcode: wback = (W == '1') */ + res->fields[FIELD_wback] = ((res->fields[FIELD_W]) == (0x1)); + res->fields_mask[FIELD_wback >> 6] |= 1LL << (FIELD_wback & 63); + /* pcode: if wback && (n == t || n == t2) then UNPREDICTABLE */ + if((res->fields[FIELD_wback]) && ((((res->fields[FIELD_n]) == (res->fields[FIELD_t])) || ((res->fields[FIELD_n]) == (res->fields[FIELD_t2]))))) { + res->flags |= FLAG_UNPREDICTABLE; + } + /* pcode: if n == 15 || BadReg(t) || BadReg(t2) then UNPREDICTABLE */ + if((((res->fields[FIELD_n]) == (15)) || (BadReg(res->fields[FIELD_t]))) || (BadReg(res->fields[FIELD_t2]))) { + res->flags |= FLAG_UNPREDICTABLE; + } + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: 36D3142D +int strex(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + /* Encoding T1 */ + /* pattern="11101,00,0,0,1,0,0,Rn.4,Rt.4,Rd.4,imm8.8" width=32 stringency=12 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFFF00000)==0xE8400000)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ARMv6T2) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_Rn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Rn >> 6] |= 1LL << (FIELD_Rn & 63); + char Rn_width = 4; + res->fields[FIELD_Rt] = (instr & 0xF000)>>12; + res->fields_mask[FIELD_Rt >> 6] |= 1LL << (FIELD_Rt & 63); + char Rt_width = 4; + res->fields[FIELD_Rd] = (instr & 0xF00)>>8; + res->fields_mask[FIELD_Rd >> 6] |= 1LL << (FIELD_Rd & 63); + char Rd_width = 4; + res->fields[FIELD_imm8] = instr & 0xFF; + res->fields_mask[FIELD_imm8 >> 6] |= 1LL << (FIELD_imm8 & 63); + char imm8_width = 8; + + static const instruction_format instr_formats[] = + { + { /* STREX<c> <Rd>,<Rt>,[<Rn>{,#<imm32>}] */ + "strex", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rd,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rt,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_MEMORY_ONE_REG_OPTIONAL_IMM,FIELD_Rn,FIELD_imm32,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_STREX; + + /* pcode: d = UInt(Rd) */ + res->fields[FIELD_d] = (res->fields[FIELD_Rd]); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: t = UInt(Rt) */ + res->fields[FIELD_t] = (res->fields[FIELD_Rt]); + res->fields_mask[FIELD_t >> 6] |= 1LL << (FIELD_t & 63); + /* pcode: n = UInt(Rn) */ + res->fields[FIELD_n] = (res->fields[FIELD_Rn]); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: imm32 = ZeroExtend(imm8:'00', 32) */ + res->fields[FIELD_imm32] = (res->fields[FIELD_imm8]<<2)|(0x0); + res->fields_mask[FIELD_imm32 >> 6] |= 1LL << (FIELD_imm32 & 63); + /* pcode: if BadReg(d) || BadReg(t) || n == 15 then UNPREDICTABLE */ + if(((BadReg(res->fields[FIELD_d])) || (BadReg(res->fields[FIELD_t]))) || ((res->fields[FIELD_n]) == (15))) { + res->flags |= FLAG_UNPREDICTABLE; + } + /* pcode: if d == n || d == t then UNPREDICTABLE */ + if(((res->fields[FIELD_d]) == (res->fields[FIELD_n])) || ((res->fields[FIELD_d]) == (res->fields[FIELD_t]))) { + res->flags |= FLAG_UNPREDICTABLE; + } + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: E01F9C92 +int strexb(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + /* Encoding T1 */ + /* pattern="11101,000110,0,Rn.4,Rt.4,(1)(1)(1)(1),0100,Rd.4" width=32 stringency=20 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFFF000F0)==0xE8C00040)) { + res->instrSize = 32; + if(!((instr & 0xF00)==0xF00)) { + res->flags |= FLAG_UNPREDICTABLE; + } + if(!(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_Rn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Rn >> 6] |= 1LL << (FIELD_Rn & 63); + char Rn_width = 4; + res->fields[FIELD_Rt] = (instr & 0xF000)>>12; + res->fields_mask[FIELD_Rt >> 6] |= 1LL << (FIELD_Rt & 63); + char Rt_width = 4; + res->fields[FIELD_Rd] = instr & 0xF; + res->fields_mask[FIELD_Rd >> 6] |= 1LL << (FIELD_Rd & 63); + char Rd_width = 4; + + static const instruction_format instr_formats[] = + { + { /* STREXB<c> <Rd>,<Rt>,[<Rn>] */ + "strexb", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rd,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rt,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_MEMORY_ONE_REG,FIELD_Rn,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_STREXB; + + /* pcode: d = UInt(Rd) */ + res->fields[FIELD_d] = (res->fields[FIELD_Rd]); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: t = UInt(Rt) */ + res->fields[FIELD_t] = (res->fields[FIELD_Rt]); + res->fields_mask[FIELD_t >> 6] |= 1LL << (FIELD_t & 63); + /* pcode: n = UInt(Rn) */ + res->fields[FIELD_n] = (res->fields[FIELD_Rn]); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: if BadReg(d) || BadReg(t) || n == 15 then UNPREDICTABLE */ + if(((BadReg(res->fields[FIELD_d])) || (BadReg(res->fields[FIELD_t]))) || ((res->fields[FIELD_n]) == (15))) { + res->flags |= FLAG_UNPREDICTABLE; + } + /* pcode: if d == n || d == t then UNPREDICTABLE */ + if(((res->fields[FIELD_d]) == (res->fields[FIELD_n])) || ((res->fields[FIELD_d]) == (res->fields[FIELD_t]))) { + res->flags |= FLAG_UNPREDICTABLE; + } + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: E4DA5B0E +int strexd(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + /* Encoding T1 */ + /* pattern="11101,000110,0,Rn.4,Rt.4,Rt2.4,0111,Rd.4" width=32 stringency=16 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFFF000F0)==0xE8C00070)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_Rn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Rn >> 6] |= 1LL << (FIELD_Rn & 63); + char Rn_width = 4; + res->fields[FIELD_Rt] = (instr & 0xF000)>>12; + res->fields_mask[FIELD_Rt >> 6] |= 1LL << (FIELD_Rt & 63); + char Rt_width = 4; + res->fields[FIELD_Rt2] = (instr & 0xF00)>>8; + res->fields_mask[FIELD_Rt2 >> 6] |= 1LL << (FIELD_Rt2 & 63); + char Rt2_width = 4; + res->fields[FIELD_Rd] = instr & 0xF; + res->fields_mask[FIELD_Rd >> 6] |= 1LL << (FIELD_Rd & 63); + char Rd_width = 4; + + static const instruction_format instr_formats[] = + { + { /* STREXD<c> <Rd>,<Rt>,<Rt2>,[<Rn>] */ + "strexd", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rd,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rt,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rt2,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_MEMORY_ONE_REG,FIELD_Rn,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 4 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_STREXD; + + /* pcode: d = UInt(Rd) */ + res->fields[FIELD_d] = (res->fields[FIELD_Rd]); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: t = UInt(Rt) */ + res->fields[FIELD_t] = (res->fields[FIELD_Rt]); + res->fields_mask[FIELD_t >> 6] |= 1LL << (FIELD_t & 63); + /* pcode: t2 = UInt(Rt2) */ + res->fields[FIELD_t2] = (res->fields[FIELD_Rt2]); + res->fields_mask[FIELD_t2 >> 6] |= 1LL << (FIELD_t2 & 63); + /* pcode: n = UInt(Rn) */ + res->fields[FIELD_n] = (res->fields[FIELD_Rn]); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: if BadReg(d) || BadReg(t) || BadReg(t2) || n == 15 then UNPREDICTABLE */ + if((((BadReg(res->fields[FIELD_d])) || (BadReg(res->fields[FIELD_t]))) || (BadReg(res->fields[FIELD_t2]))) || ((res->fields[FIELD_n]) == (15))) { + res->flags |= FLAG_UNPREDICTABLE; + } + /* pcode: if d == n || d == t || d == t2 then UNPREDICTABLE */ + if((((res->fields[FIELD_d]) == (res->fields[FIELD_n])) || ((res->fields[FIELD_d]) == (res->fields[FIELD_t]))) || ((res->fields[FIELD_d]) == (res->fields[FIELD_t2]))) { + res->flags |= FLAG_UNPREDICTABLE; + } + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: B18F9A9B +int strexh(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + /* Encoding T1 */ + /* pattern="11101,000110,0,Rn.4,Rt.4,(1)(1)(1)(1),0101,Rd.4" width=32 stringency=20 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFFF000F0)==0xE8C00050)) { + res->instrSize = 32; + if(!((instr & 0xF00)==0xF00)) { + res->flags |= FLAG_UNPREDICTABLE; + } + if(!(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_Rn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Rn >> 6] |= 1LL << (FIELD_Rn & 63); + char Rn_width = 4; + res->fields[FIELD_Rt] = (instr & 0xF000)>>12; + res->fields_mask[FIELD_Rt >> 6] |= 1LL << (FIELD_Rt & 63); + char Rt_width = 4; + res->fields[FIELD_Rd] = instr & 0xF; + res->fields_mask[FIELD_Rd >> 6] |= 1LL << (FIELD_Rd & 63); + char Rd_width = 4; + + static const instruction_format instr_formats[] = + { + { /* STREXH<c> <Rd>,<Rt>,[<Rn>] */ + "strexh", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rd,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rt,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_MEMORY_ONE_REG,FIELD_Rn,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_STREXH; + + /* pcode: d = UInt(Rd) */ + res->fields[FIELD_d] = (res->fields[FIELD_Rd]); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: t = UInt(Rt) */ + res->fields[FIELD_t] = (res->fields[FIELD_Rt]); + res->fields_mask[FIELD_t >> 6] |= 1LL << (FIELD_t & 63); + /* pcode: n = UInt(Rn) */ + res->fields[FIELD_n] = (res->fields[FIELD_Rn]); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: if BadReg(d) || BadReg(t) || n == 15 then UNPREDICTABLE */ + if(((BadReg(res->fields[FIELD_d])) || (BadReg(res->fields[FIELD_t]))) || ((res->fields[FIELD_n]) == (15))) { + res->flags |= FLAG_UNPREDICTABLE; + } + /* pcode: if d == n || d == t then UNPREDICTABLE */ + if(((res->fields[FIELD_d]) == (res->fields[FIELD_n])) || ((res->fields[FIELD_d]) == (res->fields[FIELD_t]))) { + res->flags |= FLAG_UNPREDICTABLE; + } + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: 7442EBF4 +int strh_immediate(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + /* Encoding T1 */ + /* pattern="1000,0,imm5.5,Rn.3,Rt.3" width=16 stringency=5 */ + { + uint16_t instr = req->instr_word16; + if(((instr & 0xF800)==0x8000)) { + res->instrSize = 16; + if(!(req->arch & ARCH_ARMv4T) && !(req->arch & ARCH_ARMv5T) && !(req->arch & ARCH_ARMv6) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_imm5] = (instr & 0x7C0)>>6; + res->fields_mask[FIELD_imm5 >> 6] |= 1LL << (FIELD_imm5 & 63); + char imm5_width = 5; + res->fields[FIELD_Rn] = (instr & 0x38)>>3; + res->fields_mask[FIELD_Rn >> 6] |= 1LL << (FIELD_Rn & 63); + char Rn_width = 3; + res->fields[FIELD_Rt] = instr & 0x7; + res->fields_mask[FIELD_Rt >> 6] |= 1LL << (FIELD_Rt & 63); + char Rt_width = 3; + + static const instruction_format instr_formats[] = + { + { /* STRH<c> <Rt>,[<Rn>{,#<imm32>}] */ + "strh", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rt,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_MEMORY_ONE_REG_OPTIONAL_IMM,FIELD_Rn,FIELD_imm32,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_STRH; + + /* pcode: t = UInt(Rt) */ + res->fields[FIELD_t] = (res->fields[FIELD_Rt]); + res->fields_mask[FIELD_t >> 6] |= 1LL << (FIELD_t & 63); + /* pcode: n = UInt(Rn) */ + res->fields[FIELD_n] = (res->fields[FIELD_Rn]); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: imm32 = ZeroExtend(imm5:'0', 32) */ + res->fields[FIELD_imm32] = (res->fields[FIELD_imm5]<<1)|(0x0); + res->fields_mask[FIELD_imm32 >> 6] |= 1LL << (FIELD_imm32 & 63); + /* pcode: index = TRUE */ + res->fields[FIELD_index] = 1; + res->fields_mask[FIELD_index >> 6] |= 1LL << (FIELD_index & 63); + /* pcode: add = TRUE */ + res->fields[FIELD_add] = 1; + res->fields_mask[FIELD_add >> 6] |= 1LL << (FIELD_add & 63); + /* pcode: wback = FALSE */ + res->fields[FIELD_wback] = 0; + res->fields_mask[FIELD_wback >> 6] |= 1LL << (FIELD_wback & 63); + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* Encoding T2 */ + /* pattern="11111,00,0,1,01,0,Rn.4,Rt.4,imm12.12" width=32 stringency=14 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFFF00000)==0xF8A00000)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ARMv6T2) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_Rn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Rn >> 6] |= 1LL << (FIELD_Rn & 63); + char Rn_width = 4; + res->fields[FIELD_Rt] = (instr & 0xF000)>>12; + res->fields_mask[FIELD_Rt >> 6] |= 1LL << (FIELD_Rt & 63); + char Rt_width = 4; + res->fields[FIELD_imm12] = instr & 0xFFF; + res->fields_mask[FIELD_imm12 >> 6] |= 1LL << (FIELD_imm12 & 63); + char imm12_width = 12; + + static const instruction_format instr_formats[] = + { + { /* STRH<c> <Rt>,[<Rn>{,#<imm32>}] */ + "strh", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rt,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_MEMORY_ONE_REG_OPTIONAL_IMM,FIELD_Rn,FIELD_imm32,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_STRH; + + /* pcode: if Rn == '1111' then UNDEFINED */ + if((res->fields[FIELD_Rn]) == (0xF)) { + res->status |= STATUS_UNDEFINED; + } + /* pcode: t = UInt(Rt) */ + res->fields[FIELD_t] = (res->fields[FIELD_Rt]); + res->fields_mask[FIELD_t >> 6] |= 1LL << (FIELD_t & 63); + /* pcode: n = UInt(Rn) */ + res->fields[FIELD_n] = (res->fields[FIELD_Rn]); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: imm32 = ZeroExtend(imm12, 32) */ + res->fields[FIELD_imm32] = res->fields[FIELD_imm12]; + res->fields_mask[FIELD_imm32 >> 6] |= 1LL << (FIELD_imm32 & 63); + /* pcode: index = TRUE */ + res->fields[FIELD_index] = 1; + res->fields_mask[FIELD_index >> 6] |= 1LL << (FIELD_index & 63); + /* pcode: add = TRUE */ + res->fields[FIELD_add] = 1; + res->fields_mask[FIELD_add >> 6] |= 1LL << (FIELD_add & 63); + /* pcode: wback = FALSE */ + res->fields[FIELD_wback] = 0; + res->fields_mask[FIELD_wback >> 6] |= 1LL << (FIELD_wback & 63); + /* pcode: if BadReg(t) then UNPREDICTABLE */ + if(BadReg(res->fields[FIELD_t])) { + res->flags |= FLAG_UNPREDICTABLE; + } + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* Encoding T3 */ + /* pattern="11111,00,0,0,01,0,Rn.4,Rt.4,1,P.1,U.1,W.1,imm8.8" width=32 stringency=16 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFFF00800)==0xF8200800)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ARMv6T2) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_Rn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Rn >> 6] |= 1LL << (FIELD_Rn & 63); + char Rn_width = 4; + res->fields[FIELD_Rt] = (instr & 0xF000)>>12; + res->fields_mask[FIELD_Rt >> 6] |= 1LL << (FIELD_Rt & 63); + char Rt_width = 4; + res->fields[FIELD_P] = (instr & 0x400)>>10; + res->fields_mask[FIELD_P >> 6] |= 1LL << (FIELD_P & 63); + char P_width = 1; + res->fields[FIELD_U] = (instr & 0x200)>>9; + res->fields_mask[FIELD_U >> 6] |= 1LL << (FIELD_U & 63); + char U_width = 1; + res->fields[FIELD_W] = (instr & 0x100)>>8; + res->fields_mask[FIELD_W >> 6] |= 1LL << (FIELD_W & 63); + char W_width = 1; + res->fields[FIELD_imm8] = instr & 0xFF; + res->fields_mask[FIELD_imm8 >> 6] |= 1LL << (FIELD_imm8 & 63); + char imm8_width = 8; + + static const instruction_format instr_formats[] = + { + { /* STRH<c> <Rt>,[<Rn>,#-<imm32>] */ + "strh", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rt,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_MEMORY_ONE_REG_NEG_IMM,FIELD_Rn,FIELD_imm32,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + { /* STRH<c> <Rt>,[<Rn>,#<+/-><imm32>]! */ + "strh", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rt,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_MEMORY_ONE_REG_ADD_IMM,FIELD_Rn,FIELD_imm32,"","",WRITEBACK_YES}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + { /* STRH<c> <Rt>,[<Rn>],#<+/-><imm32> */ + "strh", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rt,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_MEMORY_ONE_REG,FIELD_Rn,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_ADD_IMM,FIELD_imm32,FIELD_UNINIT,"#","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 3; + res->mnem = armv7::ARMV7_STRH; + + /* pcode: if P == '1' && U == '1' && W == '0' then SEE STRHT */ + if((((res->fields[FIELD_P]) == (0x1)) && ((res->fields[FIELD_U]) == (0x1))) && ((res->fields[FIELD_W]) == (0x0))) { + + return strht(req, res); + } + /* pcode: if Rn == '1111' || (P == '0' && W == '0') then UNDEFINED */ + if(((res->fields[FIELD_Rn]) == (0xF)) || ((((res->fields[FIELD_P]) == (0x0)) && ((res->fields[FIELD_W]) == (0x0))))) { + res->status |= STATUS_UNDEFINED; + } + /* pcode: t = UInt(Rt) */ + res->fields[FIELD_t] = (res->fields[FIELD_Rt]); + res->fields_mask[FIELD_t >> 6] |= 1LL << (FIELD_t & 63); + /* pcode: n = UInt(Rn) */ + res->fields[FIELD_n] = (res->fields[FIELD_Rn]); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: imm32 = ZeroExtend(imm8, 32) */ + res->fields[FIELD_imm32] = res->fields[FIELD_imm8]; + res->fields_mask[FIELD_imm32 >> 6] |= 1LL << (FIELD_imm32 & 63); + /* pcode: index = (P == '1') */ + res->fields[FIELD_index] = ((res->fields[FIELD_P]) == (0x1)); + res->fields_mask[FIELD_index >> 6] |= 1LL << (FIELD_index & 63); + /* pcode: add = (U == '1') */ + res->fields[FIELD_add] = ((res->fields[FIELD_U]) == (0x1)); + res->fields_mask[FIELD_add >> 6] |= 1LL << (FIELD_add & 63); + /* pcode: wback = (W == '1') */ + res->fields[FIELD_wback] = ((res->fields[FIELD_W]) == (0x1)); + res->fields_mask[FIELD_wback >> 6] |= 1LL << (FIELD_wback & 63); + /* pcode: if BadReg(t) || (wback && n == t) then UNPREDICTABLE */ + if((BadReg(res->fields[FIELD_t])) || (((res->fields[FIELD_wback]) && ((res->fields[FIELD_n]) == (res->fields[FIELD_t]))))) { + res->flags |= FLAG_UNPREDICTABLE; + } + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: 1903FC46 +int strh_register(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + /* Encoding T1 */ + /* pattern="0101,001,Rm.3,Rn.3,Rt.3" width=16 stringency=7 */ + { + uint16_t instr = req->instr_word16; + if(((instr & 0xFE00)==0x5200)) { + res->instrSize = 16; + if(!(req->arch & ARCH_ARMv4T) && !(req->arch & ARCH_ARMv5T) && !(req->arch & ARCH_ARMv6) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_Rm] = (instr & 0x1C0)>>6; + res->fields_mask[FIELD_Rm >> 6] |= 1LL << (FIELD_Rm & 63); + char Rm_width = 3; + res->fields[FIELD_Rn] = (instr & 0x38)>>3; + res->fields_mask[FIELD_Rn >> 6] |= 1LL << (FIELD_Rn & 63); + char Rn_width = 3; + res->fields[FIELD_Rt] = instr & 0x7; + res->fields_mask[FIELD_Rt >> 6] |= 1LL << (FIELD_Rt & 63); + char Rt_width = 3; + + static const instruction_format instr_formats[] = + { + { /* STRH<c> <Rt>,[<Rn>,<Rm>] */ + "strh", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rt,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_MEMORY_TWO_REG,FIELD_Rn,FIELD_Rm,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_STRH; + + /* pcode: t = UInt(Rt) */ + res->fields[FIELD_t] = (res->fields[FIELD_Rt]); + res->fields_mask[FIELD_t >> 6] |= 1LL << (FIELD_t & 63); + /* pcode: n = UInt(Rn) */ + res->fields[FIELD_n] = (res->fields[FIELD_Rn]); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: m = UInt(Rm) */ + res->fields[FIELD_m] = (res->fields[FIELD_Rm]); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + /* pcode: index = TRUE */ + res->fields[FIELD_index] = 1; + res->fields_mask[FIELD_index >> 6] |= 1LL << (FIELD_index & 63); + /* pcode: add = TRUE */ + res->fields[FIELD_add] = 1; + res->fields_mask[FIELD_add >> 6] |= 1LL << (FIELD_add & 63); + /* pcode: wback = FALSE */ + res->fields[FIELD_wback] = 0; + res->fields_mask[FIELD_wback >> 6] |= 1LL << (FIELD_wback & 63); + /* pcode: (shift_t, shift_n) = (SRType_LSL, 0) */ + res->fields[FIELD_shift_t] = 0; + res->fields_mask[FIELD_shift_t >> 6] |= 1LL << (FIELD_shift_t & 63); + res->fields[FIELD_shift_n] = 0; + res->fields_mask[FIELD_shift_n >> 6] |= 1LL << (FIELD_shift_n & 63); + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* Encoding T2 */ + /* pattern="11111,00,0,0,01,0,Rn.4,Rt.4,0,00000,imm2.2,Rm.4" width=32 stringency=18 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFFF00FC0)==0xF8200000)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ARMv6T2) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_Rn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Rn >> 6] |= 1LL << (FIELD_Rn & 63); + char Rn_width = 4; + res->fields[FIELD_Rt] = (instr & 0xF000)>>12; + res->fields_mask[FIELD_Rt >> 6] |= 1LL << (FIELD_Rt & 63); + char Rt_width = 4; + res->fields[FIELD_imm2] = (instr & 0x30)>>4; + res->fields_mask[FIELD_imm2 >> 6] |= 1LL << (FIELD_imm2 & 63); + char imm2_width = 2; + res->fields[FIELD_Rm] = instr & 0xF; + res->fields_mask[FIELD_Rm >> 6] |= 1LL << (FIELD_Rm & 63); + char Rm_width = 4; + + static const instruction_format instr_formats[] = + { + { /* STRH<c> <Rt>,[<Rn>,<Rm>{,<shift>}] */ + "strh", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rt,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_MEMORY_TWO_REG_SHIFT,FIELD_Rn,FIELD_Rm,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_STRH; + + /* pcode: if Rn == '1111' then UNDEFINED */ + if((res->fields[FIELD_Rn]) == (0xF)) { + res->status |= STATUS_UNDEFINED; + } + /* pcode: t = UInt(Rt) */ + res->fields[FIELD_t] = (res->fields[FIELD_Rt]); + res->fields_mask[FIELD_t >> 6] |= 1LL << (FIELD_t & 63); + /* pcode: n = UInt(Rn) */ + res->fields[FIELD_n] = (res->fields[FIELD_Rn]); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: m = UInt(Rm) */ + res->fields[FIELD_m] = (res->fields[FIELD_Rm]); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + /* pcode: index = TRUE */ + res->fields[FIELD_index] = 1; + res->fields_mask[FIELD_index >> 6] |= 1LL << (FIELD_index & 63); + /* pcode: add = TRUE */ + res->fields[FIELD_add] = 1; + res->fields_mask[FIELD_add >> 6] |= 1LL << (FIELD_add & 63); + /* pcode: wback = FALSE */ + res->fields[FIELD_wback] = 0; + res->fields_mask[FIELD_wback >> 6] |= 1LL << (FIELD_wback & 63); + /* pcode: (shift_t, shift_n) = (SRType_LSL, UInt(imm2)) */ + res->fields[FIELD_shift_t] = 0; + res->fields_mask[FIELD_shift_t >> 6] |= 1LL << (FIELD_shift_t & 63); + res->fields[FIELD_shift_n] = (res->fields[FIELD_imm2]); + res->fields_mask[FIELD_shift_n >> 6] |= 1LL << (FIELD_shift_n & 63); + /* pcode: if BadReg(t) || BadReg(m) then UNPREDICTABLE */ + if((BadReg(res->fields[FIELD_t])) || (BadReg(res->fields[FIELD_m]))) { + res->flags |= FLAG_UNPREDICTABLE; + } + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: 55006FC0 +int strht(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + /* Encoding T1 */ + /* pattern="11111,00,0,0,01,0,Rn.4,Rt.4,1,110,imm8.8" width=32 stringency=16 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFFF00F00)==0xF8200E00)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ARMv6T2) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_Rn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Rn >> 6] |= 1LL << (FIELD_Rn & 63); + char Rn_width = 4; + res->fields[FIELD_Rt] = (instr & 0xF000)>>12; + res->fields_mask[FIELD_Rt >> 6] |= 1LL << (FIELD_Rt & 63); + char Rt_width = 4; + res->fields[FIELD_imm8] = instr & 0xFF; + res->fields_mask[FIELD_imm8 >> 6] |= 1LL << (FIELD_imm8 & 63); + char imm8_width = 8; + + static const instruction_format instr_formats[] = + { + { /* STRHT<c> <Rt>,[<Rn>,#<imm8>] */ + "strht", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rt,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_MEMORY_ONE_REG_IMM,FIELD_Rn,FIELD_imm8,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_STRHT; + + /* pcode: if Rn == '1111' then UNDEFINED */ + if((res->fields[FIELD_Rn]) == (0xF)) { + res->status |= STATUS_UNDEFINED; + } + /* pcode: t = UInt(Rt) */ + res->fields[FIELD_t] = (res->fields[FIELD_Rt]); + res->fields_mask[FIELD_t >> 6] |= 1LL << (FIELD_t & 63); + /* pcode: n = UInt(Rn) */ + res->fields[FIELD_n] = (res->fields[FIELD_Rn]); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: postindex = FALSE */ + res->fields[FIELD_postindex] = 0; + res->fields_mask[FIELD_postindex >> 6] |= 1LL << (FIELD_postindex & 63); + /* pcode: add = TRUE */ + res->fields[FIELD_add] = 1; + res->fields_mask[FIELD_add >> 6] |= 1LL << (FIELD_add & 63); + /* pcode: register_form = FALSE */ + res->fields[FIELD_register_form] = 0; + res->fields_mask[FIELD_register_form >> 6] |= 1LL << (FIELD_register_form & 63); + /* pcode: imm32 = ZeroExtend(imm8, 32) */ + res->fields[FIELD_imm32] = res->fields[FIELD_imm8]; + res->fields_mask[FIELD_imm32 >> 6] |= 1LL << (FIELD_imm32 & 63); + /* pcode: if BadReg(t) then UNPREDICTABLE */ + if(BadReg(res->fields[FIELD_t])) { + res->flags |= FLAG_UNPREDICTABLE; + } + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: 357153B0 +int strt(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + /* Encoding T1 */ + /* pattern="11111,00,0,0,10,0,Rn.4,Rt.4,1,110,imm8.8" width=32 stringency=16 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFFF00F00)==0xF8400E00)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ARMv6T2) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_Rn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Rn >> 6] |= 1LL << (FIELD_Rn & 63); + char Rn_width = 4; + res->fields[FIELD_Rt] = (instr & 0xF000)>>12; + res->fields_mask[FIELD_Rt >> 6] |= 1LL << (FIELD_Rt & 63); + char Rt_width = 4; + res->fields[FIELD_imm8] = instr & 0xFF; + res->fields_mask[FIELD_imm8 >> 6] |= 1LL << (FIELD_imm8 & 63); + char imm8_width = 8; + + static const instruction_format instr_formats[] = + { + { /* STRT<c> <Rt>,[<Rn>,#<imm8>] */ + "strt", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rt,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_MEMORY_ONE_REG_IMM,FIELD_Rn,FIELD_imm8,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_STRT; + + /* pcode: if Rn == '1111' then UNDEFINED */ + if((res->fields[FIELD_Rn]) == (0xF)) { + res->status |= STATUS_UNDEFINED; + } + /* pcode: t = UInt(Rt) */ + res->fields[FIELD_t] = (res->fields[FIELD_Rt]); + res->fields_mask[FIELD_t >> 6] |= 1LL << (FIELD_t & 63); + /* pcode: n = UInt(Rn) */ + res->fields[FIELD_n] = (res->fields[FIELD_Rn]); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: postindex = FALSE */ + res->fields[FIELD_postindex] = 0; + res->fields_mask[FIELD_postindex >> 6] |= 1LL << (FIELD_postindex & 63); + /* pcode: add = TRUE */ + res->fields[FIELD_add] = 1; + res->fields_mask[FIELD_add >> 6] |= 1LL << (FIELD_add & 63); + /* pcode: register_form = FALSE */ + res->fields[FIELD_register_form] = 0; + res->fields_mask[FIELD_register_form >> 6] |= 1LL << (FIELD_register_form & 63); + /* pcode: imm32 = ZeroExtend(imm8, 32) */ + res->fields[FIELD_imm32] = res->fields[FIELD_imm8]; + res->fields_mask[FIELD_imm32 >> 6] |= 1LL << (FIELD_imm32 & 63); + /* pcode: if BadReg(t) then UNPREDICTABLE */ + if(BadReg(res->fields[FIELD_t])) { + res->flags |= FLAG_UNPREDICTABLE; + } + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: 158FA976 +int sub_immediate(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + /* Encoding T1 */ + /* pattern="000,11,1,1,imm3.3,Rn.3,Rd.3" width=16 stringency=7 */ + { + uint16_t instr = req->instr_word16; + if(((instr & 0xFE00)==0x1E00)) { + res->instrSize = 16; + if(!(req->arch & ARCH_ARMv4T) && !(req->arch & ARCH_ARMv5T) && !(req->arch & ARCH_ARMv6) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_imm3] = (instr & 0x1C0)>>6; + res->fields_mask[FIELD_imm3 >> 6] |= 1LL << (FIELD_imm3 & 63); + char imm3_width = 3; + res->fields[FIELD_Rn] = (instr & 0x38)>>3; + res->fields_mask[FIELD_Rn >> 6] |= 1LL << (FIELD_Rn & 63); + char Rn_width = 3; + res->fields[FIELD_Rd] = instr & 0x7; + res->fields_mask[FIELD_Rd >> 6] |= 1LL << (FIELD_Rd & 63); + char Rd_width = 3; + + static const instruction_format instr_formats[] = + { + { /* SUBS <Rd>,<Rn>,#<imm3> */ + "subs", /* .operation (const char *) */ + 0, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rd,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rn,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_IMM,FIELD_imm3,FIELD_UNINIT,"#","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + { /* SUB<c> <Rd>,<Rn>,#<imm3> */ + "sub", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rd,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rn,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_IMM,FIELD_imm3,FIELD_UNINIT,"#","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 2; + res->mnem = armv7::ARMV7_SUBS; + + /* pcode: d = UInt(Rd) */ + res->fields[FIELD_d] = (res->fields[FIELD_Rd]); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: n = UInt(Rn) */ + res->fields[FIELD_n] = (res->fields[FIELD_Rn]); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: setflags = !InITBlock() */ + res->fields[FIELD_setflags] = !(req->inIfThen == IFTHEN_YES); + res->fields_mask[FIELD_setflags >> 6] |= 1LL << (FIELD_setflags & 63); + /* pcode: imm32 = ZeroExtend(imm3, 32) */ + res->fields[FIELD_imm32] = res->fields[FIELD_imm3]; + res->fields_mask[FIELD_imm32 >> 6] |= 1LL << (FIELD_imm32 & 63); + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* Encoding T2 */ + /* pattern="001,11,Rdn.3,imm8.8" width=16 stringency=5 */ + { + uint16_t instr = req->instr_word16; + if(((instr & 0xF800)==0x3800)) { + res->instrSize = 16; + if(!(req->arch & ARCH_ARMv4T) && !(req->arch & ARCH_ARMv5T) && !(req->arch & ARCH_ARMv6) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_Rdn] = (instr & 0x700)>>8; + res->fields_mask[FIELD_Rdn >> 6] |= 1LL << (FIELD_Rdn & 63); + char Rdn_width = 3; + res->fields[FIELD_imm8] = instr & 0xFF; + res->fields_mask[FIELD_imm8 >> 6] |= 1LL << (FIELD_imm8 & 63); + char imm8_width = 8; + + static const instruction_format instr_formats[] = + { + { /* SUBS <Rdn>,#<imm8> */ + "subs", /* .operation (const char *) */ + 0, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rdn,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_IMM,FIELD_imm8,FIELD_UNINIT,"#","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + { /* SUB<c> <Rdn>,#<imm8> */ + "sub", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rdn,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_IMM,FIELD_imm8,FIELD_UNINIT,"#","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 2; + res->mnem = armv7::ARMV7_SUBS; + + /* pcode: d = UInt(Rdn) */ + res->fields[FIELD_d] = (res->fields[FIELD_Rdn]); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: n = UInt(Rdn) */ + res->fields[FIELD_n] = (res->fields[FIELD_Rdn]); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: setflags = !InITBlock() */ + res->fields[FIELD_setflags] = !(req->inIfThen == IFTHEN_YES); + res->fields_mask[FIELD_setflags >> 6] |= 1LL << (FIELD_setflags & 63); + /* pcode: imm32 = ZeroExtend(imm8, 32) */ + res->fields[FIELD_imm32] = res->fields[FIELD_imm8]; + res->fields_mask[FIELD_imm32 >> 6] |= 1LL << (FIELD_imm32 & 63); + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* Encoding T3 */ + /* pattern="11110,i.1,0,1101,S.1,Rn.4,0,imm3.3,Rd.4,imm8.8" width=32 stringency=13 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFBE08000)==0xF1A00000)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ARMv6T2) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_i] = (instr & 0x4000000)>>26; + res->fields_mask[FIELD_i >> 6] |= 1LL << (FIELD_i & 63); + char i_width = 1; + res->fields[FIELD_S] = (instr & 0x100000)>>20; + res->fields_mask[FIELD_S >> 6] |= 1LL << (FIELD_S & 63); + char S_width = 1; + res->fields[FIELD_Rn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Rn >> 6] |= 1LL << (FIELD_Rn & 63); + char Rn_width = 4; + res->fields[FIELD_imm3] = (instr & 0x7000)>>12; + res->fields_mask[FIELD_imm3 >> 6] |= 1LL << (FIELD_imm3 & 63); + char imm3_width = 3; + res->fields[FIELD_Rd] = (instr & 0xF00)>>8; + res->fields_mask[FIELD_Rd >> 6] |= 1LL << (FIELD_Rd & 63); + char Rd_width = 4; + res->fields[FIELD_imm8] = instr & 0xFF; + res->fields_mask[FIELD_imm8 >> 6] |= 1LL << (FIELD_imm8 & 63); + char imm8_width = 8; + + static const instruction_format instr_formats[] = + { + { /* SUB{S}<c> <Rd>,<Rn>,#<imm32> */ + "sub", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_OPTIONAL_STATUS, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rd,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rn,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_IMM,FIELD_imm32,FIELD_UNINIT,"#","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_SUB; + + /* pcode: d = UInt(Rd) */ + res->fields[FIELD_d] = (res->fields[FIELD_Rd]); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: n = UInt(Rn) */ + res->fields[FIELD_n] = (res->fields[FIELD_Rn]); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: setflags = (S == '1') */ + res->fields[FIELD_setflags] = ((res->fields[FIELD_S]) == (0x1)); + res->fields_mask[FIELD_setflags >> 6] |= 1LL << (FIELD_setflags & 63); + /* pcode: imm32 = ThumbExpandImm(i:imm3:imm8) */ + res->fields[FIELD_imm32] = ThumbExpandImm_C_imm32((res->fields[FIELD_i]<<(8+3))|(res->fields[FIELD_imm3]<<8)|(res->fields[FIELD_imm8]), req->carry_in); + /* TODO: handle ThumbExpandImm_C's possible setting of UNPREDICTABLE */ while(0); + res->fields_mask[FIELD_imm32 >> 6] |= 1LL << (FIELD_imm32 & 63); + /* pcode: if d == 13 || (d == 15 && S == '0') || n == 15 then UNPREDICTABLE */ + if((((res->fields[FIELD_d]) == (13)) || ((((res->fields[FIELD_d]) == (15)) && ((res->fields[FIELD_S]) == (0x0))))) || ((res->fields[FIELD_n]) == (15))) { + res->flags |= FLAG_UNPREDICTABLE; + } + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* Encoding T4 */ + /* pattern="11110,i.1,1,0101,0,Rn.4,0,imm3.3,Rd.4,imm8.8" width=32 stringency=13 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFBF08000)==0xF2A00000)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ARMv6T2) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_i] = (instr & 0x4000000)>>26; + res->fields_mask[FIELD_i >> 6] |= 1LL << (FIELD_i & 63); + char i_width = 1; + res->fields[FIELD_Rn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Rn >> 6] |= 1LL << (FIELD_Rn & 63); + char Rn_width = 4; + res->fields[FIELD_imm3] = (instr & 0x7000)>>12; + res->fields_mask[FIELD_imm3 >> 6] |= 1LL << (FIELD_imm3 & 63); + char imm3_width = 3; + res->fields[FIELD_Rd] = (instr & 0xF00)>>8; + res->fields_mask[FIELD_Rd >> 6] |= 1LL << (FIELD_Rd & 63); + char Rd_width = 4; + res->fields[FIELD_imm8] = instr & 0xFF; + res->fields_mask[FIELD_imm8 >> 6] |= 1LL << (FIELD_imm8 & 63); + char imm8_width = 8; + + static const instruction_format instr_formats[] = + { + { /* SUBW<c> <Rd>,<Rn>,#<imm32> */ + "subw", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rd,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rn,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_IMM,FIELD_imm32,FIELD_UNINIT,"#","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_SUBW; + + /* pcode: d = UInt(Rd) */ + res->fields[FIELD_d] = (res->fields[FIELD_Rd]); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: n = UInt(Rn) */ + res->fields[FIELD_n] = (res->fields[FIELD_Rn]); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: setflags = FALSE */ + res->fields[FIELD_setflags] = 0; + res->fields_mask[FIELD_setflags >> 6] |= 1LL << (FIELD_setflags & 63); + /* pcode: imm32 = ZeroExtend(i:imm3:imm8, 32) */ + res->fields[FIELD_imm32] = (res->fields[FIELD_i]<<(8+3))|(res->fields[FIELD_imm3]<<8)|(res->fields[FIELD_imm8]); + res->fields_mask[FIELD_imm32 >> 6] |= 1LL << (FIELD_imm32 & 63); + /* pcode: if d == 13 || d == 15 then UNPREDICTABLE */ + if(((res->fields[FIELD_d]) == (13)) || ((res->fields[FIELD_d]) == (15))) { + res->flags |= FLAG_UNPREDICTABLE; + } + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: A933072B +int sub_register(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + /* Encoding T1 */ + /* pattern="000,11,0,1,Rm.3,Rn.3,Rd.3" width=16 stringency=7 */ + { + uint16_t instr = req->instr_word16; + if(((instr & 0xFE00)==0x1A00)) { + res->instrSize = 16; + if(!(req->arch & ARCH_ARMv4T) && !(req->arch & ARCH_ARMv5T) && !(req->arch & ARCH_ARMv6) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_Rm] = (instr & 0x1C0)>>6; + res->fields_mask[FIELD_Rm >> 6] |= 1LL << (FIELD_Rm & 63); + char Rm_width = 3; + res->fields[FIELD_Rn] = (instr & 0x38)>>3; + res->fields_mask[FIELD_Rn >> 6] |= 1LL << (FIELD_Rn & 63); + char Rn_width = 3; + res->fields[FIELD_Rd] = instr & 0x7; + res->fields_mask[FIELD_Rd >> 6] |= 1LL << (FIELD_Rd & 63); + char Rd_width = 3; + + static const instruction_format instr_formats[] = + { + { /* SUBS <Rd>,<Rn>,<Rm> */ + "subs", /* .operation (const char *) */ + 0, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rd,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rn,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rm,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + { /* SUB<c> <Rd>,<Rn>,<Rm> */ + "sub", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rd,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rn,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rm,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 2; + res->mnem = armv7::ARMV7_SUBS; + + /* pcode: d = UInt(Rd) */ + res->fields[FIELD_d] = (res->fields[FIELD_Rd]); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: n = UInt(Rn) */ + res->fields[FIELD_n] = (res->fields[FIELD_Rn]); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: m = UInt(Rm) */ + res->fields[FIELD_m] = (res->fields[FIELD_Rm]); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + /* pcode: setflags = !InITBlock() */ + res->fields[FIELD_setflags] = !(req->inIfThen == IFTHEN_YES); + res->fields_mask[FIELD_setflags >> 6] |= 1LL << (FIELD_setflags & 63); + /* pcode: (shift_t, shift_n) = (SRType_LSL, 0) */ + res->fields[FIELD_shift_t] = 0; + res->fields_mask[FIELD_shift_t >> 6] |= 1LL << (FIELD_shift_t & 63); + res->fields[FIELD_shift_n] = 0; + res->fields_mask[FIELD_shift_n >> 6] |= 1LL << (FIELD_shift_n & 63); + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* Encoding T2 */ + /* pattern="11101,01,1101,S.1,Rn.4,(0),imm3.3,Rd.4,imm2.2,type.2,Rm.4" width=32 stringency=13 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFFE00000)==0xEBA00000)) { + res->instrSize = 32; + if(!((instr & 0x8000)==0x0)) { + res->flags |= FLAG_UNPREDICTABLE; + } + if(!(req->arch & ARCH_ARMv6T2) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_S] = (instr & 0x100000)>>20; + res->fields_mask[FIELD_S >> 6] |= 1LL << (FIELD_S & 63); + char S_width = 1; + res->fields[FIELD_Rn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Rn >> 6] |= 1LL << (FIELD_Rn & 63); + char Rn_width = 4; + res->fields[FIELD_imm3] = (instr & 0x7000)>>12; + res->fields_mask[FIELD_imm3 >> 6] |= 1LL << (FIELD_imm3 & 63); + char imm3_width = 3; + res->fields[FIELD_Rd] = (instr & 0xF00)>>8; + res->fields_mask[FIELD_Rd >> 6] |= 1LL << (FIELD_Rd & 63); + char Rd_width = 4; + res->fields[FIELD_imm2] = (instr & 0xC0)>>6; + res->fields_mask[FIELD_imm2 >> 6] |= 1LL << (FIELD_imm2 & 63); + char imm2_width = 2; + res->fields[FIELD_type] = (instr & 0x30)>>4; + res->fields_mask[FIELD_type >> 6] |= 1LL << (FIELD_type & 63); + char type_width = 2; + res->fields[FIELD_Rm] = instr & 0xF; + res->fields_mask[FIELD_Rm >> 6] |= 1LL << (FIELD_Rm & 63); + char Rm_width = 4; + + static const instruction_format instr_formats[] = + { + { /* SUB{S}<c> <Rd>,<Rn>,<Rm>{,<shift>} */ + "sub", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_OPTIONAL_STATUS, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rd,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rn,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rm,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_SHIFT,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 4 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_SUB; + + /* pcode: if Rd == '1111' && S == '1' then SEE CMP (register) */ + if(((res->fields[FIELD_Rd]) == (0xF)) && ((res->fields[FIELD_S]) == (0x1))) { + + return cmp_register(req, res); + } + /* pcode: if Rn == '1101' then SEE SUB (SP minus register) */ + if((res->fields[FIELD_Rn]) == (0xD)) { + + return sub_sp_minus_register(req, res); + } + /* pcode: d = UInt(Rd) */ + res->fields[FIELD_d] = (res->fields[FIELD_Rd]); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: n = UInt(Rn) */ + res->fields[FIELD_n] = (res->fields[FIELD_Rn]); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: m = UInt(Rm) */ + res->fields[FIELD_m] = (res->fields[FIELD_Rm]); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + /* pcode: setflags = (S == '1') */ + res->fields[FIELD_setflags] = ((res->fields[FIELD_S]) == (0x1)); + res->fields_mask[FIELD_setflags >> 6] |= 1LL << (FIELD_setflags & 63); + /* pcode: (shift_t, shift_n) = DecodeImmShift(type, imm3:imm2) */ + res->fields[FIELD_shift_t] = DecodeImmShift_shift_t(res->fields[FIELD_type], (res->fields[FIELD_imm3]<<2)|(res->fields[FIELD_imm2])); + res->fields_mask[FIELD_shift_t >> 6] |= 1LL << (FIELD_shift_t & 63); + res->fields[FIELD_shift_n] = DecodeImmShift_shift_n(res->fields[FIELD_type], (res->fields[FIELD_imm3]<<2)|(res->fields[FIELD_imm2])); + res->fields_mask[FIELD_shift_n >> 6] |= 1LL << (FIELD_shift_n & 63); + /* pcode: if BadReg(d) || n == 15 || BadReg(m) then UNPREDICTABLE */ + if(((BadReg(res->fields[FIELD_d])) || ((res->fields[FIELD_n]) == (15))) || (BadReg(res->fields[FIELD_m]))) { + res->flags |= FLAG_UNPREDICTABLE; + } + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: 1F7273FD +int sub_sp_minus_immediate(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + /* Encoding T1 */ + /* pattern="1011,0000,1,imm7.7" width=16 stringency=9 */ + { + uint16_t instr = req->instr_word16; + if(((instr & 0xFF80)==0xB080)) { + res->instrSize = 16; + if(!(req->arch & ARCH_ARMv4T) && !(req->arch & ARCH_ARMv5T) && !(req->arch & ARCH_ARMv6) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_imm7] = instr & 0x7F; + res->fields_mask[FIELD_imm7 >> 6] |= 1LL << (FIELD_imm7 & 63); + char imm7_width = 7; + + static const instruction_format instr_formats[] = + { + { /* SUB<c> SP,#<imm32> */ + "sub", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_SP,FIELD_UNINIT,FIELD_UNINIT,"sp","",WRITEBACK_NO}, + {OPERAND_FORMAT_IMM,FIELD_imm32,FIELD_UNINIT,"#","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_SUB; + + /* pcode: d = 13 */ + res->fields[FIELD_d] = 13; + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: setflags = FALSE */ + res->fields[FIELD_setflags] = 0; + res->fields_mask[FIELD_setflags >> 6] |= 1LL << (FIELD_setflags & 63); + /* pcode: imm32 = ZeroExtend(imm7:'00', 32) */ + res->fields[FIELD_imm32] = (res->fields[FIELD_imm7]<<2)|(0x0); + res->fields_mask[FIELD_imm32 >> 6] |= 1LL << (FIELD_imm32 & 63); + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* Encoding T2 */ + /* pattern="11110,i.1,0,1101,S.1,1101,0,imm3.3,Rd.4,imm8.8" width=32 stringency=17 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFBEF8000)==0xF1AD0000)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ARMv6T2) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_i] = (instr & 0x4000000)>>26; + res->fields_mask[FIELD_i >> 6] |= 1LL << (FIELD_i & 63); + char i_width = 1; + res->fields[FIELD_S] = (instr & 0x100000)>>20; + res->fields_mask[FIELD_S >> 6] |= 1LL << (FIELD_S & 63); + char S_width = 1; + res->fields[FIELD_imm3] = (instr & 0x7000)>>12; + res->fields_mask[FIELD_imm3 >> 6] |= 1LL << (FIELD_imm3 & 63); + char imm3_width = 3; + res->fields[FIELD_Rd] = (instr & 0xF00)>>8; + res->fields_mask[FIELD_Rd >> 6] |= 1LL << (FIELD_Rd & 63); + char Rd_width = 4; + res->fields[FIELD_imm8] = instr & 0xFF; + res->fields_mask[FIELD_imm8 >> 6] |= 1LL << (FIELD_imm8 & 63); + char imm8_width = 8; + + static const instruction_format instr_formats[] = + { + { /* SUB{S}<c> <Rd>,SP,#<imm32> */ + "sub", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_OPTIONAL_STATUS, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rd,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_SP,FIELD_UNINIT,FIELD_UNINIT,"sp","",WRITEBACK_NO}, + {OPERAND_FORMAT_IMM,FIELD_imm32,FIELD_UNINIT,"#","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_SUB; + + /* pcode: if Rd == '1111' && S == '1' then SEE CMP (immediate) */ + if(((res->fields[FIELD_Rd]) == (0xF)) && ((res->fields[FIELD_S]) == (0x1))) { + + return cmp_immediate(req, res); + } + /* pcode: d = UInt(Rd) */ + res->fields[FIELD_d] = (res->fields[FIELD_Rd]); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: setflags = (S == '1') */ + res->fields[FIELD_setflags] = ((res->fields[FIELD_S]) == (0x1)); + res->fields_mask[FIELD_setflags >> 6] |= 1LL << (FIELD_setflags & 63); + /* pcode: imm32 = ThumbExpandImm(i:imm3:imm8) */ + res->fields[FIELD_imm32] = ThumbExpandImm_C_imm32((res->fields[FIELD_i]<<(8+3))|(res->fields[FIELD_imm3]<<8)|(res->fields[FIELD_imm8]), req->carry_in); + /* TODO: handle ThumbExpandImm_C's possible setting of UNPREDICTABLE */ while(0); + res->fields_mask[FIELD_imm32 >> 6] |= 1LL << (FIELD_imm32 & 63); + /* pcode: if d == 15 then UNPREDICTABLE */ + if((res->fields[FIELD_d]) == (15)) { + res->flags |= FLAG_UNPREDICTABLE; + } + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* Encoding T3 */ + /* pattern="11110,i.1,1,0101,0,1101,0,imm3.3,Rd.4,imm8.8" width=32 stringency=17 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFBFF8000)==0xF2AD0000)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ARMv6T2) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_i] = (instr & 0x4000000)>>26; + res->fields_mask[FIELD_i >> 6] |= 1LL << (FIELD_i & 63); + char i_width = 1; + res->fields[FIELD_imm3] = (instr & 0x7000)>>12; + res->fields_mask[FIELD_imm3 >> 6] |= 1LL << (FIELD_imm3 & 63); + char imm3_width = 3; + res->fields[FIELD_Rd] = (instr & 0xF00)>>8; + res->fields_mask[FIELD_Rd >> 6] |= 1LL << (FIELD_Rd & 63); + char Rd_width = 4; + res->fields[FIELD_imm8] = instr & 0xFF; + res->fields_mask[FIELD_imm8 >> 6] |= 1LL << (FIELD_imm8 & 63); + char imm8_width = 8; + + static const instruction_format instr_formats[] = + { + { /* SUBW<c> <Rd>,SP,#<imm32> */ + "subw", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rd,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_SP,FIELD_UNINIT,FIELD_UNINIT,"sp","",WRITEBACK_NO}, + {OPERAND_FORMAT_IMM,FIELD_imm32,FIELD_UNINIT,"#","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_SUBW; + + /* pcode: d = UInt(Rd) */ + res->fields[FIELD_d] = (res->fields[FIELD_Rd]); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: setflags = FALSE */ + res->fields[FIELD_setflags] = 0; + res->fields_mask[FIELD_setflags >> 6] |= 1LL << (FIELD_setflags & 63); + /* pcode: imm32 = ZeroExtend(i:imm3:imm8, 32) */ + res->fields[FIELD_imm32] = (res->fields[FIELD_i]<<(8+3))|(res->fields[FIELD_imm3]<<8)|(res->fields[FIELD_imm8]); + res->fields_mask[FIELD_imm32 >> 6] |= 1LL << (FIELD_imm32 & 63); + /* pcode: if d == 15 then UNPREDICTABLE */ + if((res->fields[FIELD_d]) == (15)) { + res->flags |= FLAG_UNPREDICTABLE; + } + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: 3EC3A657 +int sub_sp_minus_register(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + /* Encoding T1 */ + /* pattern="11101,0,1,1101,S.1,1101,(0),imm3.3,Rd.4,imm2.2,type.2,Rm.4" width=32 stringency=17 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFFEF0000)==0xEBAD0000)) { + res->instrSize = 32; + if(!((instr & 0x8000)==0x0)) { + res->flags |= FLAG_UNPREDICTABLE; + } + if(!(req->arch & ARCH_ARMv6T2) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_S] = (instr & 0x100000)>>20; + res->fields_mask[FIELD_S >> 6] |= 1LL << (FIELD_S & 63); + char S_width = 1; + res->fields[FIELD_imm3] = (instr & 0x7000)>>12; + res->fields_mask[FIELD_imm3 >> 6] |= 1LL << (FIELD_imm3 & 63); + char imm3_width = 3; + res->fields[FIELD_Rd] = (instr & 0xF00)>>8; + res->fields_mask[FIELD_Rd >> 6] |= 1LL << (FIELD_Rd & 63); + char Rd_width = 4; + res->fields[FIELD_imm2] = (instr & 0xC0)>>6; + res->fields_mask[FIELD_imm2 >> 6] |= 1LL << (FIELD_imm2 & 63); + char imm2_width = 2; + res->fields[FIELD_type] = (instr & 0x30)>>4; + res->fields_mask[FIELD_type >> 6] |= 1LL << (FIELD_type & 63); + char type_width = 2; + res->fields[FIELD_Rm] = instr & 0xF; + res->fields_mask[FIELD_Rm >> 6] |= 1LL << (FIELD_Rm & 63); + char Rm_width = 4; + + static const instruction_format instr_formats[] = + { + { /* SUB{S}<c> <Rd>,SP,<Rm>{,<shift>} */ + "sub", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_OPTIONAL_STATUS, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rd,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_SP,FIELD_UNINIT,FIELD_UNINIT,"sp","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rm,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_SHIFT,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 4 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_SUB; + + /* pcode: d = UInt(Rd) */ + res->fields[FIELD_d] = (res->fields[FIELD_Rd]); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: m = UInt(Rm) */ + res->fields[FIELD_m] = (res->fields[FIELD_Rm]); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + /* pcode: setflags = (S == '1') */ + res->fields[FIELD_setflags] = ((res->fields[FIELD_S]) == (0x1)); + res->fields_mask[FIELD_setflags >> 6] |= 1LL << (FIELD_setflags & 63); + /* pcode: (shift_t, shift_n) = DecodeImmShift(type, imm3:imm2) */ + res->fields[FIELD_shift_t] = DecodeImmShift_shift_t(res->fields[FIELD_type], (res->fields[FIELD_imm3]<<2)|(res->fields[FIELD_imm2])); + res->fields_mask[FIELD_shift_t >> 6] |= 1LL << (FIELD_shift_t & 63); + res->fields[FIELD_shift_n] = DecodeImmShift_shift_n(res->fields[FIELD_type], (res->fields[FIELD_imm3]<<2)|(res->fields[FIELD_imm2])); + res->fields_mask[FIELD_shift_n >> 6] |= 1LL << (FIELD_shift_n & 63); + /* pcode: if d == 13 && (shift_t != SRType_LSL || shift_n > 3) then UNPREDICTABLE */ + if(((res->fields[FIELD_d]) == (13)) && ((((res->fields[FIELD_shift_t]) != (0)) || ((res->fields[FIELD_shift_n]) > (3))))) { + res->flags |= FLAG_UNPREDICTABLE; + } + /* pcode: if d == 15 || BadReg(m) then UNPREDICTABLE */ + if(((res->fields[FIELD_d]) == (15)) || (BadReg(res->fields[FIELD_m]))) { + res->flags |= FLAG_UNPREDICTABLE; + } + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: A3D625A0 +int subs_pc_lr_related(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + /* Encoding T1 */ + /* pattern="11110,0,1111,0,1,(1)(1)(1)(0),10,(0),0,(1)(1)(1)(1),imm8.8" width=32 stringency=24 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFFF0D000)==0xF3D08000)) { + res->instrSize = 32; + if(!((instr & 0xF2F00)==0xE0F00)) { + res->flags |= FLAG_UNPREDICTABLE; + } + if(!(req->arch & ARCH_ARMv6T2) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_imm8] = instr & 0xFF; + res->fields_mask[FIELD_imm8 >> 6] |= 1LL << (FIELD_imm8 & 63); + char imm8_width = 8; + + static const instruction_format instr_formats[] = + { + { /* SUBS<c> PC,LR,#<imm8> */ + "subs", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_PC,FIELD_UNINIT,FIELD_UNINIT,"pc","",WRITEBACK_NO}, + {OPERAND_FORMAT_LR,FIELD_UNINIT,FIELD_UNINIT,"lr","",WRITEBACK_NO}, + {OPERAND_FORMAT_IMM,FIELD_imm8,FIELD_UNINIT,"#","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_SUBS; + + /* pcode: n = 14 */ + res->fields[FIELD_n] = 14; + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: imm32 = ZeroExtend(imm8, 32) */ + res->fields[FIELD_imm32] = res->fields[FIELD_imm8]; + res->fields_mask[FIELD_imm32 >> 6] |= 1LL << (FIELD_imm32 & 63); + /* pcode: register_form = FALSE */ + res->fields[FIELD_register_form] = 0; + res->fields_mask[FIELD_register_form >> 6] |= 1LL << (FIELD_register_form & 63); + /* pcode: opcode = '0010' */ + res->fields[FIELD_opcode] = 0x2; + res->fields_mask[FIELD_opcode >> 6] |= 1LL << (FIELD_opcode & 63); + /* pcode: if InITBlock() && !LastInITBlock() then UNPREDICTABLE */ + if((req->inIfThen == IFTHEN_YES) && (!(req->inIfThenLast == IFTHENLAST_YES))) { + res->flags |= FLAG_UNPREDICTABLE; + } + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: 55218289 +int svc(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + /* Encoding T1 */ + /* pattern="1101,1111,imm8.8" width=16 stringency=8 */ + { + uint16_t instr = req->instr_word16; + if(((instr & 0xFF00)==0xDF00)) { + res->instrSize = 16; + if(!(req->arch & ARCH_ARMv4T) && !(req->arch & ARCH_ARMv5T) && !(req->arch & ARCH_ARMv6) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_imm8] = instr & 0xFF; + res->fields_mask[FIELD_imm8 >> 6] |= 1LL << (FIELD_imm8 & 63); + char imm8_width = 8; + + static const instruction_format instr_formats[] = + { + { /* SVC<c> #<imm8> */ + "svc", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_IMM,FIELD_imm8,FIELD_UNINIT,"#","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 1 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_SVC; + + /* pcode: imm32 = ZeroExtend(imm8, 32) */ + res->fields[FIELD_imm32] = res->fields[FIELD_imm8]; + res->fields_mask[FIELD_imm32 >> 6] |= 1LL << (FIELD_imm32 & 63); + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: A0523D40 +int sxtab(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + /* Encoding T1 */ + /* pattern="11111,010,0,100,Rn.4,1111,Rd.4,1,(0),rotate.2,Rm.4" width=32 stringency=18 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFFF0F080)==0xFA40F080)) { + res->instrSize = 32; + if(!((instr & 0x40)==0x0)) { + res->flags |= FLAG_UNPREDICTABLE; + } + if(!(req->arch & ARCH_ARMv6T2) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_Rn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Rn >> 6] |= 1LL << (FIELD_Rn & 63); + char Rn_width = 4; + res->fields[FIELD_Rd] = (instr & 0xF00)>>8; + res->fields_mask[FIELD_Rd >> 6] |= 1LL << (FIELD_Rd & 63); + char Rd_width = 4; + res->fields[FIELD_rotate] = (instr & 0x30)>>4; + res->fields_mask[FIELD_rotate >> 6] |= 1LL << (FIELD_rotate & 63); + char rotate_width = 2; + res->fields[FIELD_Rm] = instr & 0xF; + res->fields_mask[FIELD_Rm >> 6] |= 1LL << (FIELD_Rm & 63); + char Rm_width = 4; + + static const instruction_format instr_formats[] = + { + { /* SXTAB<c> <Rd>,<Rn>,<Rm>{,<rotation>} */ + "sxtab", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rd,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rn,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rm,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_ROTATION,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 4 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_SXTAB; + + /* pcode: if Rn == '1111' then SEE SXTB */ + if((res->fields[FIELD_Rn]) == (0xF)) { + + return sxtb(req, res); + } + /* pcode: d = UInt(Rd) */ + res->fields[FIELD_d] = (res->fields[FIELD_Rd]); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: n = UInt(Rn) */ + res->fields[FIELD_n] = (res->fields[FIELD_Rn]); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: m = UInt(Rm) */ + res->fields[FIELD_m] = (res->fields[FIELD_Rm]); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + /* pcode: rotation = UInt(rotate:'000') */ + res->fields[FIELD_rotation] = ((res->fields[FIELD_rotate]<<3)|(0x0)); + res->fields_mask[FIELD_rotation >> 6] |= 1LL << (FIELD_rotation & 63); + /* pcode: if BadReg(d) || n == 13 || BadReg(m) then UNPREDICTABLE */ + if(((BadReg(res->fields[FIELD_d])) || ((res->fields[FIELD_n]) == (13))) || (BadReg(res->fields[FIELD_m]))) { + res->flags |= FLAG_UNPREDICTABLE; + } + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: BF380115 +int sxtab16(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + /* Encoding T1 */ + /* pattern="11111,010,0,010,Rn.4,1111,Rd.4,1,(0),rotate.2,Rm.4" width=32 stringency=18 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFFF0F080)==0xFA20F080)) { + res->instrSize = 32; + if(!((instr & 0x40)==0x0)) { + res->flags |= FLAG_UNPREDICTABLE; + } + if(!(req->arch & ARCH_ARMv6T2) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_Rn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Rn >> 6] |= 1LL << (FIELD_Rn & 63); + char Rn_width = 4; + res->fields[FIELD_Rd] = (instr & 0xF00)>>8; + res->fields_mask[FIELD_Rd >> 6] |= 1LL << (FIELD_Rd & 63); + char Rd_width = 4; + res->fields[FIELD_rotate] = (instr & 0x30)>>4; + res->fields_mask[FIELD_rotate >> 6] |= 1LL << (FIELD_rotate & 63); + char rotate_width = 2; + res->fields[FIELD_Rm] = instr & 0xF; + res->fields_mask[FIELD_Rm >> 6] |= 1LL << (FIELD_Rm & 63); + char Rm_width = 4; + + static const instruction_format instr_formats[] = + { + { /* SXTAB16<c> <Rd>,<Rn>,<Rm>{,<rotation>} */ + "sxtab16", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rd,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rn,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rm,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_ROTATION,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 4 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_SXTAB16; + + /* pcode: if Rn == '1111' then SEE SXTB16 */ + if((res->fields[FIELD_Rn]) == (0xF)) { + + return sxtb16(req, res); + } + /* pcode: d = UInt(Rd) */ + res->fields[FIELD_d] = (res->fields[FIELD_Rd]); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: n = UInt(Rn) */ + res->fields[FIELD_n] = (res->fields[FIELD_Rn]); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: m = UInt(Rm) */ + res->fields[FIELD_m] = (res->fields[FIELD_Rm]); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + /* pcode: rotation = UInt(rotate:'000') */ + res->fields[FIELD_rotation] = ((res->fields[FIELD_rotate]<<3)|(0x0)); + res->fields_mask[FIELD_rotation >> 6] |= 1LL << (FIELD_rotation & 63); + /* pcode: if BadReg(d) || n == 13 || BadReg(m) then UNPREDICTABLE */ + if(((BadReg(res->fields[FIELD_d])) || ((res->fields[FIELD_n]) == (13))) || (BadReg(res->fields[FIELD_m]))) { + res->flags |= FLAG_UNPREDICTABLE; + } + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: B638E147 +int sxtah(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + /* Encoding T1 */ + /* pattern="11111,010,0,000,Rn.4,1111,Rd.4,1,(0),rotate.2,Rm.4" width=32 stringency=18 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFFF0F080)==0xFA00F080)) { + res->instrSize = 32; + if(!((instr & 0x40)==0x0)) { + res->flags |= FLAG_UNPREDICTABLE; + } + if(!(req->arch & ARCH_ARMv6T2) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_Rn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Rn >> 6] |= 1LL << (FIELD_Rn & 63); + char Rn_width = 4; + res->fields[FIELD_Rd] = (instr & 0xF00)>>8; + res->fields_mask[FIELD_Rd >> 6] |= 1LL << (FIELD_Rd & 63); + char Rd_width = 4; + res->fields[FIELD_rotate] = (instr & 0x30)>>4; + res->fields_mask[FIELD_rotate >> 6] |= 1LL << (FIELD_rotate & 63); + char rotate_width = 2; + res->fields[FIELD_Rm] = instr & 0xF; + res->fields_mask[FIELD_Rm >> 6] |= 1LL << (FIELD_Rm & 63); + char Rm_width = 4; + + static const instruction_format instr_formats[] = + { + { /* SXTAH<c> <Rd>,<Rn>,<Rm>{,<rotation>} */ + "sxtah", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rd,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rn,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rm,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_ROTATION,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 4 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_SXTAH; + + /* pcode: if Rn == '1111' then SEE SXTH */ + if((res->fields[FIELD_Rn]) == (0xF)) { + + return sxth(req, res); + } + /* pcode: d = UInt(Rd) */ + res->fields[FIELD_d] = (res->fields[FIELD_Rd]); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: n = UInt(Rn) */ + res->fields[FIELD_n] = (res->fields[FIELD_Rn]); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: m = UInt(Rm) */ + res->fields[FIELD_m] = (res->fields[FIELD_Rm]); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + /* pcode: rotation = UInt(rotate:'000') */ + res->fields[FIELD_rotation] = ((res->fields[FIELD_rotate]<<3)|(0x0)); + res->fields_mask[FIELD_rotation >> 6] |= 1LL << (FIELD_rotation & 63); + /* pcode: if BadReg(d) || n == 13 || BadReg(m) then UNPREDICTABLE */ + if(((BadReg(res->fields[FIELD_d])) || ((res->fields[FIELD_n]) == (13))) || (BadReg(res->fields[FIELD_m]))) { + res->flags |= FLAG_UNPREDICTABLE; + } + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: 0284ECBA +int sxtb(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + /* Encoding T1 */ + /* pattern="1011,0010,01,Rm.3,Rd.3" width=16 stringency=10 */ + { + uint16_t instr = req->instr_word16; + if(((instr & 0xFFC0)==0xB240)) { + res->instrSize = 16; + if(!(req->arch & ARCH_ARMv6) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_Rm] = (instr & 0x38)>>3; + res->fields_mask[FIELD_Rm >> 6] |= 1LL << (FIELD_Rm & 63); + char Rm_width = 3; + res->fields[FIELD_Rd] = instr & 0x7; + res->fields_mask[FIELD_Rd >> 6] |= 1LL << (FIELD_Rd & 63); + char Rd_width = 3; + + static const instruction_format instr_formats[] = + { + { /* SXTB<c> <Rd>,<Rm> */ + "sxtb", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rd,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rm,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_SXTB; + + /* pcode: d = UInt(Rd) */ + res->fields[FIELD_d] = (res->fields[FIELD_Rd]); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: m = UInt(Rm) */ + res->fields[FIELD_m] = (res->fields[FIELD_Rm]); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + /* pcode: rotation = 0 */ + res->fields[FIELD_rotation] = 0; + res->fields_mask[FIELD_rotation >> 6] |= 1LL << (FIELD_rotation & 63); + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* Encoding T2 */ + /* pattern="11111,010,0,100,1111,1111,Rd.4,1,(0),rotate.2,Rm.4" width=32 stringency=22 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFFFFF080)==0xFA4FF080)) { + res->instrSize = 32; + if(!((instr & 0x40)==0x0)) { + res->flags |= FLAG_UNPREDICTABLE; + } + if(!(req->arch & ARCH_ARMv6T2) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_Rd] = (instr & 0xF00)>>8; + res->fields_mask[FIELD_Rd >> 6] |= 1LL << (FIELD_Rd & 63); + char Rd_width = 4; + res->fields[FIELD_rotate] = (instr & 0x30)>>4; + res->fields_mask[FIELD_rotate >> 6] |= 1LL << (FIELD_rotate & 63); + char rotate_width = 2; + res->fields[FIELD_Rm] = instr & 0xF; + res->fields_mask[FIELD_Rm >> 6] |= 1LL << (FIELD_Rm & 63); + char Rm_width = 4; + + static const instruction_format instr_formats[] = + { + { /* SXTB<c> <Rd>,<Rm>{,<rotation>} */ + "sxtb", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rd,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rm,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_ROTATION,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_SXTB; + + /* pcode: d = UInt(Rd) */ + res->fields[FIELD_d] = (res->fields[FIELD_Rd]); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: m = UInt(Rm) */ + res->fields[FIELD_m] = (res->fields[FIELD_Rm]); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + /* pcode: rotation = UInt(rotate:'000') */ + res->fields[FIELD_rotation] = ((res->fields[FIELD_rotate]<<3)|(0x0)); + res->fields_mask[FIELD_rotation >> 6] |= 1LL << (FIELD_rotation & 63); + /* pcode: if BadReg(d) || BadReg(m) then UNPREDICTABLE */ + if((BadReg(res->fields[FIELD_d])) || (BadReg(res->fields[FIELD_m]))) { + res->flags |= FLAG_UNPREDICTABLE; + } + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: DAF74D2E +int sxtb16(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + /* Encoding T1 */ + /* pattern="11111,010,0,010,1111,1111,Rd.4,1,(0),rotate.2,Rm.4" width=32 stringency=22 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFFFFF080)==0xFA2FF080)) { + res->instrSize = 32; + if(!((instr & 0x40)==0x0)) { + res->flags |= FLAG_UNPREDICTABLE; + } + if(!(req->arch & ARCH_ARMv6T2) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_Rd] = (instr & 0xF00)>>8; + res->fields_mask[FIELD_Rd >> 6] |= 1LL << (FIELD_Rd & 63); + char Rd_width = 4; + res->fields[FIELD_rotate] = (instr & 0x30)>>4; + res->fields_mask[FIELD_rotate >> 6] |= 1LL << (FIELD_rotate & 63); + char rotate_width = 2; + res->fields[FIELD_Rm] = instr & 0xF; + res->fields_mask[FIELD_Rm >> 6] |= 1LL << (FIELD_Rm & 63); + char Rm_width = 4; + + static const instruction_format instr_formats[] = + { + { /* SXTB16<c> <Rd>,<Rm>{,<rotation>} */ + "sxtb16", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rd,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rm,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_ROTATION,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_SXTB16; + + /* pcode: d = UInt(Rd) */ + res->fields[FIELD_d] = (res->fields[FIELD_Rd]); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: m = UInt(Rm) */ + res->fields[FIELD_m] = (res->fields[FIELD_Rm]); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + /* pcode: rotation = UInt(rotate:'000') */ + res->fields[FIELD_rotation] = ((res->fields[FIELD_rotate]<<3)|(0x0)); + res->fields_mask[FIELD_rotation >> 6] |= 1LL << (FIELD_rotation & 63); + /* pcode: if BadReg(d) || BadReg(m) then UNPREDICTABLE */ + if((BadReg(res->fields[FIELD_d])) || (BadReg(res->fields[FIELD_m]))) { + res->flags |= FLAG_UNPREDICTABLE; + } + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: 225ECCD5 +int sxth(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + /* Encoding T1 */ + /* pattern="1011,0010,00,Rm.3,Rd.3" width=16 stringency=10 */ + { + uint16_t instr = req->instr_word16; + if(((instr & 0xFFC0)==0xB200)) { + res->instrSize = 16; + if(!(req->arch & ARCH_ARMv6) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_Rm] = (instr & 0x38)>>3; + res->fields_mask[FIELD_Rm >> 6] |= 1LL << (FIELD_Rm & 63); + char Rm_width = 3; + res->fields[FIELD_Rd] = instr & 0x7; + res->fields_mask[FIELD_Rd >> 6] |= 1LL << (FIELD_Rd & 63); + char Rd_width = 3; + + static const instruction_format instr_formats[] = + { + { /* SXTH<c> <Rd>,<Rm> */ + "sxth", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rd,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rm,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_SXTH; + + /* pcode: d = UInt(Rd) */ + res->fields[FIELD_d] = (res->fields[FIELD_Rd]); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: m = UInt(Rm) */ + res->fields[FIELD_m] = (res->fields[FIELD_Rm]); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + /* pcode: rotation = 0 */ + res->fields[FIELD_rotation] = 0; + res->fields_mask[FIELD_rotation >> 6] |= 1LL << (FIELD_rotation & 63); + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* Encoding T2 */ + /* pattern="11111,010,0,000,1111,1111,Rd.4,1,(0),rotate.2,Rm.4" width=32 stringency=22 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFFFFF080)==0xFA0FF080)) { + res->instrSize = 32; + if(!((instr & 0x40)==0x0)) { + res->flags |= FLAG_UNPREDICTABLE; + } + if(!(req->arch & ARCH_ARMv6T2) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_Rd] = (instr & 0xF00)>>8; + res->fields_mask[FIELD_Rd >> 6] |= 1LL << (FIELD_Rd & 63); + char Rd_width = 4; + res->fields[FIELD_rotate] = (instr & 0x30)>>4; + res->fields_mask[FIELD_rotate >> 6] |= 1LL << (FIELD_rotate & 63); + char rotate_width = 2; + res->fields[FIELD_Rm] = instr & 0xF; + res->fields_mask[FIELD_Rm >> 6] |= 1LL << (FIELD_Rm & 63); + char Rm_width = 4; + + static const instruction_format instr_formats[] = + { + { /* SXTH<c> <Rd>,<Rm>{,<rotation>} */ + "sxth", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rd,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rm,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_ROTATION,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_SXTH; + + /* pcode: d = UInt(Rd) */ + res->fields[FIELD_d] = (res->fields[FIELD_Rd]); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: m = UInt(Rm) */ + res->fields[FIELD_m] = (res->fields[FIELD_Rm]); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + /* pcode: rotation = UInt(rotate:'000') */ + res->fields[FIELD_rotation] = ((res->fields[FIELD_rotate]<<3)|(0x0)); + res->fields_mask[FIELD_rotation >> 6] |= 1LL << (FIELD_rotation & 63); + /* pcode: if BadReg(d) || BadReg(m) then UNPREDICTABLE */ + if((BadReg(res->fields[FIELD_d])) || (BadReg(res->fields[FIELD_m]))) { + res->flags |= FLAG_UNPREDICTABLE; + } + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: 433D429D +int tbb_tbh(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + /* Encoding T1 */ + /* pattern="11101,00,0,1,1,0,1,Rn.4,(1)(1)(1)(1),(0)(0)(0)(0),000,0,Rm.4" width=32 stringency=24 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFFF000F0)==0xE8D00000)) { + res->instrSize = 32; + if(!((instr & 0xFF00)==0xF000)) { + res->flags |= FLAG_UNPREDICTABLE; + } + if(!(req->arch & ARCH_ARMv6T2) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_Rn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Rn >> 6] |= 1LL << (FIELD_Rn & 63); + char Rn_width = 4; + res->fields[FIELD_Rm] = instr & 0xF; + res->fields_mask[FIELD_Rm >> 6] |= 1LL << (FIELD_Rm & 63); + char Rm_width = 4; + + static const instruction_format instr_formats[] = + { + { /* TBB<c> [<Rn>,<Rm>] */ + "tbb", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_MEMORY_TWO_REG,FIELD_Rn,FIELD_Rm,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 1 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_TBB; + + /* pcode: n = UInt(Rn) */ + res->fields[FIELD_n] = (res->fields[FIELD_Rn]); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: m = UInt(Rm) */ + res->fields[FIELD_m] = (res->fields[FIELD_Rm]); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + /* pcode: if n == 13 || BadReg(m) then UNPREDICTABLE */ + if(((res->fields[FIELD_n]) == (13)) || (BadReg(res->fields[FIELD_m]))) { + res->flags |= FLAG_UNPREDICTABLE; + } + /* pcode: if InITBlock() && !LastInITBlock() then UNPREDICTABLE */ + if((req->inIfThen == IFTHEN_YES) && (!(req->inIfThenLast == IFTHENLAST_YES))) { + res->flags |= FLAG_UNPREDICTABLE; + } + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* Encoding T2 */ + /* pattern="11101,00,0,1,1,0,1,Rn.4,(1)(1)(1)(1),(0)(0)(0)(0),000,1,Rm.4" width=32 stringency=24 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFFF000F0)==0xE8D00010)) { + res->instrSize = 32; + if(!((instr & 0xFF00)==0xF000)) { + res->flags |= FLAG_UNPREDICTABLE; + } + if(!(req->arch & ARCH_ARMv6T2) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_Rn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Rn >> 6] |= 1LL << (FIELD_Rn & 63); + char Rn_width = 4; + res->fields[FIELD_Rm] = instr & 0xF; + res->fields_mask[FIELD_Rm >> 6] |= 1LL << (FIELD_Rm & 63); + char Rm_width = 4; + + static const instruction_format instr_formats[] = + { + { /* TBH<c> [<Rn>,<Rm>,LSL #1] */ + "tbh", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_MEMORY_TWO_REG_LSL_ONE,FIELD_Rn,FIELD_Rm,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 1 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_TBH; + + /* pcode: n = UInt(Rn) */ + res->fields[FIELD_n] = (res->fields[FIELD_Rn]); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: m = UInt(Rm) */ + res->fields[FIELD_m] = (res->fields[FIELD_Rm]); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + /* pcode: if n == 13 || BadReg(m) then UNPREDICTABLE */ + if(((res->fields[FIELD_n]) == (13)) || (BadReg(res->fields[FIELD_m]))) { + res->flags |= FLAG_UNPREDICTABLE; + } + /* pcode: if InITBlock() && !LastInITBlock() then UNPREDICTABLE */ + if((req->inIfThen == IFTHEN_YES) && (!(req->inIfThenLast == IFTHENLAST_YES))) { + res->flags |= FLAG_UNPREDICTABLE; + } + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: 8DB62E62 +int teq_immediate(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + /* Encoding T1 */ + /* pattern="11110,i.1,0,0100,1,Rn.4,0,imm3.3,1111,imm8.8" width=32 stringency=17 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFBF08F00)==0xF0900F00)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ARMv6T2) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_i] = (instr & 0x4000000)>>26; + res->fields_mask[FIELD_i >> 6] |= 1LL << (FIELD_i & 63); + char i_width = 1; + res->fields[FIELD_Rn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Rn >> 6] |= 1LL << (FIELD_Rn & 63); + char Rn_width = 4; + res->fields[FIELD_imm3] = (instr & 0x7000)>>12; + res->fields_mask[FIELD_imm3 >> 6] |= 1LL << (FIELD_imm3 & 63); + char imm3_width = 3; + res->fields[FIELD_imm8] = instr & 0xFF; + res->fields_mask[FIELD_imm8 >> 6] |= 1LL << (FIELD_imm8 & 63); + char imm8_width = 8; + + static const instruction_format instr_formats[] = + { + { /* TEQ<c> <Rn>,#<imm32> */ + "teq", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rn,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_IMM,FIELD_imm32,FIELD_UNINIT,"#","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_TEQ; + + /* pcode: n = UInt(Rn) */ + res->fields[FIELD_n] = (res->fields[FIELD_Rn]); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: (imm32, carry) = ThumbExpandImm_C(i:imm3:imm8, APSR.C) */ + res->fields[FIELD_imm32] = ThumbExpandImm_C_imm32((res->fields[FIELD_i]<<(8+3))|(res->fields[FIELD_imm3]<<8)|(res->fields[FIELD_imm8]), res->fields[FIELD_APSR_C]); + res->fields_mask[FIELD_imm32 >> 6] |= 1LL << (FIELD_imm32 & 63); + res->fields[FIELD_carry] = ThumbExpandImm_C_cout((res->fields[FIELD_i]<<(8+3))|(res->fields[FIELD_imm3]<<8)|(res->fields[FIELD_imm8]), res->fields[FIELD_APSR_C]); + res->fields_mask[FIELD_carry >> 6] |= 1LL << (FIELD_carry & 63); + /* TODO: handle ThumbExpandImm_C's possible setting of UNPREDICTABLE */ while(0); + /* pcode: if BadReg(n) then UNPREDICTABLE */ + if(BadReg(res->fields[FIELD_n])) { + res->flags |= FLAG_UNPREDICTABLE; + } + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: 6D212762 +int teq_register(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + /* Encoding T1 */ + /* pattern="11101,01,0100,1,Rn.4,(0),imm3.3,1111,imm2.2,type.2,Rm.4" width=32 stringency=17 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFFF00F00)==0xEA900F00)) { + res->instrSize = 32; + if(!((instr & 0x8000)==0x0)) { + res->flags |= FLAG_UNPREDICTABLE; + } + if(!(req->arch & ARCH_ARMv6T2) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_Rn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Rn >> 6] |= 1LL << (FIELD_Rn & 63); + char Rn_width = 4; + res->fields[FIELD_imm3] = (instr & 0x7000)>>12; + res->fields_mask[FIELD_imm3 >> 6] |= 1LL << (FIELD_imm3 & 63); + char imm3_width = 3; + res->fields[FIELD_imm2] = (instr & 0xC0)>>6; + res->fields_mask[FIELD_imm2 >> 6] |= 1LL << (FIELD_imm2 & 63); + char imm2_width = 2; + res->fields[FIELD_type] = (instr & 0x30)>>4; + res->fields_mask[FIELD_type >> 6] |= 1LL << (FIELD_type & 63); + char type_width = 2; + res->fields[FIELD_Rm] = instr & 0xF; + res->fields_mask[FIELD_Rm >> 6] |= 1LL << (FIELD_Rm & 63); + char Rm_width = 4; + + static const instruction_format instr_formats[] = + { + { /* TEQ<c> <Rn>,<Rm>{,<shift>} */ + "teq", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rn,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rm,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_SHIFT,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_TEQ; + + /* pcode: n = UInt(Rn) */ + res->fields[FIELD_n] = (res->fields[FIELD_Rn]); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: m = UInt(Rm) */ + res->fields[FIELD_m] = (res->fields[FIELD_Rm]); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + /* pcode: (shift_t, shift_n) = DecodeImmShift(type, imm3:imm2) */ + res->fields[FIELD_shift_t] = DecodeImmShift_shift_t(res->fields[FIELD_type], (res->fields[FIELD_imm3]<<2)|(res->fields[FIELD_imm2])); + res->fields_mask[FIELD_shift_t >> 6] |= 1LL << (FIELD_shift_t & 63); + res->fields[FIELD_shift_n] = DecodeImmShift_shift_n(res->fields[FIELD_type], (res->fields[FIELD_imm3]<<2)|(res->fields[FIELD_imm2])); + res->fields_mask[FIELD_shift_n >> 6] |= 1LL << (FIELD_shift_n & 63); + /* pcode: if BadReg(n) || BadReg(m) then UNPREDICTABLE */ + if((BadReg(res->fields[FIELD_n])) || (BadReg(res->fields[FIELD_m]))) { + res->flags |= FLAG_UNPREDICTABLE; + } + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: 3251FBC4 +int thumb16(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + uint16_t instr = req->instr_word16; + uint16_t Opcode = (instr & 0xFC00)>>10; + if(((Opcode & 0x3F)==0x10)) return data_proc(req, res); + if(((Opcode & 0x3F)==0x11)) return spcl_data_branch_exch(req, res); + if(((Opcode & 0x3E)==0x12)) return load_lit_pool(req, res); + if(((Opcode & 0x3E)==0x28)) return adr(req, res); + if(((Opcode & 0x3E)==0x2A)) return add_sp_plus_immediate(req, res); + if(((Opcode & 0x3E)==0x30)) return stm(req, res); + if(((Opcode & 0x3E)==0x32)) return ldm(req, res); + if(((Opcode & 0x3E)==0x38)) return b(req, res); + if(((Opcode & 0x3C)==0x14)) return load_store_single_data(req, res); + if(((Opcode & 0x3C)==0x2C)) return misc(req, res); + if(((Opcode & 0x3C)==0x34)) return cond_branch_superv_call(req, res); + if(((Opcode & 0x38)==0x18)) return load_store_single_data(req, res); + if(((Opcode & 0x38)==0x20)) return load_store_single_data(req, res); + if(((Opcode & 0x30)==0x0)) return shift_immediate_add_sub_mov_cmp(req, res); + return undefined(req, res); +} + +// gen_crc: 05E75796 +int thumb32(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + uint32_t instr = req->instr_word32; + uint32_t op1 = (instr & 0x18000000)>>27; + uint32_t op2 = (instr & 0x7F00000)>>20; + uint32_t op = (instr & 0x8000)>>15; + if(((op1 & 0x3)==0x3) && ((op2 & 0x67)==0x1) && 1) return load_byte_mem_hint(req, res); + if(((op1 & 0x3)==0x3) && ((op2 & 0x67)==0x3) && 1) return load_halfword_mem_hint(req, res); + if(((op1 & 0x3)==0x3) && ((op2 & 0x67)==0x5) && 1) return load_word(req, res); + if(((op1 & 0x3)==0x3) && ((op2 & 0x67)==0x7) && 1) return undefined(req, res); + if(((op1 & 0x3)==0x3) && ((op2 & 0x71)==0x0) && 1) return store_single_data_item(req, res); + if(((op1 & 0x3)==0x3) && ((op2 & 0x71)==0x10) && 1) return advanced_simd_elem_struct_load_store(req, res); + if(((op1 & 0x3)==0x3) && ((op2 & 0x78)==0x30) && 1) return mul_accumulate_absolute_difference(req, res); + if(((op1 & 0x3)==0x3) && ((op2 & 0x78)==0x38) && 1) return long_mul_accumulate_divide(req, res); + if(((op1 & 0x3)==0x1) && ((op2 & 0x64)==0x0) && 1) return load_store_multiple(req, res); + if(((op1 & 0x3)==0x1) && ((op2 & 0x64)==0x4) && 1) return load_store_dual_exclusive_table_branch(req, res); + if(((op1 & 0x3)==0x3) && ((op2 & 0x70)==0x20) && 1) return data_processing_register(req, res); + if(((op1 & 0x3)==0x1) && ((op2 & 0x60)==0x20) && 1) return data_processing_shifted_register(req, res); + if(((op1 & 0x3)==0x2) && ((op2 & 0x20)==0x0) && ((op & 0x1)==0x0)) return data_processing_modified_immediate(req, res); + if(((op1 & 0x3)==0x2) && ((op2 & 0x20)==0x20) && ((op & 0x1)==0x0)) return data_processing_plain_binary_immediate(req, res); + if(((op1 & 0x3)==0x1) && ((op2 & 0x40)==0x40) && 1) return coprocessor_instructions(req, res); + if(((op1 & 0x3)==0x2) && ((op & 0x1)==0x1) && 1) return branches_misc_control(req, res); + if(((op1 & 0x3)==0x3) && ((op2 & 0x40)==0x40) && 1) return coprocessor_instructions(req, res); + return undefined(req, res); +} + +// gen_crc: 339D16D3 +int thumb_root(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + uint16_t instr = req->instr_word16; + uint16_t tmp = (instr & 0xF800)>>11; + if(((tmp & 0x1F)==0x1D)) return thumb32(req, res); + if(((tmp & 0x1F)==0x1E)) return thumb32(req, res); + if(((tmp & 0x1F)==0x1F)) return thumb32(req, res); + if(1) return thumb16(req, res); + return undefined(req, res); +} + +// gen_crc: B083424B +int tst_immediate(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + /* Encoding T1 */ + /* pattern="11110,i.1,0,0000,1,Rn.4,0,imm3.3,1111,imm8.8" width=32 stringency=17 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFBF08F00)==0xF0100F00)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ARMv6T2) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_i] = (instr & 0x4000000)>>26; + res->fields_mask[FIELD_i >> 6] |= 1LL << (FIELD_i & 63); + char i_width = 1; + res->fields[FIELD_Rn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Rn >> 6] |= 1LL << (FIELD_Rn & 63); + char Rn_width = 4; + res->fields[FIELD_imm3] = (instr & 0x7000)>>12; + res->fields_mask[FIELD_imm3 >> 6] |= 1LL << (FIELD_imm3 & 63); + char imm3_width = 3; + res->fields[FIELD_imm8] = instr & 0xFF; + res->fields_mask[FIELD_imm8 >> 6] |= 1LL << (FIELD_imm8 & 63); + char imm8_width = 8; + + static const instruction_format instr_formats[] = + { + { /* TST<c> <Rn>,#<imm32> */ + "tst", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rn,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_IMM,FIELD_imm32,FIELD_UNINIT,"#","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_TST; + + /* pcode: n = UInt(Rn) */ + res->fields[FIELD_n] = (res->fields[FIELD_Rn]); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: (imm32, carry) = ThumbExpandImm_C(i:imm3:imm8, APSR.C) */ + res->fields[FIELD_imm32] = ThumbExpandImm_C_imm32((res->fields[FIELD_i]<<(8+3))|(res->fields[FIELD_imm3]<<8)|(res->fields[FIELD_imm8]), res->fields[FIELD_APSR_C]); + res->fields_mask[FIELD_imm32 >> 6] |= 1LL << (FIELD_imm32 & 63); + res->fields[FIELD_carry] = ThumbExpandImm_C_cout((res->fields[FIELD_i]<<(8+3))|(res->fields[FIELD_imm3]<<8)|(res->fields[FIELD_imm8]), res->fields[FIELD_APSR_C]); + res->fields_mask[FIELD_carry >> 6] |= 1LL << (FIELD_carry & 63); + /* TODO: handle ThumbExpandImm_C's possible setting of UNPREDICTABLE */ while(0); + /* pcode: if BadReg(n) then UNPREDICTABLE */ + if(BadReg(res->fields[FIELD_n])) { + res->flags |= FLAG_UNPREDICTABLE; + } + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: FA7F85AB +int tst_register(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + /* Encoding T1 */ + /* pattern="010000,1000,Rm.3,Rn.3" width=16 stringency=10 */ + { + uint16_t instr = req->instr_word16; + if(((instr & 0xFFC0)==0x4200)) { + res->instrSize = 16; + if(!(req->arch & ARCH_ARMv4T) && !(req->arch & ARCH_ARMv5T) && !(req->arch & ARCH_ARMv6) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_Rm] = (instr & 0x38)>>3; + res->fields_mask[FIELD_Rm >> 6] |= 1LL << (FIELD_Rm & 63); + char Rm_width = 3; + res->fields[FIELD_Rn] = instr & 0x7; + res->fields_mask[FIELD_Rn >> 6] |= 1LL << (FIELD_Rn & 63); + char Rn_width = 3; + + static const instruction_format instr_formats[] = + { + { /* TST<c> <Rn>,<Rm> */ + "tst", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rn,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rm,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_TST; + + /* pcode: n = UInt(Rn) */ + res->fields[FIELD_n] = (res->fields[FIELD_Rn]); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: m = UInt(Rm) */ + res->fields[FIELD_m] = (res->fields[FIELD_Rm]); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + /* pcode: (shift_t, shift_n) = (SRType_LSL, 0) */ + res->fields[FIELD_shift_t] = 0; + res->fields_mask[FIELD_shift_t >> 6] |= 1LL << (FIELD_shift_t & 63); + res->fields[FIELD_shift_n] = 0; + res->fields_mask[FIELD_shift_n >> 6] |= 1LL << (FIELD_shift_n & 63); + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* Encoding T2 */ + /* pattern="11101,01,0000,1,Rn.4,(0),imm3.3,1111,imm2.2,type.2,Rm.4" width=32 stringency=17 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFFF00F00)==0xEA100F00)) { + res->instrSize = 32; + if(!((instr & 0x8000)==0x0)) { + res->flags |= FLAG_UNPREDICTABLE; + } + if(!(req->arch & ARCH_ARMv6T2) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_Rn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Rn >> 6] |= 1LL << (FIELD_Rn & 63); + char Rn_width = 4; + res->fields[FIELD_imm3] = (instr & 0x7000)>>12; + res->fields_mask[FIELD_imm3 >> 6] |= 1LL << (FIELD_imm3 & 63); + char imm3_width = 3; + res->fields[FIELD_imm2] = (instr & 0xC0)>>6; + res->fields_mask[FIELD_imm2 >> 6] |= 1LL << (FIELD_imm2 & 63); + char imm2_width = 2; + res->fields[FIELD_type] = (instr & 0x30)>>4; + res->fields_mask[FIELD_type >> 6] |= 1LL << (FIELD_type & 63); + char type_width = 2; + res->fields[FIELD_Rm] = instr & 0xF; + res->fields_mask[FIELD_Rm >> 6] |= 1LL << (FIELD_Rm & 63); + char Rm_width = 4; + + static const instruction_format instr_formats[] = + { + { /* TST<c> <Rn>,<Rm>{,<shift>} */ + "tst", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rn,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rm,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_SHIFT,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_TST; + + /* pcode: n = UInt(Rn) */ + res->fields[FIELD_n] = (res->fields[FIELD_Rn]); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: m = UInt(Rm) */ + res->fields[FIELD_m] = (res->fields[FIELD_Rm]); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + /* pcode: (shift_t, shift_n) = DecodeImmShift(type, imm3:imm2) */ + res->fields[FIELD_shift_t] = DecodeImmShift_shift_t(res->fields[FIELD_type], (res->fields[FIELD_imm3]<<2)|(res->fields[FIELD_imm2])); + res->fields_mask[FIELD_shift_t >> 6] |= 1LL << (FIELD_shift_t & 63); + res->fields[FIELD_shift_n] = DecodeImmShift_shift_n(res->fields[FIELD_type], (res->fields[FIELD_imm3]<<2)|(res->fields[FIELD_imm2])); + res->fields_mask[FIELD_shift_n >> 6] |= 1LL << (FIELD_shift_n & 63); + /* pcode: if BadReg(n) || BadReg(m) then UNPREDICTABLE */ + if((BadReg(res->fields[FIELD_n])) || (BadReg(res->fields[FIELD_m]))) { + res->flags |= FLAG_UNPREDICTABLE; + } + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: 9B25A763 +int uadd16(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + /* Encoding T1 */ + /* pattern="11111,010,1,001,Rn.4,1111,Rd.4,0,100,Rm.4" width=32 stringency=20 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFFF0F0F0)==0xFA90F040)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ARMv6T2) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_Rn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Rn >> 6] |= 1LL << (FIELD_Rn & 63); + char Rn_width = 4; + res->fields[FIELD_Rd] = (instr & 0xF00)>>8; + res->fields_mask[FIELD_Rd >> 6] |= 1LL << (FIELD_Rd & 63); + char Rd_width = 4; + res->fields[FIELD_Rm] = instr & 0xF; + res->fields_mask[FIELD_Rm >> 6] |= 1LL << (FIELD_Rm & 63); + char Rm_width = 4; + + static const instruction_format instr_formats[] = + { + { /* UADD16<c> <Rd>,<Rn>,<Rm> */ + "uadd16", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rd,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rn,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rm,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_UADD16; + + /* pcode: d = UInt(Rd) */ + res->fields[FIELD_d] = (res->fields[FIELD_Rd]); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: n = UInt(Rn) */ + res->fields[FIELD_n] = (res->fields[FIELD_Rn]); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: m = UInt(Rm) */ + res->fields[FIELD_m] = (res->fields[FIELD_Rm]); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + /* pcode: if BadReg(d) || BadReg(n) || BadReg(m) then UNPREDICTABLE */ + if(((BadReg(res->fields[FIELD_d])) || (BadReg(res->fields[FIELD_n]))) || (BadReg(res->fields[FIELD_m]))) { + res->flags |= FLAG_UNPREDICTABLE; + } + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: 4BD52621 +int uadd8(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + /* Encoding T1 */ + /* pattern="11111,010,1,000,Rn.4,1111,Rd.4,0,100,Rm.4" width=32 stringency=20 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFFF0F0F0)==0xFA80F040)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ARMv6T2) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_Rn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Rn >> 6] |= 1LL << (FIELD_Rn & 63); + char Rn_width = 4; + res->fields[FIELD_Rd] = (instr & 0xF00)>>8; + res->fields_mask[FIELD_Rd >> 6] |= 1LL << (FIELD_Rd & 63); + char Rd_width = 4; + res->fields[FIELD_Rm] = instr & 0xF; + res->fields_mask[FIELD_Rm >> 6] |= 1LL << (FIELD_Rm & 63); + char Rm_width = 4; + + static const instruction_format instr_formats[] = + { + { /* UADD8<c> <Rd>,<Rn>,<Rm> */ + "uadd8", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rd,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rn,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rm,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_UADD8; + + /* pcode: d = UInt(Rd) */ + res->fields[FIELD_d] = (res->fields[FIELD_Rd]); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: n = UInt(Rn) */ + res->fields[FIELD_n] = (res->fields[FIELD_Rn]); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: m = UInt(Rm) */ + res->fields[FIELD_m] = (res->fields[FIELD_Rm]); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + /* pcode: if BadReg(d) || BadReg(n) || BadReg(m) then UNPREDICTABLE */ + if(((BadReg(res->fields[FIELD_d])) || (BadReg(res->fields[FIELD_n]))) || (BadReg(res->fields[FIELD_m]))) { + res->flags |= FLAG_UNPREDICTABLE; + } + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: 49363777 +int uasx(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + /* Encoding T1 */ + /* pattern="11111,010,1,010,Rn.4,1111,Rd.4,0,100,Rm.4" width=32 stringency=20 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFFF0F0F0)==0xFAA0F040)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ARMv6T2) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_Rn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Rn >> 6] |= 1LL << (FIELD_Rn & 63); + char Rn_width = 4; + res->fields[FIELD_Rd] = (instr & 0xF00)>>8; + res->fields_mask[FIELD_Rd >> 6] |= 1LL << (FIELD_Rd & 63); + char Rd_width = 4; + res->fields[FIELD_Rm] = instr & 0xF; + res->fields_mask[FIELD_Rm >> 6] |= 1LL << (FIELD_Rm & 63); + char Rm_width = 4; + + static const instruction_format instr_formats[] = + { + { /* UASX<c> <Rd>,<Rn>,<Rm> */ + "uasx", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rd,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rn,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rm,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_UASX; + + /* pcode: d = UInt(Rd) */ + res->fields[FIELD_d] = (res->fields[FIELD_Rd]); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: n = UInt(Rn) */ + res->fields[FIELD_n] = (res->fields[FIELD_Rn]); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: m = UInt(Rm) */ + res->fields[FIELD_m] = (res->fields[FIELD_Rm]); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + /* pcode: if BadReg(d) || BadReg(n) || BadReg(m) then UNPREDICTABLE */ + if(((BadReg(res->fields[FIELD_d])) || (BadReg(res->fields[FIELD_n]))) || (BadReg(res->fields[FIELD_m]))) { + res->flags |= FLAG_UNPREDICTABLE; + } + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: F2A5E01B +int ubfx(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + /* Encoding T1 */ + /* pattern="11110,(0),11,110,0,Rn.4,0,imm3.3,Rd.4,imm2.2,(0),widthm1.5" width=32 stringency=15 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFBF08000)==0xF3C00000)) { + res->instrSize = 32; + if(!((instr & 0x4000020)==0x0)) { + res->flags |= FLAG_UNPREDICTABLE; + } + if(!(req->arch & ARCH_ARMv6T2) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_Rn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Rn >> 6] |= 1LL << (FIELD_Rn & 63); + char Rn_width = 4; + res->fields[FIELD_imm3] = (instr & 0x7000)>>12; + res->fields_mask[FIELD_imm3 >> 6] |= 1LL << (FIELD_imm3 & 63); + char imm3_width = 3; + res->fields[FIELD_Rd] = (instr & 0xF00)>>8; + res->fields_mask[FIELD_Rd >> 6] |= 1LL << (FIELD_Rd & 63); + char Rd_width = 4; + res->fields[FIELD_imm2] = (instr & 0xC0)>>6; + res->fields_mask[FIELD_imm2 >> 6] |= 1LL << (FIELD_imm2 & 63); + char imm2_width = 2; + res->fields[FIELD_widthm1] = instr & 0x1F; + res->fields_mask[FIELD_widthm1 >> 6] |= 1LL << (FIELD_widthm1 & 63); + char widthm1_width = 5; + + static const instruction_format instr_formats[] = + { + { /* UBFX<c> <Rd>,<Rn>,#<lsbit>,#<width> */ + "ubfx", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rd,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rn,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_IMM,FIELD_lsbit,FIELD_UNINIT,"#","",WRITEBACK_NO}, + {OPERAND_FORMAT_IMM,FIELD_width,FIELD_UNINIT,"#","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 4 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_UBFX; + + /* pcode: d = UInt(Rd) */ + res->fields[FIELD_d] = (res->fields[FIELD_Rd]); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: n = UInt(Rn) */ + res->fields[FIELD_n] = (res->fields[FIELD_Rn]); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: lsbit = UInt(imm3:imm2) */ + res->fields[FIELD_lsbit] = ((res->fields[FIELD_imm3]<<2)|(res->fields[FIELD_imm2])); + res->fields_mask[FIELD_lsbit >> 6] |= 1LL << (FIELD_lsbit & 63); + /* pcode: width = UInt(widthm1)+1 */ + res->fields[FIELD_width] = ((res->fields[FIELD_widthm1])) + (1); + res->fields_mask[FIELD_width >> 6] |= 1LL << (FIELD_width & 63); + /* pcode: if BadReg(d) || BadReg(n) then UNPREDICTABLE */ + if((BadReg(res->fields[FIELD_d])) || (BadReg(res->fields[FIELD_n]))) { + res->flags |= FLAG_UNPREDICTABLE; + } + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: 42193EA0 +int udf(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + /* Encoding T1 */ + /* pattern="1101,1110,imm8.8" width=16 stringency=8 */ + { + uint16_t instr = req->instr_word16; + if(((instr & 0xFF00)==0xDE00)) { + res->instrSize = 16; + if(!(req->arch & ARCH_ARMv4T) && !(req->arch & ARCH_ARMv5T) && !(req->arch & ARCH_ARMv6) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_imm8] = instr & 0xFF; + res->fields_mask[FIELD_imm8 >> 6] |= 1LL << (FIELD_imm8 & 63); + char imm8_width = 8; + + static const instruction_format instr_formats[] = + { + { /* UDF<c> #<imm8> */ + "udf", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_IMM,FIELD_imm8,FIELD_UNINIT,"#","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 1 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_UDF; + + /* pcode: imm32 = ZeroExtend(imm8,32) */ + res->fields[FIELD_imm32] = res->fields[FIELD_imm8]; + res->fields_mask[FIELD_imm32 >> 6] |= 1LL << (FIELD_imm32 & 63); + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* Encoding T2 */ + /* pattern="111,10,1111111,imm4.4,1,010,imm12.12" width=32 stringency=18 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFFF0F000)==0xF7F0A000)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ARMv6T2) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_imm4] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_imm4 >> 6] |= 1LL << (FIELD_imm4 & 63); + char imm4_width = 4; + res->fields[FIELD_imm12] = instr & 0xFFF; + res->fields_mask[FIELD_imm12 >> 6] |= 1LL << (FIELD_imm12 & 63); + char imm12_width = 12; + + static const instruction_format instr_formats[] = + { + { /* UDF<c>.W #<imm16> */ + "udf", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_WIDE, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_IMM,FIELD_imm16,FIELD_UNINIT,"#","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 1 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_UDF; + + /* pcode: imm32 = ZeroExtend(imm4:imm12,32) */ + res->fields[FIELD_imm32] = (res->fields[FIELD_imm4]<<12)|(res->fields[FIELD_imm12]); + res->fields_mask[FIELD_imm32 >> 6] |= 1LL << (FIELD_imm32 & 63); + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: 4E35CA80 +int udiv(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + /* Encoding T1 */ + /* pattern="11111,011101,1,Rn.4,(1)(1)(1)(1),Rd.4,1111,Rm.4" width=32 stringency=20 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFFF000F0)==0xFBB000F0)) { + res->instrSize = 32; + if(!((instr & 0xF000)==0xF000)) { + res->flags |= FLAG_UNPREDICTABLE; + } + if(!(req->arch & ARCH_ARMv7_R)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_Rn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Rn >> 6] |= 1LL << (FIELD_Rn & 63); + char Rn_width = 4; + res->fields[FIELD_Rd] = (instr & 0xF00)>>8; + res->fields_mask[FIELD_Rd >> 6] |= 1LL << (FIELD_Rd & 63); + char Rd_width = 4; + res->fields[FIELD_Rm] = instr & 0xF; + res->fields_mask[FIELD_Rm >> 6] |= 1LL << (FIELD_Rm & 63); + char Rm_width = 4; + + static const instruction_format instr_formats[] = + { + { /* UDIV<c> <Rd>,<Rn>,<Rm> */ + "udiv", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rd,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rn,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rm,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_UDIV; + + /* pcode: d = UInt(Rd) */ + res->fields[FIELD_d] = (res->fields[FIELD_Rd]); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: n = UInt(Rn) */ + res->fields[FIELD_n] = (res->fields[FIELD_Rn]); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: m = UInt(Rm) */ + res->fields[FIELD_m] = (res->fields[FIELD_Rm]); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + /* pcode: if BadReg(d) || BadReg(n) || BadReg(m) then UNPREDICTABLE */ + if(((BadReg(res->fields[FIELD_d])) || (BadReg(res->fields[FIELD_n]))) || (BadReg(res->fields[FIELD_m]))) { + res->flags |= FLAG_UNPREDICTABLE; + } + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: 6CC0300D +int uhadd16(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + /* Encoding T1 */ + /* pattern="11111,010,1,001,Rn.4,1111,Rd.4,0,110,Rm.4" width=32 stringency=20 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFFF0F0F0)==0xFA90F060)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ARMv6T2) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_Rn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Rn >> 6] |= 1LL << (FIELD_Rn & 63); + char Rn_width = 4; + res->fields[FIELD_Rd] = (instr & 0xF00)>>8; + res->fields_mask[FIELD_Rd >> 6] |= 1LL << (FIELD_Rd & 63); + char Rd_width = 4; + res->fields[FIELD_Rm] = instr & 0xF; + res->fields_mask[FIELD_Rm >> 6] |= 1LL << (FIELD_Rm & 63); + char Rm_width = 4; + + static const instruction_format instr_formats[] = + { + { /* UHADD16<c> <Rd>,<Rn>,<Rm> */ + "uhadd16", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rd,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rn,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rm,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_UHADD16; + + /* pcode: d = UInt(Rd) */ + res->fields[FIELD_d] = (res->fields[FIELD_Rd]); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: n = UInt(Rn) */ + res->fields[FIELD_n] = (res->fields[FIELD_Rn]); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: m = UInt(Rm) */ + res->fields[FIELD_m] = (res->fields[FIELD_Rm]); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + /* pcode: if BadReg(d) || BadReg(n) || BadReg(m) then UNPREDICTABLE */ + if(((BadReg(res->fields[FIELD_d])) || (BadReg(res->fields[FIELD_n]))) || (BadReg(res->fields[FIELD_m]))) { + res->flags |= FLAG_UNPREDICTABLE; + } + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: 4BBAF087 +int uhadd8(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + /* Encoding T1 */ + /* pattern="11111,010,1,000,Rn.4,1111,Rd.4,0,110,Rm.4" width=32 stringency=20 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFFF0F0F0)==0xFA80F060)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ARMv6T2) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_Rn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Rn >> 6] |= 1LL << (FIELD_Rn & 63); + char Rn_width = 4; + res->fields[FIELD_Rd] = (instr & 0xF00)>>8; + res->fields_mask[FIELD_Rd >> 6] |= 1LL << (FIELD_Rd & 63); + char Rd_width = 4; + res->fields[FIELD_Rm] = instr & 0xF; + res->fields_mask[FIELD_Rm >> 6] |= 1LL << (FIELD_Rm & 63); + char Rm_width = 4; + + static const instruction_format instr_formats[] = + { + { /* UHADD8<c> <Rd>,<Rn>,<Rm> */ + "uhadd8", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rd,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rn,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rm,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_UHADD8; + + /* pcode: d = UInt(Rd) */ + res->fields[FIELD_d] = (res->fields[FIELD_Rd]); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: n = UInt(Rn) */ + res->fields[FIELD_n] = (res->fields[FIELD_Rn]); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: m = UInt(Rm) */ + res->fields[FIELD_m] = (res->fields[FIELD_Rm]); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + /* pcode: if BadReg(d) || BadReg(n) || BadReg(m) then UNPREDICTABLE */ + if(((BadReg(res->fields[FIELD_d])) || (BadReg(res->fields[FIELD_n]))) || (BadReg(res->fields[FIELD_m]))) { + res->flags |= FLAG_UNPREDICTABLE; + } + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: A14F7445 +int uhasx(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + /* Encoding T1 */ + /* pattern="11111,010,1,010,Rn.4,1111,Rd.4,0,110,Rm.4" width=32 stringency=20 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFFF0F0F0)==0xFAA0F060)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ARMv6T2) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_Rn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Rn >> 6] |= 1LL << (FIELD_Rn & 63); + char Rn_width = 4; + res->fields[FIELD_Rd] = (instr & 0xF00)>>8; + res->fields_mask[FIELD_Rd >> 6] |= 1LL << (FIELD_Rd & 63); + char Rd_width = 4; + res->fields[FIELD_Rm] = instr & 0xF; + res->fields_mask[FIELD_Rm >> 6] |= 1LL << (FIELD_Rm & 63); + char Rm_width = 4; + + static const instruction_format instr_formats[] = + { + { /* UHASX<c> <Rd>,<Rn>,<Rm> */ + "uhasx", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rd,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rn,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rm,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_UHASX; + + /* pcode: d = UInt(Rd) */ + res->fields[FIELD_d] = (res->fields[FIELD_Rd]); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: n = UInt(Rn) */ + res->fields[FIELD_n] = (res->fields[FIELD_Rn]); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: m = UInt(Rm) */ + res->fields[FIELD_m] = (res->fields[FIELD_Rm]); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + /* pcode: if BadReg(d) || BadReg(n) || BadReg(m) then UNPREDICTABLE */ + if(((BadReg(res->fields[FIELD_d])) || (BadReg(res->fields[FIELD_n]))) || (BadReg(res->fields[FIELD_m]))) { + res->flags |= FLAG_UNPREDICTABLE; + } + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: 5FDCD4B6 +int uhsax(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + /* Encoding T1 */ + /* pattern="11111,010,1,110,Rn.4,1111,Rd.4,0,110,Rm.4" width=32 stringency=20 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFFF0F0F0)==0xFAE0F060)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ARMv6T2) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_Rn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Rn >> 6] |= 1LL << (FIELD_Rn & 63); + char Rn_width = 4; + res->fields[FIELD_Rd] = (instr & 0xF00)>>8; + res->fields_mask[FIELD_Rd >> 6] |= 1LL << (FIELD_Rd & 63); + char Rd_width = 4; + res->fields[FIELD_Rm] = instr & 0xF; + res->fields_mask[FIELD_Rm >> 6] |= 1LL << (FIELD_Rm & 63); + char Rm_width = 4; + + static const instruction_format instr_formats[] = + { + { /* UHSAX<c> <Rd>,<Rn>,<Rm> */ + "uhsax", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rd,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rn,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rm,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_UHSAX; + + /* pcode: d = UInt(Rd) */ + res->fields[FIELD_d] = (res->fields[FIELD_Rd]); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: n = UInt(Rn) */ + res->fields[FIELD_n] = (res->fields[FIELD_Rn]); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: m = UInt(Rm) */ + res->fields[FIELD_m] = (res->fields[FIELD_Rm]); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + /* pcode: if BadReg(d) || BadReg(n) || BadReg(m) then UNPREDICTABLE */ + if(((BadReg(res->fields[FIELD_d])) || (BadReg(res->fields[FIELD_n]))) || (BadReg(res->fields[FIELD_m]))) { + res->flags |= FLAG_UNPREDICTABLE; + } + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: 2AA27B74 +int uhsub16(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + /* Encoding T1 */ + /* pattern="11111,010,1,101,Rn.4,1111,Rd.4,0,110,Rm.4" width=32 stringency=20 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFFF0F0F0)==0xFAD0F060)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ARMv6T2) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_Rn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Rn >> 6] |= 1LL << (FIELD_Rn & 63); + char Rn_width = 4; + res->fields[FIELD_Rd] = (instr & 0xF00)>>8; + res->fields_mask[FIELD_Rd >> 6] |= 1LL << (FIELD_Rd & 63); + char Rd_width = 4; + res->fields[FIELD_Rm] = instr & 0xF; + res->fields_mask[FIELD_Rm >> 6] |= 1LL << (FIELD_Rm & 63); + char Rm_width = 4; + + static const instruction_format instr_formats[] = + { + { /* UHSUB16<c> <Rd>,<Rn>,<Rm> */ + "uhsub16", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rd,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rn,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rm,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_UHSUB16; + + /* pcode: d = UInt(Rd) */ + res->fields[FIELD_d] = (res->fields[FIELD_Rd]); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: n = UInt(Rn) */ + res->fields[FIELD_n] = (res->fields[FIELD_Rn]); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: m = UInt(Rm) */ + res->fields[FIELD_m] = (res->fields[FIELD_Rm]); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + /* pcode: if BadReg(d) || BadReg(n) || BadReg(m) then UNPREDICTABLE */ + if(((BadReg(res->fields[FIELD_d])) || (BadReg(res->fields[FIELD_n]))) || (BadReg(res->fields[FIELD_m]))) { + res->flags |= FLAG_UNPREDICTABLE; + } + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: 4E73A098 +int uhsub8(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + /* Encoding T1 */ + /* pattern="11111,010,1,100,Rn.4,1111,Rd.4,0,110,Rm.4" width=32 stringency=20 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFFF0F0F0)==0xFAC0F060)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ARMv6T2) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_Rn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Rn >> 6] |= 1LL << (FIELD_Rn & 63); + char Rn_width = 4; + res->fields[FIELD_Rd] = (instr & 0xF00)>>8; + res->fields_mask[FIELD_Rd >> 6] |= 1LL << (FIELD_Rd & 63); + char Rd_width = 4; + res->fields[FIELD_Rm] = instr & 0xF; + res->fields_mask[FIELD_Rm >> 6] |= 1LL << (FIELD_Rm & 63); + char Rm_width = 4; + + static const instruction_format instr_formats[] = + { + { /* UHSUB8<c> <Rd>,<Rn>,<Rm> */ + "uhsub8", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rd,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rn,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rm,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_UHSUB8; + + /* pcode: d = UInt(Rd) */ + res->fields[FIELD_d] = (res->fields[FIELD_Rd]); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: n = UInt(Rn) */ + res->fields[FIELD_n] = (res->fields[FIELD_Rn]); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: m = UInt(Rm) */ + res->fields[FIELD_m] = (res->fields[FIELD_Rm]); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + /* pcode: if BadReg(d) || BadReg(n) || BadReg(m) then UNPREDICTABLE */ + if(((BadReg(res->fields[FIELD_d])) || (BadReg(res->fields[FIELD_n]))) || (BadReg(res->fields[FIELD_m]))) { + res->flags |= FLAG_UNPREDICTABLE; + } + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: 04858039 +int umaal(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + /* Encoding T1 */ + /* pattern="11111,0111,110,Rn.4,RdLo.4,RdHi.4,0110,Rm.4" width=32 stringency=16 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFFF000F0)==0xFBE00060)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ARMv6T2) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_Rn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Rn >> 6] |= 1LL << (FIELD_Rn & 63); + char Rn_width = 4; + res->fields[FIELD_RdLo] = (instr & 0xF000)>>12; + res->fields_mask[FIELD_RdLo >> 6] |= 1LL << (FIELD_RdLo & 63); + char RdLo_width = 4; + res->fields[FIELD_RdHi] = (instr & 0xF00)>>8; + res->fields_mask[FIELD_RdHi >> 6] |= 1LL << (FIELD_RdHi & 63); + char RdHi_width = 4; + res->fields[FIELD_Rm] = instr & 0xF; + res->fields_mask[FIELD_Rm >> 6] |= 1LL << (FIELD_Rm & 63); + char Rm_width = 4; + + static const instruction_format instr_formats[] = + { + { /* UMAAL<c> <RdLo>,<RdHi>,<Rn>,<Rm> */ + "umaal", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_RdLo,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_RdHi,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rn,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rm,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 4 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_UMAAL; + + /* pcode: dLo = UInt(RdLo) */ + res->fields[FIELD_dLo] = (res->fields[FIELD_RdLo]); + res->fields_mask[FIELD_dLo >> 6] |= 1LL << (FIELD_dLo & 63); + /* pcode: dHi = UInt(RdHi) */ + res->fields[FIELD_dHi] = (res->fields[FIELD_RdHi]); + res->fields_mask[FIELD_dHi >> 6] |= 1LL << (FIELD_dHi & 63); + /* pcode: n = UInt(Rn) */ + res->fields[FIELD_n] = (res->fields[FIELD_Rn]); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: m = UInt(Rm) */ + res->fields[FIELD_m] = (res->fields[FIELD_Rm]); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + /* pcode: if BadReg(dLo) || BadReg(dHi) || BadReg(n) || BadReg(m) then UNPREDICTABLE */ + if((((BadReg(res->fields[FIELD_dLo])) || (BadReg(res->fields[FIELD_dHi]))) || (BadReg(res->fields[FIELD_n]))) || (BadReg(res->fields[FIELD_m]))) { + res->flags |= FLAG_UNPREDICTABLE; + } + /* pcode: if dHi == dLo then UNPREDICTABLE */ + if((res->fields[FIELD_dHi]) == (res->fields[FIELD_dLo])) { + res->flags |= FLAG_UNPREDICTABLE; + } + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: 5799FC39 +int umlal(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + /* Encoding T1 */ + /* pattern="11111,0111,110,Rn.4,RdLo.4,RdHi.4,0000,Rm.4" width=32 stringency=16 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFFF000F0)==0xFBE00000)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ARMv6T2) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_Rn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Rn >> 6] |= 1LL << (FIELD_Rn & 63); + char Rn_width = 4; + res->fields[FIELD_RdLo] = (instr & 0xF000)>>12; + res->fields_mask[FIELD_RdLo >> 6] |= 1LL << (FIELD_RdLo & 63); + char RdLo_width = 4; + res->fields[FIELD_RdHi] = (instr & 0xF00)>>8; + res->fields_mask[FIELD_RdHi >> 6] |= 1LL << (FIELD_RdHi & 63); + char RdHi_width = 4; + res->fields[FIELD_Rm] = instr & 0xF; + res->fields_mask[FIELD_Rm >> 6] |= 1LL << (FIELD_Rm & 63); + char Rm_width = 4; + + static const instruction_format instr_formats[] = + { + { /* UMLAL<c> <RdLo>,<RdHi>,<Rn>,<Rm> */ + "umlal", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_RdLo,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_RdHi,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rn,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rm,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 4 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_UMLAL; + + /* pcode: dLo = UInt(RdLo) */ + res->fields[FIELD_dLo] = (res->fields[FIELD_RdLo]); + res->fields_mask[FIELD_dLo >> 6] |= 1LL << (FIELD_dLo & 63); + /* pcode: dHi = UInt(RdHi) */ + res->fields[FIELD_dHi] = (res->fields[FIELD_RdHi]); + res->fields_mask[FIELD_dHi >> 6] |= 1LL << (FIELD_dHi & 63); + /* pcode: n = UInt(Rn) */ + res->fields[FIELD_n] = (res->fields[FIELD_Rn]); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: m = UInt(Rm) */ + res->fields[FIELD_m] = (res->fields[FIELD_Rm]); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + /* pcode: setflags = FALSE */ + res->fields[FIELD_setflags] = 0; + res->fields_mask[FIELD_setflags >> 6] |= 1LL << (FIELD_setflags & 63); + /* pcode: if BadReg(dLo) || BadReg(dHi) || BadReg(n) || BadReg(m) then UNPREDICTABLE */ + if((((BadReg(res->fields[FIELD_dLo])) || (BadReg(res->fields[FIELD_dHi]))) || (BadReg(res->fields[FIELD_n]))) || (BadReg(res->fields[FIELD_m]))) { + res->flags |= FLAG_UNPREDICTABLE; + } + /* pcode: if dHi == dLo then UNPREDICTABLE */ + if((res->fields[FIELD_dHi]) == (res->fields[FIELD_dLo])) { + res->flags |= FLAG_UNPREDICTABLE; + } + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: 1E0A4900 +int umull(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + /* Encoding T1 */ + /* pattern="11111,0111,010,Rn.4,RdLo.4,RdHi.4,0000,Rm.4" width=32 stringency=16 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFFF000F0)==0xFBA00000)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ARMv6T2) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_Rn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Rn >> 6] |= 1LL << (FIELD_Rn & 63); + char Rn_width = 4; + res->fields[FIELD_RdLo] = (instr & 0xF000)>>12; + res->fields_mask[FIELD_RdLo >> 6] |= 1LL << (FIELD_RdLo & 63); + char RdLo_width = 4; + res->fields[FIELD_RdHi] = (instr & 0xF00)>>8; + res->fields_mask[FIELD_RdHi >> 6] |= 1LL << (FIELD_RdHi & 63); + char RdHi_width = 4; + res->fields[FIELD_Rm] = instr & 0xF; + res->fields_mask[FIELD_Rm >> 6] |= 1LL << (FIELD_Rm & 63); + char Rm_width = 4; + + static const instruction_format instr_formats[] = + { + { /* UMULL<c> <RdLo>,<RdHi>,<Rn>,<Rm> */ + "umull", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_RdLo,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_RdHi,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rn,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rm,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 4 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_UMULL; + + /* pcode: dLo = UInt(RdLo) */ + res->fields[FIELD_dLo] = (res->fields[FIELD_RdLo]); + res->fields_mask[FIELD_dLo >> 6] |= 1LL << (FIELD_dLo & 63); + /* pcode: dHi = UInt(RdHi) */ + res->fields[FIELD_dHi] = (res->fields[FIELD_RdHi]); + res->fields_mask[FIELD_dHi >> 6] |= 1LL << (FIELD_dHi & 63); + /* pcode: n = UInt(Rn) */ + res->fields[FIELD_n] = (res->fields[FIELD_Rn]); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: m = UInt(Rm) */ + res->fields[FIELD_m] = (res->fields[FIELD_Rm]); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + /* pcode: setflags = FALSE */ + res->fields[FIELD_setflags] = 0; + res->fields_mask[FIELD_setflags >> 6] |= 1LL << (FIELD_setflags & 63); + /* pcode: if BadReg(dLo) || BadReg(dHi) || BadReg(n) || BadReg(m) then UNPREDICTABLE */ + if((((BadReg(res->fields[FIELD_dLo])) || (BadReg(res->fields[FIELD_dHi]))) || (BadReg(res->fields[FIELD_n]))) || (BadReg(res->fields[FIELD_m]))) { + res->flags |= FLAG_UNPREDICTABLE; + } + /* pcode: if dHi == dLo then UNPREDICTABLE */ + if((res->fields[FIELD_dHi]) == (res->fields[FIELD_dLo])) { + res->flags |= FLAG_UNPREDICTABLE; + } + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: FF26C526 +int undefined(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + /* Encoding T1 */ + /* pattern="(0)(0)(0)(0)(0)(0)(0)(0)(0)(0)(0)(0)(0)(0)(0)(0)" width=16 stringency=16 */ + { + uint16_t instr = req->instr_word16; + if(1) { + res->instrSize = 16; + if(!((instr & 0xFFFF)==0x0)) { + res->flags |= FLAG_UNPREDICTABLE; + } + if(!(req->arch & ARCH_ARMv4T) && !(req->arch & ARCH_ARMv5T) && !(req->arch & ARCH_ARMv6) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + static const instruction_format instr_formats[] = + { + { /* UNDEFINED */ + "undefined", /* .operation (const char *) */ + 0, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 0 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_UNDEFINED; + + /* pcode: UNDEFINED */ + res->status |= STATUS_UNDEFINED; + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* Encoding T1 */ + /* pattern="(0)(0)(0)(0)(0)(0)(0)(0)(0)(0)(0)(0)(0)(0)(0)(0)(0)(0)(0)(0)(0)(0)(0)(0)(0)(0)(0)(0)(0)(0)(0)(0)" width=32 stringency=32 */ + { + uint32_t instr = req->instr_word32; + if(1) { + res->instrSize = 32; + if(!((instr & 0xFFFFFFFF)==0x0)) { + res->flags |= FLAG_UNPREDICTABLE; + } + if(!(req->arch & ARCH_ARMv4T) && !(req->arch & ARCH_ARMv5T) && !(req->arch & ARCH_ARMv6) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + static const instruction_format instr_formats[] = + { + { /* UNDEFINED */ + "undefined", /* .operation (const char *) */ + 0, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 0 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_UNDEFINED; + + /* pcode: UNDEFINED */ + res->status |= STATUS_UNDEFINED; + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: 2CE90D6B +int unpredictable(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + /* Encoding T1 */ + /* pattern="(0)(0)(0)(0)(0)(0)(0)(0)(0)(0)(0)(0)(0)(0)(0)(0)" width=16 stringency=16 */ + { + uint16_t instr = req->instr_word16; + if(1) { + res->instrSize = 16; + if(!((instr & 0xFFFF)==0x0)) { + res->flags |= FLAG_UNPREDICTABLE; + } + if(!(req->arch & ARCH_ARMv4T) && !(req->arch & ARCH_ARMv5T) && !(req->arch & ARCH_ARMv6) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + static const instruction_format instr_formats[] = + { + { /* UNPREDICTABLE */ + "unpredictable", /* .operation (const char *) */ + 0, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 0 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_UNPREDICTABLE; + + /* pcode: UNPREDICTABLE */ + res->flags |= FLAG_UNPREDICTABLE; + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* Encoding T1 */ + /* pattern="(0)(0)(0)(0)(0)(0)(0)(0)(0)(0)(0)(0)(0)(0)(0)(0)(0)(0)(0)(0)(0)(0)(0)(0)(0)(0)(0)(0)(0)(0)(0)(0)" width=32 stringency=32 */ + { + uint32_t instr = req->instr_word32; + if(1) { + res->instrSize = 32; + if(!((instr & 0xFFFFFFFF)==0x0)) { + res->flags |= FLAG_UNPREDICTABLE; + } + if(!(req->arch & ARCH_ARMv4T) && !(req->arch & ARCH_ARMv5T) && !(req->arch & ARCH_ARMv6) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + static const instruction_format instr_formats[] = + { + { /* UNPREDICTABLE */ + "unpredictable", /* .operation (const char *) */ + 0, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 0 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_UNPREDICTABLE; + + /* pcode: UNPREDICTABLE */ + res->flags |= FLAG_UNPREDICTABLE; + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: 637C7ED3 +int uqadd16(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + /* Encoding T1 */ + /* pattern="11111,010,1,001,Rn.4,1111,Rd.4,0,101,Rm.4" width=32 stringency=20 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFFF0F0F0)==0xFA90F050)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ARMv6T2) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_Rn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Rn >> 6] |= 1LL << (FIELD_Rn & 63); + char Rn_width = 4; + res->fields[FIELD_Rd] = (instr & 0xF00)>>8; + res->fields_mask[FIELD_Rd >> 6] |= 1LL << (FIELD_Rd & 63); + char Rd_width = 4; + res->fields[FIELD_Rm] = instr & 0xF; + res->fields_mask[FIELD_Rm >> 6] |= 1LL << (FIELD_Rm & 63); + char Rm_width = 4; + + static const instruction_format instr_formats[] = + { + { /* UQADD16<c> <Rd>,<Rn>,<Rm> */ + "uqadd16", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rd,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rn,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rm,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_UQADD16; + + /* pcode: d = UInt(Rd) */ + res->fields[FIELD_d] = (res->fields[FIELD_Rd]); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: n = UInt(Rn) */ + res->fields[FIELD_n] = (res->fields[FIELD_Rn]); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: m = UInt(Rm) */ + res->fields[FIELD_m] = (res->fields[FIELD_Rm]); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + /* pcode: if BadReg(d) || BadReg(n) || BadReg(m) then UNPREDICTABLE */ + if(((BadReg(res->fields[FIELD_d])) || (BadReg(res->fields[FIELD_n]))) || (BadReg(res->fields[FIELD_m]))) { + res->flags |= FLAG_UNPREDICTABLE; + } + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: D7E41F6D +int uqadd8(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + /* Encoding T1 */ + /* pattern="11111,010,1,000,Rn.4,1111,Rd.4,0,101,Rm.4" width=32 stringency=20 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFFF0F0F0)==0xFA80F050)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ARMv6T2) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_Rn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Rn >> 6] |= 1LL << (FIELD_Rn & 63); + char Rn_width = 4; + res->fields[FIELD_Rd] = (instr & 0xF00)>>8; + res->fields_mask[FIELD_Rd >> 6] |= 1LL << (FIELD_Rd & 63); + char Rd_width = 4; + res->fields[FIELD_Rm] = instr & 0xF; + res->fields_mask[FIELD_Rm >> 6] |= 1LL << (FIELD_Rm & 63); + char Rm_width = 4; + + static const instruction_format instr_formats[] = + { + { /* UQADD8<c> <Rd>,<Rn>,<Rm> */ + "uqadd8", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rd,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rn,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rm,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_UQADD8; + + /* pcode: d = UInt(Rd) */ + res->fields[FIELD_d] = (res->fields[FIELD_Rd]); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: n = UInt(Rn) */ + res->fields[FIELD_n] = (res->fields[FIELD_Rn]); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: m = UInt(Rm) */ + res->fields[FIELD_m] = (res->fields[FIELD_Rm]); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + /* pcode: if BadReg(d) || BadReg(n) || BadReg(m) then UNPREDICTABLE */ + if(((BadReg(res->fields[FIELD_d])) || (BadReg(res->fields[FIELD_n]))) || (BadReg(res->fields[FIELD_m]))) { + res->flags |= FLAG_UNPREDICTABLE; + } + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: D64F3222 +int uqasx(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + /* Encoding T1 */ + /* pattern="11111,010,1,010,Rn.4,1111,Rd.4,0,101,Rm.4" width=32 stringency=20 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFFF0F0F0)==0xFAA0F050)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ARMv6T2) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_Rn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Rn >> 6] |= 1LL << (FIELD_Rn & 63); + char Rn_width = 4; + res->fields[FIELD_Rd] = (instr & 0xF00)>>8; + res->fields_mask[FIELD_Rd >> 6] |= 1LL << (FIELD_Rd & 63); + char Rd_width = 4; + res->fields[FIELD_Rm] = instr & 0xF; + res->fields_mask[FIELD_Rm >> 6] |= 1LL << (FIELD_Rm & 63); + char Rm_width = 4; + + static const instruction_format instr_formats[] = + { + { /* UQASX<c> <Rd>,<Rn>,<Rm> */ + "uqasx", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rd,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rn,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rm,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_UQASX; + + /* pcode: d = UInt(Rd) */ + res->fields[FIELD_d] = (res->fields[FIELD_Rd]); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: n = UInt(Rn) */ + res->fields[FIELD_n] = (res->fields[FIELD_Rn]); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: m = UInt(Rm) */ + res->fields[FIELD_m] = (res->fields[FIELD_Rm]); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + /* pcode: if BadReg(d) || BadReg(n) || BadReg(m) then UNPREDICTABLE */ + if(((BadReg(res->fields[FIELD_d])) || (BadReg(res->fields[FIELD_n]))) || (BadReg(res->fields[FIELD_m]))) { + res->flags |= FLAG_UNPREDICTABLE; + } + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: 28DC92D1 +int uqsax(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + /* Encoding T1 */ + /* pattern="11111,010,1,110,Rn.4,1111,Rd.4,0,101,Rm.4" width=32 stringency=20 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFFF0F0F0)==0xFAE0F050)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ARMv6T2) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_Rn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Rn >> 6] |= 1LL << (FIELD_Rn & 63); + char Rn_width = 4; + res->fields[FIELD_Rd] = (instr & 0xF00)>>8; + res->fields_mask[FIELD_Rd >> 6] |= 1LL << (FIELD_Rd & 63); + char Rd_width = 4; + res->fields[FIELD_Rm] = instr & 0xF; + res->fields_mask[FIELD_Rm >> 6] |= 1LL << (FIELD_Rm & 63); + char Rm_width = 4; + + static const instruction_format instr_formats[] = + { + { /* UQSAX<c> <Rd>,<Rn>,<Rm> */ + "uqsax", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rd,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rn,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rm,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_UQSAX; + + /* pcode: d = UInt(Rd) */ + res->fields[FIELD_d] = (res->fields[FIELD_Rd]); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: n = UInt(Rn) */ + res->fields[FIELD_n] = (res->fields[FIELD_Rn]); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: m = UInt(Rm) */ + res->fields[FIELD_m] = (res->fields[FIELD_Rm]); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + /* pcode: if BadReg(d) || BadReg(n) || BadReg(m) then UNPREDICTABLE */ + if(((BadReg(res->fields[FIELD_d])) || (BadReg(res->fields[FIELD_n]))) || (BadReg(res->fields[FIELD_m]))) { + res->flags |= FLAG_UNPREDICTABLE; + } + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: 251E35AA +int uqsub16(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + /* Encoding T1 */ + /* pattern="11111,010,1,101,Rn.4,1111,Rd.4,0,101,Rm.4" width=32 stringency=20 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFFF0F0F0)==0xFAD0F050)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ARMv6T2) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_Rn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Rn >> 6] |= 1LL << (FIELD_Rn & 63); + char Rn_width = 4; + res->fields[FIELD_Rd] = (instr & 0xF00)>>8; + res->fields_mask[FIELD_Rd >> 6] |= 1LL << (FIELD_Rd & 63); + char Rd_width = 4; + res->fields[FIELD_Rm] = instr & 0xF; + res->fields_mask[FIELD_Rm >> 6] |= 1LL << (FIELD_Rm & 63); + char Rm_width = 4; + + static const instruction_format instr_formats[] = + { + { /* UQSUB16<c> <Rd>,<Rn>,<Rm> */ + "uqsub16", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rd,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rn,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rm,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_UQSUB16; + + /* pcode: d = UInt(Rd) */ + res->fields[FIELD_d] = (res->fields[FIELD_Rd]); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: n = UInt(Rn) */ + res->fields[FIELD_n] = (res->fields[FIELD_Rn]); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: m = UInt(Rm) */ + res->fields[FIELD_m] = (res->fields[FIELD_Rm]); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + /* pcode: if BadReg(d) || BadReg(n) || BadReg(m) then UNPREDICTABLE */ + if(((BadReg(res->fields[FIELD_d])) || (BadReg(res->fields[FIELD_n]))) || (BadReg(res->fields[FIELD_m]))) { + res->flags |= FLAG_UNPREDICTABLE; + } + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: D22D4F72 +int uqsub8(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + /* Encoding T1 */ + /* pattern="11111,010,1,100,Rn.4,1111,Rd.4,0,101,Rm.4" width=32 stringency=20 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFFF0F0F0)==0xFAC0F050)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ARMv6T2) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_Rn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Rn >> 6] |= 1LL << (FIELD_Rn & 63); + char Rn_width = 4; + res->fields[FIELD_Rd] = (instr & 0xF00)>>8; + res->fields_mask[FIELD_Rd >> 6] |= 1LL << (FIELD_Rd & 63); + char Rd_width = 4; + res->fields[FIELD_Rm] = instr & 0xF; + res->fields_mask[FIELD_Rm >> 6] |= 1LL << (FIELD_Rm & 63); + char Rm_width = 4; + + static const instruction_format instr_formats[] = + { + { /* UQSUB8<c> <Rd>,<Rn>,<Rm> */ + "uqsub8", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rd,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rn,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rm,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_UQSUB8; + + /* pcode: d = UInt(Rd) */ + res->fields[FIELD_d] = (res->fields[FIELD_Rd]); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: n = UInt(Rn) */ + res->fields[FIELD_n] = (res->fields[FIELD_Rn]); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: m = UInt(Rm) */ + res->fields[FIELD_m] = (res->fields[FIELD_Rm]); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + /* pcode: if BadReg(d) || BadReg(n) || BadReg(m) then UNPREDICTABLE */ + if(((BadReg(res->fields[FIELD_d])) || (BadReg(res->fields[FIELD_n]))) || (BadReg(res->fields[FIELD_m]))) { + res->flags |= FLAG_UNPREDICTABLE; + } + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: 6B6CFA6B +int usad8(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + /* Encoding T1 */ + /* pattern="11111,0110,111,Rn.4,1111,Rd.4,0000,Rm.4" width=32 stringency=20 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFFF0F0F0)==0xFB70F000)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ARMv6T2) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_Rn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Rn >> 6] |= 1LL << (FIELD_Rn & 63); + char Rn_width = 4; + res->fields[FIELD_Rd] = (instr & 0xF00)>>8; + res->fields_mask[FIELD_Rd >> 6] |= 1LL << (FIELD_Rd & 63); + char Rd_width = 4; + res->fields[FIELD_Rm] = instr & 0xF; + res->fields_mask[FIELD_Rm >> 6] |= 1LL << (FIELD_Rm & 63); + char Rm_width = 4; + + static const instruction_format instr_formats[] = + { + { /* USAD8<c> <Rd>,<Rn>,<Rm> */ + "usad8", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rd,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rn,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rm,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_USAD8; + + /* pcode: d = UInt(Rd) */ + res->fields[FIELD_d] = (res->fields[FIELD_Rd]); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: n = UInt(Rn) */ + res->fields[FIELD_n] = (res->fields[FIELD_Rn]); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: m = UInt(Rm) */ + res->fields[FIELD_m] = (res->fields[FIELD_Rm]); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + /* pcode: if BadReg(d) || BadReg(n) || BadReg(m) then UNPREDICTABLE */ + if(((BadReg(res->fields[FIELD_d])) || (BadReg(res->fields[FIELD_n]))) || (BadReg(res->fields[FIELD_m]))) { + res->flags |= FLAG_UNPREDICTABLE; + } + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: E80E2023 +int usada8(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + /* Encoding T1 */ + /* pattern="11111,0110,111,Rn.4,Ra.4,Rd.4,0000,Rm.4" width=32 stringency=16 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFFF000F0)==0xFB700000)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ARMv6T2) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_Rn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Rn >> 6] |= 1LL << (FIELD_Rn & 63); + char Rn_width = 4; + res->fields[FIELD_Ra] = (instr & 0xF000)>>12; + res->fields_mask[FIELD_Ra >> 6] |= 1LL << (FIELD_Ra & 63); + char Ra_width = 4; + res->fields[FIELD_Rd] = (instr & 0xF00)>>8; + res->fields_mask[FIELD_Rd >> 6] |= 1LL << (FIELD_Rd & 63); + char Rd_width = 4; + res->fields[FIELD_Rm] = instr & 0xF; + res->fields_mask[FIELD_Rm >> 6] |= 1LL << (FIELD_Rm & 63); + char Rm_width = 4; + + static const instruction_format instr_formats[] = + { + { /* USADA8<c> <Rd>,<Rn>,<Rm>,<Ra> */ + "usada8", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rd,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rn,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rm,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Ra,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 4 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_USADA8; + + /* pcode: if Ra == '1111' then SEE USAD8 */ + if((res->fields[FIELD_Ra]) == (0xF)) { + + return usad8(req, res); + } + /* pcode: d = UInt(Rd) */ + res->fields[FIELD_d] = (res->fields[FIELD_Rd]); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: n = UInt(Rn) */ + res->fields[FIELD_n] = (res->fields[FIELD_Rn]); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: m = UInt(Rm) */ + res->fields[FIELD_m] = (res->fields[FIELD_Rm]); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + /* pcode: a = UInt(Ra) */ + res->fields[FIELD_a] = (res->fields[FIELD_Ra]); + res->fields_mask[FIELD_a >> 6] |= 1LL << (FIELD_a & 63); + /* pcode: if BadReg(d) || BadReg(n) || BadReg(m) || BadReg(a) then UNPREDICTABLE */ + if((((BadReg(res->fields[FIELD_d])) || (BadReg(res->fields[FIELD_n]))) || (BadReg(res->fields[FIELD_m]))) || (BadReg(res->fields[FIELD_a]))) { + res->flags |= FLAG_UNPREDICTABLE; + } + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: DDA1DCE6 +int usat(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + /* Encoding T1 */ + /* pattern="11110,(0),11,10,sh.1,0,Rn.4,0,imm3.3,Rd.4,imm2.2,(0),sat_imm.5" width=32 stringency=14 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFBD08000)==0xF3800000)) { + res->instrSize = 32; + if(!((instr & 0x4000020)==0x0)) { + res->flags |= FLAG_UNPREDICTABLE; + } + if(!(req->arch & ARCH_ARMv6T2) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_sh] = (instr & 0x200000)>>21; + res->fields_mask[FIELD_sh >> 6] |= 1LL << (FIELD_sh & 63); + char sh_width = 1; + res->fields[FIELD_Rn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Rn >> 6] |= 1LL << (FIELD_Rn & 63); + char Rn_width = 4; + res->fields[FIELD_imm3] = (instr & 0x7000)>>12; + res->fields_mask[FIELD_imm3 >> 6] |= 1LL << (FIELD_imm3 & 63); + char imm3_width = 3; + res->fields[FIELD_Rd] = (instr & 0xF00)>>8; + res->fields_mask[FIELD_Rd >> 6] |= 1LL << (FIELD_Rd & 63); + char Rd_width = 4; + res->fields[FIELD_imm2] = (instr & 0xC0)>>6; + res->fields_mask[FIELD_imm2 >> 6] |= 1LL << (FIELD_imm2 & 63); + char imm2_width = 2; + res->fields[FIELD_sat_imm] = instr & 0x1F; + res->fields_mask[FIELD_sat_imm >> 6] |= 1LL << (FIELD_sat_imm & 63); + char sat_imm_width = 5; + + static const instruction_format instr_formats[] = + { + { /* USAT<c> <Rd>,#<saturate_to>,<Rn>{,<shift>} */ + "usat", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rd,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_IMM,FIELD_saturate_to,FIELD_UNINIT,"#","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rn,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_SHIFT,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 4 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_USAT; + + /* pcode: if sh == '1' && (imm3:imm2) == '00000' then SEE USAT16 */ + if(((res->fields[FIELD_sh]) == (0x1)) && ((((res->fields[FIELD_imm3]<<2)|(res->fields[FIELD_imm2]))) == (0x0))) { + + return usat16(req, res); + } + /* pcode: d = UInt(Rd) */ + res->fields[FIELD_d] = (res->fields[FIELD_Rd]); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: n = UInt(Rn) */ + res->fields[FIELD_n] = (res->fields[FIELD_Rn]); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: saturate_to = UInt(sat_imm) */ + res->fields[FIELD_saturate_to] = (res->fields[FIELD_sat_imm]); + res->fields_mask[FIELD_saturate_to >> 6] |= 1LL << (FIELD_saturate_to & 63); + /* pcode: (shift_t, shift_n) = DecodeImmShift(sh:'0', imm3:imm2) */ + res->fields[FIELD_shift_t] = DecodeImmShift_shift_t((res->fields[FIELD_sh]<<1)|(0x0), (res->fields[FIELD_imm3]<<2)|(res->fields[FIELD_imm2])); + res->fields_mask[FIELD_shift_t >> 6] |= 1LL << (FIELD_shift_t & 63); + res->fields[FIELD_shift_n] = DecodeImmShift_shift_n((res->fields[FIELD_sh]<<1)|(0x0), (res->fields[FIELD_imm3]<<2)|(res->fields[FIELD_imm2])); + res->fields_mask[FIELD_shift_n >> 6] |= 1LL << (FIELD_shift_n & 63); + /* pcode: if BadReg(d) || BadReg(n) then UNPREDICTABLE */ + if((BadReg(res->fields[FIELD_d])) || (BadReg(res->fields[FIELD_n]))) { + res->flags |= FLAG_UNPREDICTABLE; + } + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: FA68600F +int usat16(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + /* Encoding T1 */ + /* pattern="11110,(0),11,101,0,Rn.4,0,000,Rd.4,00,(0)(0),sat_imm.4" width=32 stringency=20 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFBF0F0C0)==0xF3A00000)) { + res->instrSize = 32; + if(!((instr & 0x4000030)==0x0)) { + res->flags |= FLAG_UNPREDICTABLE; + } + if(!(req->arch & ARCH_ARMv6T2) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_Rn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Rn >> 6] |= 1LL << (FIELD_Rn & 63); + char Rn_width = 4; + res->fields[FIELD_Rd] = (instr & 0xF00)>>8; + res->fields_mask[FIELD_Rd >> 6] |= 1LL << (FIELD_Rd & 63); + char Rd_width = 4; + res->fields[FIELD_sat_imm] = instr & 0xF; + res->fields_mask[FIELD_sat_imm >> 6] |= 1LL << (FIELD_sat_imm & 63); + char sat_imm_width = 4; + + static const instruction_format instr_formats[] = + { + { /* USAT16<c> <Rd>,#<saturate_to>,<Rn> */ + "usat16", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rd,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_IMM,FIELD_saturate_to,FIELD_UNINIT,"#","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rn,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_USAT16; + + /* pcode: d = UInt(Rd) */ + res->fields[FIELD_d] = (res->fields[FIELD_Rd]); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: n = UInt(Rn) */ + res->fields[FIELD_n] = (res->fields[FIELD_Rn]); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: saturate_to = UInt(sat_imm) */ + res->fields[FIELD_saturate_to] = (res->fields[FIELD_sat_imm]); + res->fields_mask[FIELD_saturate_to >> 6] |= 1LL << (FIELD_saturate_to & 63); + /* pcode: if BadReg(d) || BadReg(n) then UNPREDICTABLE */ + if((BadReg(res->fields[FIELD_d])) || (BadReg(res->fields[FIELD_n]))) { + res->flags |= FLAG_UNPREDICTABLE; + } + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: B7A59784 +int usax(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + /* Encoding T1 */ + /* pattern="11111,010,1,110,Rn.4,1111,Rd.4,0,100,Rm.4" width=32 stringency=20 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFFF0F0F0)==0xFAE0F040)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ARMv6T2) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_Rn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Rn >> 6] |= 1LL << (FIELD_Rn & 63); + char Rn_width = 4; + res->fields[FIELD_Rd] = (instr & 0xF00)>>8; + res->fields_mask[FIELD_Rd >> 6] |= 1LL << (FIELD_Rd & 63); + char Rd_width = 4; + res->fields[FIELD_Rm] = instr & 0xF; + res->fields_mask[FIELD_Rm >> 6] |= 1LL << (FIELD_Rm & 63); + char Rm_width = 4; + + static const instruction_format instr_formats[] = + { + { /* USAX<c> <Rd>,<Rn>,<Rm> */ + "usax", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rd,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rn,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rm,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_USAX; + + /* pcode: d = UInt(Rd) */ + res->fields[FIELD_d] = (res->fields[FIELD_Rd]); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: n = UInt(Rn) */ + res->fields[FIELD_n] = (res->fields[FIELD_Rn]); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: m = UInt(Rm) */ + res->fields[FIELD_m] = (res->fields[FIELD_Rm]); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + /* pcode: if BadReg(d) || BadReg(n) || BadReg(m) then UNPREDICTABLE */ + if(((BadReg(res->fields[FIELD_d])) || (BadReg(res->fields[FIELD_n]))) || (BadReg(res->fields[FIELD_m]))) { + res->flags |= FLAG_UNPREDICTABLE; + } + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: DD47EC1A +int usub16(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + /* Encoding T1 */ + /* pattern="11111,010,1,101,Rn.4,1111,Rd.4,0,100,Rm.4" width=32 stringency=20 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFFF0F0F0)==0xFAD0F040)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ARMv6T2) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_Rn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Rn >> 6] |= 1LL << (FIELD_Rn & 63); + char Rn_width = 4; + res->fields[FIELD_Rd] = (instr & 0xF00)>>8; + res->fields_mask[FIELD_Rd >> 6] |= 1LL << (FIELD_Rd & 63); + char Rd_width = 4; + res->fields[FIELD_Rm] = instr & 0xF; + res->fields_mask[FIELD_Rm >> 6] |= 1LL << (FIELD_Rm & 63); + char Rm_width = 4; + + static const instruction_format instr_formats[] = + { + { /* USUB16<c> <Rd>,<Rn>,<Rm> */ + "usub16", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rd,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rn,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rm,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_USUB16; + + /* pcode: d = UInt(Rd) */ + res->fields[FIELD_d] = (res->fields[FIELD_Rd]); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: n = UInt(Rn) */ + res->fields[FIELD_n] = (res->fields[FIELD_Rn]); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: m = UInt(Rm) */ + res->fields[FIELD_m] = (res->fields[FIELD_Rm]); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + /* pcode: if BadReg(d) || BadReg(n) || BadReg(m) then UNPREDICTABLE */ + if(((BadReg(res->fields[FIELD_d])) || (BadReg(res->fields[FIELD_n]))) || (BadReg(res->fields[FIELD_m]))) { + res->flags |= FLAG_UNPREDICTABLE; + } + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: 4E1C763E +int usub8(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + /* Encoding T1 */ + /* pattern="11111,010,1,100,Rn.4,1111,Rd.4,0,100,Rm.4" width=32 stringency=20 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFFF0F0F0)==0xFAC0F040)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ARMv6T2) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_Rn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Rn >> 6] |= 1LL << (FIELD_Rn & 63); + char Rn_width = 4; + res->fields[FIELD_Rd] = (instr & 0xF00)>>8; + res->fields_mask[FIELD_Rd >> 6] |= 1LL << (FIELD_Rd & 63); + char Rd_width = 4; + res->fields[FIELD_Rm] = instr & 0xF; + res->fields_mask[FIELD_Rm >> 6] |= 1LL << (FIELD_Rm & 63); + char Rm_width = 4; + + static const instruction_format instr_formats[] = + { + { /* USUB8<c> <Rd>,<Rn>,<Rm> */ + "usub8", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rd,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rn,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rm,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_USUB8; + + /* pcode: d = UInt(Rd) */ + res->fields[FIELD_d] = (res->fields[FIELD_Rd]); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: n = UInt(Rn) */ + res->fields[FIELD_n] = (res->fields[FIELD_Rn]); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: m = UInt(Rm) */ + res->fields[FIELD_m] = (res->fields[FIELD_Rm]); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + /* pcode: if BadReg(d) || BadReg(n) || BadReg(m) then UNPREDICTABLE */ + if(((BadReg(res->fields[FIELD_d])) || (BadReg(res->fields[FIELD_n]))) || (BadReg(res->fields[FIELD_m]))) { + res->flags |= FLAG_UNPREDICTABLE; + } + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: 26E67C34 +int uxtab(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + /* Encoding T1 */ + /* pattern="11111,010,0,101,Rn.4,1111,Rd.4,1,(0),rotate.2,Rm.4" width=32 stringency=18 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFFF0F080)==0xFA50F080)) { + res->instrSize = 32; + if(!((instr & 0x40)==0x0)) { + res->flags |= FLAG_UNPREDICTABLE; + } + if(!(req->arch & ARCH_ARMv6T2) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_Rn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Rn >> 6] |= 1LL << (FIELD_Rn & 63); + char Rn_width = 4; + res->fields[FIELD_Rd] = (instr & 0xF00)>>8; + res->fields_mask[FIELD_Rd >> 6] |= 1LL << (FIELD_Rd & 63); + char Rd_width = 4; + res->fields[FIELD_rotate] = (instr & 0x30)>>4; + res->fields_mask[FIELD_rotate >> 6] |= 1LL << (FIELD_rotate & 63); + char rotate_width = 2; + res->fields[FIELD_Rm] = instr & 0xF; + res->fields_mask[FIELD_Rm >> 6] |= 1LL << (FIELD_Rm & 63); + char Rm_width = 4; + + static const instruction_format instr_formats[] = + { + { /* UXTAB<c> <Rd>,<Rn>,<Rm>{,<rotation>} */ + "uxtab", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rd,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rn,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rm,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_ROTATION,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 4 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_UXTAB; + + /* pcode: if Rn == '1111' then SEE UXTB */ + if((res->fields[FIELD_Rn]) == (0xF)) { + + return uxtb(req, res); + } + /* pcode: d = UInt(Rd) */ + res->fields[FIELD_d] = (res->fields[FIELD_Rd]); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: n = UInt(Rn) */ + res->fields[FIELD_n] = (res->fields[FIELD_Rn]); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: m = UInt(Rm) */ + res->fields[FIELD_m] = (res->fields[FIELD_Rm]); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + /* pcode: rotation = UInt(rotate:'000') */ + res->fields[FIELD_rotation] = ((res->fields[FIELD_rotate]<<3)|(0x0)); + res->fields_mask[FIELD_rotation >> 6] |= 1LL << (FIELD_rotation & 63); + /* pcode: if BadReg(d) || n == 13 || BadReg(m) then UNPREDICTABLE */ + if(((BadReg(res->fields[FIELD_d])) || ((res->fields[FIELD_n]) == (13))) || (BadReg(res->fields[FIELD_m]))) { + res->flags |= FLAG_UNPREDICTABLE; + } + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: B645F69C +int uxtab16(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + /* Encoding T1 */ + /* pattern="11111,010,0,011,Rn.4,1111,Rd.4,1,(0),rotate.2,Rm.4" width=32 stringency=18 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFFF0F080)==0xFA30F080)) { + res->instrSize = 32; + if(!((instr & 0x40)==0x0)) { + res->flags |= FLAG_UNPREDICTABLE; + } + if(!(req->arch & ARCH_ARMv6T2) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_Rn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Rn >> 6] |= 1LL << (FIELD_Rn & 63); + char Rn_width = 4; + res->fields[FIELD_Rd] = (instr & 0xF00)>>8; + res->fields_mask[FIELD_Rd >> 6] |= 1LL << (FIELD_Rd & 63); + char Rd_width = 4; + res->fields[FIELD_rotate] = (instr & 0x30)>>4; + res->fields_mask[FIELD_rotate >> 6] |= 1LL << (FIELD_rotate & 63); + char rotate_width = 2; + res->fields[FIELD_Rm] = instr & 0xF; + res->fields_mask[FIELD_Rm >> 6] |= 1LL << (FIELD_Rm & 63); + char Rm_width = 4; + + static const instruction_format instr_formats[] = + { + { /* UXTAB16<c> <Rd>,<Rn>,<Rm>{,<rotation>} */ + "uxtab16", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rd,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rn,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rm,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_ROTATION,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 4 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_UXTAB16; + + /* pcode: if Rn == '1111' then SEE UXTB16 */ + if((res->fields[FIELD_Rn]) == (0xF)) { + + return uxtb16(req, res); + } + /* pcode: d = UInt(Rd) */ + res->fields[FIELD_d] = (res->fields[FIELD_Rd]); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: n = UInt(Rn) */ + res->fields[FIELD_n] = (res->fields[FIELD_Rn]); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: m = UInt(Rm) */ + res->fields[FIELD_m] = (res->fields[FIELD_Rm]); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + /* pcode: rotation = UInt(rotate:'000') */ + res->fields[FIELD_rotation] = ((res->fields[FIELD_rotate]<<3)|(0x0)); + res->fields_mask[FIELD_rotation >> 6] |= 1LL << (FIELD_rotation & 63); + /* pcode: if BadReg(d) || n == 13 || BadReg(m) then UNPREDICTABLE */ + if(((BadReg(res->fields[FIELD_d])) || ((res->fields[FIELD_n]) == (13))) || (BadReg(res->fields[FIELD_m]))) { + res->flags |= FLAG_UNPREDICTABLE; + } + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: B5A5160A +int uxtah(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + /* Encoding T1 */ + /* pattern="11111,010,0,001,Rn.4,1111,Rd.4,1,(0),rotate.2,Rm.4" width=32 stringency=18 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFFF0F080)==0xFA10F080)) { + res->instrSize = 32; + if(!((instr & 0x40)==0x0)) { + res->flags |= FLAG_UNPREDICTABLE; + } + if(!(req->arch & ARCH_ARMv6T2) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_Rn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Rn >> 6] |= 1LL << (FIELD_Rn & 63); + char Rn_width = 4; + res->fields[FIELD_Rd] = (instr & 0xF00)>>8; + res->fields_mask[FIELD_Rd >> 6] |= 1LL << (FIELD_Rd & 63); + char Rd_width = 4; + res->fields[FIELD_rotate] = (instr & 0x30)>>4; + res->fields_mask[FIELD_rotate >> 6] |= 1LL << (FIELD_rotate & 63); + char rotate_width = 2; + res->fields[FIELD_Rm] = instr & 0xF; + res->fields_mask[FIELD_Rm >> 6] |= 1LL << (FIELD_Rm & 63); + char Rm_width = 4; + + static const instruction_format instr_formats[] = + { + { /* UXTAH<c> <Rd>,<Rn>,<Rm>{,<rotation>} */ + "uxtah", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rd,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rn,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rm,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_ROTATION,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 4 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_UXTAH; + + /* pcode: if Rn == '1111' then SEE UXTH */ + if((res->fields[FIELD_Rn]) == (0xF)) { + + return uxth(req, res); + } + /* pcode: d = UInt(Rd) */ + res->fields[FIELD_d] = (res->fields[FIELD_Rd]); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: n = UInt(Rn) */ + res->fields[FIELD_n] = (res->fields[FIELD_Rn]); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: m = UInt(Rm) */ + res->fields[FIELD_m] = (res->fields[FIELD_Rm]); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + /* pcode: rotation = UInt(rotate:'000') */ + res->fields[FIELD_rotation] = ((res->fields[FIELD_rotate]<<3)|(0x0)); + res->fields_mask[FIELD_rotation >> 6] |= 1LL << (FIELD_rotation & 63); + /* pcode: if BadReg(d) || n == 13 || BadReg(m) then UNPREDICTABLE */ + if(((BadReg(res->fields[FIELD_d])) || ((res->fields[FIELD_n]) == (13))) || (BadReg(res->fields[FIELD_m]))) { + res->flags |= FLAG_UNPREDICTABLE; + } + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: FC9C268F +int uxtb(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + /* Encoding T1 */ + /* pattern="1011,0010,11,Rm.3,Rd.3" width=16 stringency=10 */ + { + uint16_t instr = req->instr_word16; + if(((instr & 0xFFC0)==0xB2C0)) { + res->instrSize = 16; + if(!(req->arch & ARCH_ARMv6) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_Rm] = (instr & 0x38)>>3; + res->fields_mask[FIELD_Rm >> 6] |= 1LL << (FIELD_Rm & 63); + char Rm_width = 3; + res->fields[FIELD_Rd] = instr & 0x7; + res->fields_mask[FIELD_Rd >> 6] |= 1LL << (FIELD_Rd & 63); + char Rd_width = 3; + + static const instruction_format instr_formats[] = + { + { /* UXTB<c> <Rd>,<Rm> */ + "uxtb", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rd,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rm,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_UXTB; + + /* pcode: d = UInt(Rd) */ + res->fields[FIELD_d] = (res->fields[FIELD_Rd]); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: m = UInt(Rm) */ + res->fields[FIELD_m] = (res->fields[FIELD_Rm]); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + /* pcode: rotation = 0 */ + res->fields[FIELD_rotation] = 0; + res->fields_mask[FIELD_rotation >> 6] |= 1LL << (FIELD_rotation & 63); + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* Encoding T2 */ + /* pattern="11111,010,0,101,1111,1111,Rd.4,1,(0),rotate.2,Rm.4" width=32 stringency=22 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFFFFF080)==0xFA5FF080)) { + res->instrSize = 32; + if(!((instr & 0x40)==0x0)) { + res->flags |= FLAG_UNPREDICTABLE; + } + if(!(req->arch & ARCH_ARMv6T2) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_Rd] = (instr & 0xF00)>>8; + res->fields_mask[FIELD_Rd >> 6] |= 1LL << (FIELD_Rd & 63); + char Rd_width = 4; + res->fields[FIELD_rotate] = (instr & 0x30)>>4; + res->fields_mask[FIELD_rotate >> 6] |= 1LL << (FIELD_rotate & 63); + char rotate_width = 2; + res->fields[FIELD_Rm] = instr & 0xF; + res->fields_mask[FIELD_Rm >> 6] |= 1LL << (FIELD_Rm & 63); + char Rm_width = 4; + + static const instruction_format instr_formats[] = + { + { /* UXTB<c> <Rd>,<Rm>{,<rotation>} */ + "uxtb", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rd,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rm,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_ROTATION,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_UXTB; + + /* pcode: d = UInt(Rd) */ + res->fields[FIELD_d] = (res->fields[FIELD_Rd]); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: m = UInt(Rm) */ + res->fields[FIELD_m] = (res->fields[FIELD_Rm]); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + /* pcode: rotation = UInt(rotate:'000') */ + res->fields[FIELD_rotation] = ((res->fields[FIELD_rotate]<<3)|(0x0)); + res->fields_mask[FIELD_rotation >> 6] |= 1LL << (FIELD_rotation & 63); + /* pcode: if BadReg(d) || BadReg(m) then UNPREDICTABLE */ + if((BadReg(res->fields[FIELD_d])) || (BadReg(res->fields[FIELD_m]))) { + res->flags |= FLAG_UNPREDICTABLE; + } + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: EFB0283C +int uxtb16(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + /* Encoding T1 */ + /* pattern="11111,010,0,011,1111,1111,Rd.4,1,(0),rotate.2,Rm.4" width=32 stringency=22 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFFFFF080)==0xFA3FF080)) { + res->instrSize = 32; + if(!((instr & 0x40)==0x0)) { + res->flags |= FLAG_UNPREDICTABLE; + } + if(!(req->arch & ARCH_ARMv6T2) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_Rd] = (instr & 0xF00)>>8; + res->fields_mask[FIELD_Rd >> 6] |= 1LL << (FIELD_Rd & 63); + char Rd_width = 4; + res->fields[FIELD_rotate] = (instr & 0x30)>>4; + res->fields_mask[FIELD_rotate >> 6] |= 1LL << (FIELD_rotate & 63); + char rotate_width = 2; + res->fields[FIELD_Rm] = instr & 0xF; + res->fields_mask[FIELD_Rm >> 6] |= 1LL << (FIELD_Rm & 63); + char Rm_width = 4; + + static const instruction_format instr_formats[] = + { + { /* UXTB16<c> <Rd>,<Rm>{,<rotation>} */ + "uxtb16", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rd,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rm,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_ROTATION,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_UXTB16; + + /* pcode: d = UInt(Rd) */ + res->fields[FIELD_d] = (res->fields[FIELD_Rd]); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: m = UInt(Rm) */ + res->fields[FIELD_m] = (res->fields[FIELD_Rm]); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + /* pcode: rotation = UInt(rotate:'000') */ + res->fields[FIELD_rotation] = ((res->fields[FIELD_rotate]<<3)|(0x0)); + res->fields_mask[FIELD_rotation >> 6] |= 1LL << (FIELD_rotation & 63); + /* pcode: if BadReg(d) || BadReg(m) then UNPREDICTABLE */ + if((BadReg(res->fields[FIELD_d])) || (BadReg(res->fields[FIELD_m]))) { + res->flags |= FLAG_UNPREDICTABLE; + } + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: DC4606E0 +int uxth(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + /* Encoding T1 */ + /* pattern="1011,0010,10,Rm.3,Rd.3" width=16 stringency=10 */ + { + uint16_t instr = req->instr_word16; + if(((instr & 0xFFC0)==0xB280)) { + res->instrSize = 16; + if(!(req->arch & ARCH_ARMv6) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_Rm] = (instr & 0x38)>>3; + res->fields_mask[FIELD_Rm >> 6] |= 1LL << (FIELD_Rm & 63); + char Rm_width = 3; + res->fields[FIELD_Rd] = instr & 0x7; + res->fields_mask[FIELD_Rd >> 6] |= 1LL << (FIELD_Rd & 63); + char Rd_width = 3; + + static const instruction_format instr_formats[] = + { + { /* UXTH<c> <Rd>,<Rm> */ + "uxth", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rd,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rm,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_UXTH; + + /* pcode: d = UInt(Rd) */ + res->fields[FIELD_d] = (res->fields[FIELD_Rd]); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: m = UInt(Rm) */ + res->fields[FIELD_m] = (res->fields[FIELD_Rm]); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + /* pcode: rotation = 0 */ + res->fields[FIELD_rotation] = 0; + res->fields_mask[FIELD_rotation >> 6] |= 1LL << (FIELD_rotation & 63); + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* Encoding T2 */ + /* pattern="11111,010,0,001,1111,1111,Rd.4,1,(0),rotate.2,Rm.4" width=32 stringency=22 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFFFFF080)==0xFA1FF080)) { + res->instrSize = 32; + if(!((instr & 0x40)==0x0)) { + res->flags |= FLAG_UNPREDICTABLE; + } + if(!(req->arch & ARCH_ARMv6T2) && !(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_Rd] = (instr & 0xF00)>>8; + res->fields_mask[FIELD_Rd >> 6] |= 1LL << (FIELD_Rd & 63); + char Rd_width = 4; + res->fields[FIELD_rotate] = (instr & 0x30)>>4; + res->fields_mask[FIELD_rotate >> 6] |= 1LL << (FIELD_rotate & 63); + char rotate_width = 2; + res->fields[FIELD_Rm] = instr & 0xF; + res->fields_mask[FIELD_Rm >> 6] |= 1LL << (FIELD_Rm & 63); + char Rm_width = 4; + + static const instruction_format instr_formats[] = + { + { /* UXTH<c> <Rd>,<Rm>{,<rotation>} */ + "uxth", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rd,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rm,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_ROTATION,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_UXTH; + + /* pcode: d = UInt(Rd) */ + res->fields[FIELD_d] = (res->fields[FIELD_Rd]); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: m = UInt(Rm) */ + res->fields[FIELD_m] = (res->fields[FIELD_Rm]); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + /* pcode: rotation = UInt(rotate:'000') */ + res->fields[FIELD_rotation] = ((res->fields[FIELD_rotate]<<3)|(0x0)); + res->fields_mask[FIELD_rotation >> 6] |= 1LL << (FIELD_rotation & 63); + /* pcode: if BadReg(d) || BadReg(m) then UNPREDICTABLE */ + if((BadReg(res->fields[FIELD_d])) || (BadReg(res->fields[FIELD_m]))) { + res->flags |= FLAG_UNPREDICTABLE; + } + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: CAC6E836 +int vaba(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + res->group = INSN_GROUP_NEON; + /* Encoding T1 */ + /* pattern="111,U.1,1111,0,D.1,size.2,Vn.4,Vd.4,0111,N.1,Q.1,M.1,1,Vm.4" width=32 stringency=18 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xEF800F10)==0xEF000710)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ADVSIMD)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_U] = (instr & 0x10000000)>>28; + res->fields_mask[FIELD_U >> 6] |= 1LL << (FIELD_U & 63); + char U_width = 1; + res->fields[FIELD_D] = (instr & 0x400000)>>22; + res->fields_mask[FIELD_D >> 6] |= 1LL << (FIELD_D & 63); + char D_width = 1; + res->fields[FIELD_size] = (instr & 0x300000)>>20; + res->fields_mask[FIELD_size >> 6] |= 1LL << (FIELD_size & 63); + char size_width = 2; + res->fields[FIELD_Vn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Vn >> 6] |= 1LL << (FIELD_Vn & 63); + char Vn_width = 4; + res->fields[FIELD_Vd] = (instr & 0xF000)>>12; + res->fields_mask[FIELD_Vd >> 6] |= 1LL << (FIELD_Vd & 63); + char Vd_width = 4; + res->fields[FIELD_N] = (instr & 0x80)>>7; + res->fields_mask[FIELD_N >> 6] |= 1LL << (FIELD_N & 63); + char N_width = 1; + res->fields[FIELD_Q] = (instr & 0x40)>>6; + res->fields_mask[FIELD_Q >> 6] |= 1LL << (FIELD_Q & 63); + char Q_width = 1; + res->fields[FIELD_M] = (instr & 0x20)>>5; + res->fields_mask[FIELD_M >> 6] |= 1LL << (FIELD_M & 63); + char M_width = 1; + res->fields[FIELD_Vm] = instr & 0xF; + res->fields_mask[FIELD_Vm >> 6] |= 1LL << (FIELD_Vm & 63); + char Vm_width = 4; + + static const instruction_format instr_formats[] = + { + { /* VABA<c>.<dt> <Dd>,<Dn>,<Dm> */ + "vaba", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_VFP_DATA_SIZE, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_n,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_m,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + { /* VABA<c>.<dt> <Qd>,<Qn>,<Qm> */ + "vaba", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_VFP_DATA_SIZE, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"q","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_n,FIELD_UNINIT,"q","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_m,FIELD_UNINIT,"q","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 2; + res->mnem = armv7::ARMV7_VABA; + + /* pcode: if size == '11' then UNDEFINED */ + if((res->fields[FIELD_size]) == (0x3)) { + res->status |= STATUS_UNDEFINED; + } + /* pcode: if Q == '1' && (Vd<0> == '1' || Vn<0> == '1' || Vm<0> == '1') then UNDEFINED */ + if(((res->fields[FIELD_Q]) == (0x1)) && ((((((res->fields[FIELD_Vd] & 1)) == (0x1)) || (((res->fields[FIELD_Vn] & 1)) == (0x1))) || (((res->fields[FIELD_Vm] & 1)) == (0x1))))) { + res->status |= STATUS_UNDEFINED; + } + /* pcode: unsigned = (U == '1') */ + res->fields[FIELD_unsigned] = ((res->fields[FIELD_U]) == (0x1)); + res->fields_mask[FIELD_unsigned >> 6] |= 1LL << (FIELD_unsigned & 63); + /* pcode: long_destination = FALSE */ + res->fields[FIELD_long_destination] = 0; + res->fields_mask[FIELD_long_destination >> 6] |= 1LL << (FIELD_long_destination & 63); + /* pcode: esize = 8 << UInt(size) */ + res->fields[FIELD_esize] = (8) << ((res->fields[FIELD_size])); + res->fields_mask[FIELD_esize >> 6] |= 1LL << (FIELD_esize & 63); + /* pcode: elements = 64 DIV esize */ + res->fields[FIELD_elements] = ((res->fields[FIELD_esize]) ? ((64) / (res->fields[FIELD_esize])) : 0); + res->fields_mask[FIELD_elements >> 6] |= 1LL << (FIELD_elements & 63); + /* pcode: d = UInt(D:Vd) */ + res->fields[FIELD_d] = ((res->fields[FIELD_D]<<Vd_width)|(res->fields[FIELD_Vd])); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: n = UInt(N:Vn) */ + res->fields[FIELD_n] = ((res->fields[FIELD_N]<<Vn_width)|(res->fields[FIELD_Vn])); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: m = UInt(M:Vm) */ + res->fields[FIELD_m] = ((res->fields[FIELD_M]<<Vm_width)|(res->fields[FIELD_Vm])); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + /* pcode: regs = if Q == '0' then 1 else 2 */ + if((res->fields[FIELD_Q]) == (0x0)) { + res->fields[FIELD_regs] = 1; + res->fields_mask[FIELD_regs >> 6] |= 1LL << (FIELD_regs & 63); + } + else { + res->fields[FIELD_regs] = 2; + res->fields_mask[FIELD_regs >> 6] |= 1LL << (FIELD_regs & 63); + } + /* pcode: fmt_idx = (Q == '1') */ + res->fields[FIELD_fmt_idx] = ((res->fields[FIELD_Q]) == (0x1)); + res->fields_mask[FIELD_fmt_idx >> 6] |= 1LL << (FIELD_fmt_idx & 63); + /* pcode: dt = UInt(U:size) */ + res->fields[FIELD_dt] = ((res->fields[FIELD_U]<<size_width)|(res->fields[FIELD_size])); + res->fields_mask[FIELD_dt >> 6] |= 1LL << (FIELD_dt & 63); + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* Encoding T2 */ + /* pattern="111,U.1,1111,1,D.1,size.2,Vn.4,Vd.4,0101,N.1,0,M.1,0,Vm.4" width=32 stringency=18 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xEF800F50)==0xEF800500)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ADVSIMD)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_U] = (instr & 0x10000000)>>28; + res->fields_mask[FIELD_U >> 6] |= 1LL << (FIELD_U & 63); + char U_width = 1; + res->fields[FIELD_D] = (instr & 0x400000)>>22; + res->fields_mask[FIELD_D >> 6] |= 1LL << (FIELD_D & 63); + char D_width = 1; + res->fields[FIELD_size] = (instr & 0x300000)>>20; + res->fields_mask[FIELD_size >> 6] |= 1LL << (FIELD_size & 63); + char size_width = 2; + res->fields[FIELD_Vn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Vn >> 6] |= 1LL << (FIELD_Vn & 63); + char Vn_width = 4; + res->fields[FIELD_Vd] = (instr & 0xF000)>>12; + res->fields_mask[FIELD_Vd >> 6] |= 1LL << (FIELD_Vd & 63); + char Vd_width = 4; + res->fields[FIELD_N] = (instr & 0x80)>>7; + res->fields_mask[FIELD_N >> 6] |= 1LL << (FIELD_N & 63); + char N_width = 1; + res->fields[FIELD_M] = (instr & 0x20)>>5; + res->fields_mask[FIELD_M >> 6] |= 1LL << (FIELD_M & 63); + char M_width = 1; + res->fields[FIELD_Vm] = instr & 0xF; + res->fields_mask[FIELD_Vm >> 6] |= 1LL << (FIELD_Vm & 63); + char Vm_width = 4; + + static const instruction_format instr_formats[] = + { + { /* VABAL<c>.<dt> <Qd>,<Dn>,<Dm> */ + "vabal", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_VFP_DATA_SIZE, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"q","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_n,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_m,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_VABAL; + + /* pcode: if size == '11' then SEE "Advanced SIMD Data Proc" */ + if((res->fields[FIELD_size]) == (0x3)) { + + return advanced_simd_data_proc(req, res); + } + /* pcode: if Vd<0> == '1' then UNDEFINED */ + if(((res->fields[FIELD_Vd] & 1)) == (0x1)) { + res->status |= STATUS_UNDEFINED; + } + /* pcode: unsigned = (U == '1') */ + res->fields[FIELD_unsigned] = ((res->fields[FIELD_U]) == (0x1)); + res->fields_mask[FIELD_unsigned >> 6] |= 1LL << (FIELD_unsigned & 63); + /* pcode: long_destination = TRUE */ + res->fields[FIELD_long_destination] = 1; + res->fields_mask[FIELD_long_destination >> 6] |= 1LL << (FIELD_long_destination & 63); + /* pcode: esize = 9 << UInt(size) */ + res->fields[FIELD_esize] = (9) << ((res->fields[FIELD_size])); + res->fields_mask[FIELD_esize >> 6] |= 1LL << (FIELD_esize & 63); + /* pcode: elements = 64 DIV esize */ + res->fields[FIELD_elements] = ((res->fields[FIELD_esize]) ? ((64) / (res->fields[FIELD_esize])) : 0); + res->fields_mask[FIELD_elements >> 6] |= 1LL << (FIELD_elements & 63); + /* pcode: d = UInt(D:Vd) */ + res->fields[FIELD_d] = ((res->fields[FIELD_D]<<Vd_width)|(res->fields[FIELD_Vd])); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: n = UInt(N:Vn) */ + res->fields[FIELD_n] = ((res->fields[FIELD_N]<<Vn_width)|(res->fields[FIELD_Vn])); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: m = UInt(M:Vm) */ + res->fields[FIELD_m] = ((res->fields[FIELD_M]<<Vm_width)|(res->fields[FIELD_Vm])); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + /* pcode: regs = 1 */ + res->fields[FIELD_regs] = 1; + res->fields_mask[FIELD_regs >> 6] |= 1LL << (FIELD_regs & 63); + /* pcode: dt = UInt(U:size) */ + res->fields[FIELD_dt] = ((res->fields[FIELD_U]<<size_width)|(res->fields[FIELD_size])); + res->fields_mask[FIELD_dt >> 6] |= 1LL << (FIELD_dt & 63); + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: 4B7CFAE1 +int vabd_float(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + /* Encoding T1 */ + /* pattern="1111,1111,0,D.1,1,sz.1,Vn.4,Vd.4,1101,N.1,Q.1,M.1,0,Vm.4" width=32 stringency=20 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFFA00F10)==0xFF200D00)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ADVSIMD)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_D] = (instr & 0x400000)>>22; + res->fields_mask[FIELD_D >> 6] |= 1LL << (FIELD_D & 63); + char D_width = 1; + res->fields[FIELD_sz] = (instr & 0x100000)>>20; + res->fields_mask[FIELD_sz >> 6] |= 1LL << (FIELD_sz & 63); + char sz_width = 1; + res->fields[FIELD_Vn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Vn >> 6] |= 1LL << (FIELD_Vn & 63); + char Vn_width = 4; + res->fields[FIELD_Vd] = (instr & 0xF000)>>12; + res->fields_mask[FIELD_Vd >> 6] |= 1LL << (FIELD_Vd & 63); + char Vd_width = 4; + res->fields[FIELD_N] = (instr & 0x80)>>7; + res->fields_mask[FIELD_N >> 6] |= 1LL << (FIELD_N & 63); + char N_width = 1; + res->fields[FIELD_Q] = (instr & 0x40)>>6; + res->fields_mask[FIELD_Q >> 6] |= 1LL << (FIELD_Q & 63); + char Q_width = 1; + res->fields[FIELD_M] = (instr & 0x20)>>5; + res->fields_mask[FIELD_M >> 6] |= 1LL << (FIELD_M & 63); + char M_width = 1; + res->fields[FIELD_Vm] = instr & 0xF; + res->fields_mask[FIELD_Vm >> 6] |= 1LL << (FIELD_Vm & 63); + char Vm_width = 4; + + static const instruction_format instr_formats[] = + { + { /* VABD<c>.F32 <Dd>,<Dn>,<Dm> */ + "vabd.f32", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_F32, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_n,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_m,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + { /* VABD<c>.F32 <Qd>,<Qn>,<Qm> */ + "vabd.f32", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_F32, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"q","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_n,FIELD_UNINIT,"q","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_m,FIELD_UNINIT,"q","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 2; + res->mnem = armv7::ARMV7_VABD; + + /* pcode: if Q == '1' && (Vd<0> == '1' || Vn<0> == '1' || Vm<0> == '1') then UNDEFINED */ + if(((res->fields[FIELD_Q]) == (0x1)) && ((((((res->fields[FIELD_Vd] & 1)) == (0x1)) || (((res->fields[FIELD_Vn] & 1)) == (0x1))) || (((res->fields[FIELD_Vm] & 1)) == (0x1))))) { + res->status |= STATUS_UNDEFINED; + } + /* pcode: if sz == '1' then UNDEFINED */ + if((res->fields[FIELD_sz]) == (0x1)) { + res->status |= STATUS_UNDEFINED; + } + /* pcode: esize = 32 */ + res->fields[FIELD_esize] = 32; + res->fields_mask[FIELD_esize >> 6] |= 1LL << (FIELD_esize & 63); + /* pcode: elements = 2 */ + res->fields[FIELD_elements] = 2; + res->fields_mask[FIELD_elements >> 6] |= 1LL << (FIELD_elements & 63); + /* pcode: d = UInt(D:Vd) */ + res->fields[FIELD_d] = ((res->fields[FIELD_D]<<Vd_width)|(res->fields[FIELD_Vd])); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: n = UInt(N:Vn) */ + res->fields[FIELD_n] = ((res->fields[FIELD_N]<<Vn_width)|(res->fields[FIELD_Vn])); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: m = UInt(M:Vm) */ + res->fields[FIELD_m] = ((res->fields[FIELD_M]<<Vm_width)|(res->fields[FIELD_Vm])); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + /* pcode: regs = if Q == '0' then 1 else 2 */ + if((res->fields[FIELD_Q]) == (0x0)) { + res->fields[FIELD_regs] = 1; + res->fields_mask[FIELD_regs >> 6] |= 1LL << (FIELD_regs & 63); + } + else { + res->fields[FIELD_regs] = 2; + res->fields_mask[FIELD_regs >> 6] |= 1LL << (FIELD_regs & 63); + } + /* pcode: fmt_idx = Q == '1' */ + res->fields[FIELD_fmt_idx] = (res->fields[FIELD_Q]) == (0x1); + res->fields_mask[FIELD_fmt_idx >> 6] |= 1LL << (FIELD_fmt_idx & 63); + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: 5ECC2849 +int vabd_integer(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + res->group = INSN_GROUP_NEON; + /* Encoding T1 */ + /* pattern="111,U.1,1111,0,D.1,size.2,Vn.4,Vd.4,0111,N.1,Q.1,M.1,0,Vm.4" width=32 stringency=18 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xEF800F10)==0xEF000700)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ADVSIMD)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_U] = (instr & 0x10000000)>>28; + res->fields_mask[FIELD_U >> 6] |= 1LL << (FIELD_U & 63); + char U_width = 1; + res->fields[FIELD_D] = (instr & 0x400000)>>22; + res->fields_mask[FIELD_D >> 6] |= 1LL << (FIELD_D & 63); + char D_width = 1; + res->fields[FIELD_size] = (instr & 0x300000)>>20; + res->fields_mask[FIELD_size >> 6] |= 1LL << (FIELD_size & 63); + char size_width = 2; + res->fields[FIELD_Vn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Vn >> 6] |= 1LL << (FIELD_Vn & 63); + char Vn_width = 4; + res->fields[FIELD_Vd] = (instr & 0xF000)>>12; + res->fields_mask[FIELD_Vd >> 6] |= 1LL << (FIELD_Vd & 63); + char Vd_width = 4; + res->fields[FIELD_N] = (instr & 0x80)>>7; + res->fields_mask[FIELD_N >> 6] |= 1LL << (FIELD_N & 63); + char N_width = 1; + res->fields[FIELD_Q] = (instr & 0x40)>>6; + res->fields_mask[FIELD_Q >> 6] |= 1LL << (FIELD_Q & 63); + char Q_width = 1; + res->fields[FIELD_M] = (instr & 0x20)>>5; + res->fields_mask[FIELD_M >> 6] |= 1LL << (FIELD_M & 63); + char M_width = 1; + res->fields[FIELD_Vm] = instr & 0xF; + res->fields_mask[FIELD_Vm >> 6] |= 1LL << (FIELD_Vm & 63); + char Vm_width = 4; + + static const instruction_format instr_formats[] = + { + { /* VABD<c>.<dt> <Dd>,<Dn>,<Dm> */ + "vabd", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_VFP_DATA_SIZE, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_n,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_m,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + { /* VABD<c>.<dt> <Qd>,<Qn>,<Qm> */ + "vabd", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_VFP_DATA_SIZE, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"q","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_n,FIELD_UNINIT,"q","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_m,FIELD_UNINIT,"q","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 2; + res->mnem = armv7::ARMV7_VABD; + + /* pcode: if size == '11' then UNDEFINED */ + if((res->fields[FIELD_size]) == (0x3)) { + res->status |= STATUS_UNDEFINED; + } + /* pcode: if Q == '1' && (Vd<0> == '1' || Vn<0> == '1' || Vm<0> == '1') then UNDEFINED */ + if(((res->fields[FIELD_Q]) == (0x1)) && ((((((res->fields[FIELD_Vd] & 1)) == (0x1)) || (((res->fields[FIELD_Vn] & 1)) == (0x1))) || (((res->fields[FIELD_Vm] & 1)) == (0x1))))) { + res->status |= STATUS_UNDEFINED; + } + /* pcode: unsigned = (U == '1') */ + res->fields[FIELD_unsigned] = ((res->fields[FIELD_U]) == (0x1)); + res->fields_mask[FIELD_unsigned >> 6] |= 1LL << (FIELD_unsigned & 63); + /* pcode: long_destination = FALSE */ + res->fields[FIELD_long_destination] = 0; + res->fields_mask[FIELD_long_destination >> 6] |= 1LL << (FIELD_long_destination & 63); + /* pcode: esize = 8 << UInt(size) */ + res->fields[FIELD_esize] = (8) << ((res->fields[FIELD_size])); + res->fields_mask[FIELD_esize >> 6] |= 1LL << (FIELD_esize & 63); + /* pcode: elements = 64 DIV esize */ + res->fields[FIELD_elements] = ((res->fields[FIELD_esize]) ? ((64) / (res->fields[FIELD_esize])) : 0); + res->fields_mask[FIELD_elements >> 6] |= 1LL << (FIELD_elements & 63); + /* pcode: d = UInt(D:Vd) */ + res->fields[FIELD_d] = ((res->fields[FIELD_D]<<Vd_width)|(res->fields[FIELD_Vd])); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: n = UInt(N:Vn) */ + res->fields[FIELD_n] = ((res->fields[FIELD_N]<<Vn_width)|(res->fields[FIELD_Vn])); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: m = UInt(M:Vm) */ + res->fields[FIELD_m] = ((res->fields[FIELD_M]<<Vm_width)|(res->fields[FIELD_Vm])); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + /* pcode: regs = if Q == '0' then 1 else 2 */ + if((res->fields[FIELD_Q]) == (0x0)) { + res->fields[FIELD_regs] = 1; + res->fields_mask[FIELD_regs >> 6] |= 1LL << (FIELD_regs & 63); + } + else { + res->fields[FIELD_regs] = 2; + res->fields_mask[FIELD_regs >> 6] |= 1LL << (FIELD_regs & 63); + } + /* pcode: dt = UInt(U:size) */ + res->fields[FIELD_dt] = ((res->fields[FIELD_U]<<size_width)|(res->fields[FIELD_size])); + res->fields_mask[FIELD_dt >> 6] |= 1LL << (FIELD_dt & 63); + /* pcode: fmt_idx = Q=='1' */ + res->fields[FIELD_fmt_idx] = (res->fields[FIELD_Q]) == (0x1); + res->fields_mask[FIELD_fmt_idx >> 6] |= 1LL << (FIELD_fmt_idx & 63); + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* Encoding T2 */ + /* pattern="111,U.1,1111,1,D.1,size.2,Vn.4,Vd.4,0111,N.1,0,M.1,0,Vm.4" width=32 stringency=18 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xEF800F50)==0xEF800700)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ADVSIMD)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_U] = (instr & 0x10000000)>>28; + res->fields_mask[FIELD_U >> 6] |= 1LL << (FIELD_U & 63); + char U_width = 1; + res->fields[FIELD_D] = (instr & 0x400000)>>22; + res->fields_mask[FIELD_D >> 6] |= 1LL << (FIELD_D & 63); + char D_width = 1; + res->fields[FIELD_size] = (instr & 0x300000)>>20; + res->fields_mask[FIELD_size >> 6] |= 1LL << (FIELD_size & 63); + char size_width = 2; + res->fields[FIELD_Vn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Vn >> 6] |= 1LL << (FIELD_Vn & 63); + char Vn_width = 4; + res->fields[FIELD_Vd] = (instr & 0xF000)>>12; + res->fields_mask[FIELD_Vd >> 6] |= 1LL << (FIELD_Vd & 63); + char Vd_width = 4; + res->fields[FIELD_N] = (instr & 0x80)>>7; + res->fields_mask[FIELD_N >> 6] |= 1LL << (FIELD_N & 63); + char N_width = 1; + res->fields[FIELD_M] = (instr & 0x20)>>5; + res->fields_mask[FIELD_M >> 6] |= 1LL << (FIELD_M & 63); + char M_width = 1; + res->fields[FIELD_Vm] = instr & 0xF; + res->fields_mask[FIELD_Vm >> 6] |= 1LL << (FIELD_Vm & 63); + char Vm_width = 4; + + static const instruction_format instr_formats[] = + { + { /* VABDL<c>.<dt> <Qd>,<Dn>,<Dm> */ + "vabdl", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_VFP_DATA_SIZE, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"q","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_n,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_m,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_VABDL; + + /* pcode: if size == '11' then SEE "Advanced SIMD Data Proc" */ + if((res->fields[FIELD_size]) == (0x3)) { + + return advanced_simd_data_proc(req, res); + } + /* pcode: if Vd<0> == '1' then UNDEFINED */ + if(((res->fields[FIELD_Vd] & 1)) == (0x1)) { + res->status |= STATUS_UNDEFINED; + } + /* pcode: unsigned = (U == '1') */ + res->fields[FIELD_unsigned] = ((res->fields[FIELD_U]) == (0x1)); + res->fields_mask[FIELD_unsigned >> 6] |= 1LL << (FIELD_unsigned & 63); + /* pcode: long_destination = TRUE */ + res->fields[FIELD_long_destination] = 1; + res->fields_mask[FIELD_long_destination >> 6] |= 1LL << (FIELD_long_destination & 63); + /* pcode: esize = 8 << UInt(size) */ + res->fields[FIELD_esize] = (8) << ((res->fields[FIELD_size])); + res->fields_mask[FIELD_esize >> 6] |= 1LL << (FIELD_esize & 63); + /* pcode: elements = 64 DIV esize */ + res->fields[FIELD_elements] = ((res->fields[FIELD_esize]) ? ((64) / (res->fields[FIELD_esize])) : 0); + res->fields_mask[FIELD_elements >> 6] |= 1LL << (FIELD_elements & 63); + /* pcode: d = UInt(D:Vd) */ + res->fields[FIELD_d] = ((res->fields[FIELD_D]<<Vd_width)|(res->fields[FIELD_Vd])); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: n = UInt(N:Vn) */ + res->fields[FIELD_n] = ((res->fields[FIELD_N]<<Vn_width)|(res->fields[FIELD_Vn])); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: m = UInt(M:Vm) */ + res->fields[FIELD_m] = ((res->fields[FIELD_M]<<Vm_width)|(res->fields[FIELD_Vm])); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + /* pcode: dt = UInt(U:size) */ + res->fields[FIELD_dt] = ((res->fields[FIELD_U]<<size_width)|(res->fields[FIELD_size])); + res->fields_mask[FIELD_dt >> 6] |= 1LL << (FIELD_dt & 63); + /* pcode: regs = 1 */ + res->fields[FIELD_regs] = 1; + res->fields_mask[FIELD_regs >> 6] |= 1LL << (FIELD_regs & 63); + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: 856F0E52 +int vabs(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + res->group = INSN_GROUP_NEON; + /* Encoding T2 */ + /* pattern="1110,11101,D.1,11,0000,Vd.4,101,sz.1,1,1,M.1,0,Vm.4" width=32 stringency=24 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFFBF0ED0)==0xEEB00AC0)) { + res->instrSize = 32; + if(!(req->arch & ARCH_VFPv2) && !(req->arch & ARCH_VFPv3)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_D] = (instr & 0x400000)>>22; + res->fields_mask[FIELD_D >> 6] |= 1LL << (FIELD_D & 63); + char D_width = 1; + res->fields[FIELD_Vd] = (instr & 0xF000)>>12; + res->fields_mask[FIELD_Vd >> 6] |= 1LL << (FIELD_Vd & 63); + char Vd_width = 4; + res->fields[FIELD_sz] = (instr & 0x100)>>8; + res->fields_mask[FIELD_sz >> 6] |= 1LL << (FIELD_sz & 63); + char sz_width = 1; + res->fields[FIELD_M] = (instr & 0x20)>>5; + res->fields_mask[FIELD_M >> 6] |= 1LL << (FIELD_M & 63); + char M_width = 1; + res->fields[FIELD_Vm] = instr & 0xF; + res->fields_mask[FIELD_Vm >> 6] |= 1LL << (FIELD_Vm & 63); + char Vm_width = 4; + + static const instruction_format instr_formats[] = + { + { /* VABS<c>.F32 <Sd>,<Sm> */ + "vabs.f32", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_F32, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"s","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_m,FIELD_UNINIT,"s","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + { /* VABS<c>.F64 <Dd>,<Dm> */ + "vabs.f64", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_F64, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_m,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 2; + res->mnem = armv7::ARMV7_VABS; + + /* pcode: advsimd = FALSE */ + res->fields[FIELD_advsimd] = 0; + res->fields_mask[FIELD_advsimd >> 6] |= 1LL << (FIELD_advsimd & 63); + /* pcode: dp_operation = (sz == '1') */ + res->fields[FIELD_dp_operation] = ((res->fields[FIELD_sz]) == (0x1)); + res->fields_mask[FIELD_dp_operation >> 6] |= 1LL << (FIELD_dp_operation & 63); + /* pcode: d = if dp_operation then UInt(D:Vd) else UInt(Vd:D) */ + if(res->fields[FIELD_dp_operation]) { + res->fields[FIELD_d] = ((res->fields[FIELD_D]<<Vd_width)|(res->fields[FIELD_Vd])); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + } + else { + res->fields[FIELD_d] = ((res->fields[FIELD_Vd]<<D_width)|(res->fields[FIELD_D])); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + } + /* pcode: m = if dp_operation then UInt(M:Vm) else UInt(Vm:M) */ + if(res->fields[FIELD_dp_operation]) { + res->fields[FIELD_m] = ((res->fields[FIELD_M]<<Vm_width)|(res->fields[FIELD_Vm])); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + } + else { + res->fields[FIELD_m] = ((res->fields[FIELD_Vm]<<M_width)|(res->fields[FIELD_M])); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + } + /* pcode: fmt_idx = (dp_operation == '1') */ + res->fields[FIELD_fmt_idx] = ((res->fields[FIELD_dp_operation]) == (0x1)); + res->fields_mask[FIELD_fmt_idx >> 6] |= 1LL << (FIELD_fmt_idx & 63); + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* Encoding T1 */ + /* pattern="1111,xx11,1,D.1,11,size.2,01,Vd.4,0,F.1,110,Q.1,M.1,0,Vm.4" width=32 stringency=20 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xF3B30B90)==0xF3B10300)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ADVSIMD)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_D] = (instr & 0x400000)>>22; + res->fields_mask[FIELD_D >> 6] |= 1LL << (FIELD_D & 63); + char D_width = 1; + res->fields[FIELD_size] = (instr & 0xC0000)>>18; + res->fields_mask[FIELD_size >> 6] |= 1LL << (FIELD_size & 63); + char size_width = 2; + res->fields[FIELD_Vd] = (instr & 0xF000)>>12; + res->fields_mask[FIELD_Vd >> 6] |= 1LL << (FIELD_Vd & 63); + char Vd_width = 4; + res->fields[FIELD_F] = (instr & 0x400)>>10; + res->fields_mask[FIELD_F >> 6] |= 1LL << (FIELD_F & 63); + char F_width = 1; + res->fields[FIELD_Q] = (instr & 0x40)>>6; + res->fields_mask[FIELD_Q >> 6] |= 1LL << (FIELD_Q & 63); + char Q_width = 1; + res->fields[FIELD_M] = (instr & 0x20)>>5; + res->fields_mask[FIELD_M >> 6] |= 1LL << (FIELD_M & 63); + char M_width = 1; + res->fields[FIELD_Vm] = instr & 0xF; + res->fields_mask[FIELD_Vm >> 6] |= 1LL << (FIELD_Vm & 63); + char Vm_width = 4; + + static const instruction_format instr_formats[] = + { + { /* VABS<c>.<dt> <Dd>,<Dm> */ + "vabs", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_VFP_DATA_SIZE, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_m,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + { /* VABS<c>.<dt> <Qd>,<Qm> */ + "vabs", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_VFP_DATA_SIZE, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"q","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_m,FIELD_UNINIT,"q","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 2; + res->mnem = armv7::ARMV7_VABS; + + /* pcode: nop */ + while(0); + /* pcode: fmt_idx = (Q=='1') */ + res->fields[FIELD_fmt_idx] = ((res->fields[FIELD_Q]) == (0x1)); + res->fields_mask[FIELD_fmt_idx >> 6] |= 1LL << (FIELD_fmt_idx & 63); + /* pcode: if size == '11' || (F == '1' && size != '10') then UNDEFINED */ + if(((res->fields[FIELD_size]) == (0x3)) || ((((res->fields[FIELD_F]) == (0x1)) && ((res->fields[FIELD_size]) != (0x2))))) { + res->status |= STATUS_UNDEFINED; + } + /* pcode: if Q == '1' && (Vd<0> == '1' || Vm<0> == '1') then UNDEFINED */ + if(((res->fields[FIELD_Q]) == (0x1)) && (((((res->fields[FIELD_Vd] & 1)) == (0x1)) || (((res->fields[FIELD_Vm] & 1)) == (0x1))))) { + res->status |= STATUS_UNDEFINED; + } + /* pcode: advsimd = TRUE */ + res->fields[FIELD_advsimd] = 1; + res->fields_mask[FIELD_advsimd >> 6] |= 1LL << (FIELD_advsimd & 63); + /* pcode: floating_point = (F == '1') */ + res->fields[FIELD_floating_point] = ((res->fields[FIELD_F]) == (0x1)); + res->fields_mask[FIELD_floating_point >> 6] |= 1LL << (FIELD_floating_point & 63); + /* pcode: esize = 8 << UInt(size) */ + res->fields[FIELD_esize] = (8) << ((res->fields[FIELD_size])); + res->fields_mask[FIELD_esize >> 6] |= 1LL << (FIELD_esize & 63); + /* pcode: elements = 64 DIV esize */ + res->fields[FIELD_elements] = ((res->fields[FIELD_esize]) ? ((64) / (res->fields[FIELD_esize])) : 0); + res->fields_mask[FIELD_elements >> 6] |= 1LL << (FIELD_elements & 63); + /* pcode: d = UInt(D:Vd) */ + res->fields[FIELD_d] = ((res->fields[FIELD_D]<<Vd_width)|(res->fields[FIELD_Vd])); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: m = UInt(M:Vm) */ + res->fields[FIELD_m] = ((res->fields[FIELD_M]<<Vm_width)|(res->fields[FIELD_Vm])); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + /* pcode: regs = if Q == '0' then 1 else 2 */ + if((res->fields[FIELD_Q]) == (0x0)) { + res->fields[FIELD_regs] = 1; + res->fields_mask[FIELD_regs >> 6] |= 1LL << (FIELD_regs & 63); + } + else { + res->fields[FIELD_regs] = 2; + res->fields_mask[FIELD_regs >> 6] |= 1LL << (FIELD_regs & 63); + } + /* pcode: dt = size+F */ + res->fields[FIELD_dt] = (res->fields[FIELD_size]) + (res->fields[FIELD_F]); + res->fields_mask[FIELD_dt >> 6] |= 1LL << (FIELD_dt & 63); + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: 2E99FD53 +int vacge(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + res->group = INSN_GROUP_NEON; + /* Encoding T1 */ + /* pattern="1111,1111,0,D.1,op.1,sz.1,Vn.4,Vd.4,1110,N.1,Q.1,M.1,1,Vm.4" width=32 stringency=20 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFF800F10)==0xFF000E10)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ADVSIMD)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_D] = (instr & 0x400000)>>22; + res->fields_mask[FIELD_D >> 6] |= 1LL << (FIELD_D & 63); + char D_width = 1; + res->fields[FIELD_op] = (instr & 0x200000)>>21; + res->fields_mask[FIELD_op >> 6] |= 1LL << (FIELD_op & 63); + char op_width = 1; + res->fields[FIELD_sz] = (instr & 0x100000)>>20; + res->fields_mask[FIELD_sz >> 6] |= 1LL << (FIELD_sz & 63); + char sz_width = 1; + res->fields[FIELD_Vn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Vn >> 6] |= 1LL << (FIELD_Vn & 63); + char Vn_width = 4; + res->fields[FIELD_Vd] = (instr & 0xF000)>>12; + res->fields_mask[FIELD_Vd >> 6] |= 1LL << (FIELD_Vd & 63); + char Vd_width = 4; + res->fields[FIELD_N] = (instr & 0x80)>>7; + res->fields_mask[FIELD_N >> 6] |= 1LL << (FIELD_N & 63); + char N_width = 1; + res->fields[FIELD_Q] = (instr & 0x40)>>6; + res->fields_mask[FIELD_Q >> 6] |= 1LL << (FIELD_Q & 63); + char Q_width = 1; + res->fields[FIELD_M] = (instr & 0x20)>>5; + res->fields_mask[FIELD_M >> 6] |= 1LL << (FIELD_M & 63); + char M_width = 1; + res->fields[FIELD_Vm] = instr & 0xF; + res->fields_mask[FIELD_Vm >> 6] |= 1LL << (FIELD_Vm & 63); + char Vm_width = 4; + + static const instruction_format instr_formats[] = + { + { /* VACGE<c>.F32 <Dd>,<Dn>,<Dm> */ + "vacge.f32", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_F32, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_n,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_m,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + { /* VACGE<c>.F32 <Qd>,<Qn>,<Qm> */ + "vacge.f32", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_F32, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"q","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_n,FIELD_UNINIT,"q","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_m,FIELD_UNINIT,"q","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + { /* VACGT<c>.F32 <Dd>,<Dn>,<Dm> */ + "vacgt.f32", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_F32, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_n,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_m,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + { /* VACGT<c>.F32 <Qd>,<Qn>,<Qm> */ + "vacgt.f32", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_F32, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"q","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_n,FIELD_UNINIT,"q","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_m,FIELD_UNINIT,"q","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 4; + res->mnem = armv7::ARMV7_VACGE; + + /* pcode: if (Q == '1' && (Vd<0> == '1' || Vn<0> == '1' || Vm<0> == '1')) then UNDEFINED */ + if((((res->fields[FIELD_Q]) == (0x1)) && ((((((res->fields[FIELD_Vd] & 1)) == (0x1)) || (((res->fields[FIELD_Vn] & 1)) == (0x1))) || (((res->fields[FIELD_Vm] & 1)) == (0x1)))))) { + res->status |= STATUS_UNDEFINED; + } + /* pcode: if sz == '1' then UNDEFINED */ + if((res->fields[FIELD_sz]) == (0x1)) { + res->status |= STATUS_UNDEFINED; + } + /* pcode: esize = 32 */ + res->fields[FIELD_esize] = 32; + res->fields_mask[FIELD_esize >> 6] |= 1LL << (FIELD_esize & 63); + /* pcode: elements = 2 */ + res->fields[FIELD_elements] = 2; + res->fields_mask[FIELD_elements >> 6] |= 1LL << (FIELD_elements & 63); + /* pcode: d = UInt(D:Vd) */ + res->fields[FIELD_d] = ((res->fields[FIELD_D]<<Vd_width)|(res->fields[FIELD_Vd])); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: n = UInt(N:Vn) */ + res->fields[FIELD_n] = ((res->fields[FIELD_N]<<Vn_width)|(res->fields[FIELD_Vn])); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: m = UInt(M:Vm) */ + res->fields[FIELD_m] = ((res->fields[FIELD_M]<<Vm_width)|(res->fields[FIELD_Vm])); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + /* pcode: regs = if Q == '0' then 1 else 2 */ + if((res->fields[FIELD_Q]) == (0x0)) { + res->fields[FIELD_regs] = 1; + res->fields_mask[FIELD_regs >> 6] |= 1LL << (FIELD_regs & 63); + } + else { + res->fields[FIELD_regs] = 2; + res->fields_mask[FIELD_regs >> 6] |= 1LL << (FIELD_regs & 63); + } + /* pcode: fmt_idx = (op == '1') */ + res->fields[FIELD_fmt_idx] = ((res->fields[FIELD_op]) == (0x1)); + res->fields_mask[FIELD_fmt_idx >> 6] |= 1LL << (FIELD_fmt_idx & 63); + /* pcode: fmt_idx = fmt_idx + fmt_idx */ + res->fields[FIELD_fmt_idx] = (res->fields[FIELD_fmt_idx]) + (res->fields[FIELD_fmt_idx]); + res->fields_mask[FIELD_fmt_idx >> 6] |= 1LL << (FIELD_fmt_idx & 63); + /* pcode: fmt_idx = fmt_idx + (Q == '1') */ + res->fields[FIELD_fmt_idx] = (res->fields[FIELD_fmt_idx]) + (((res->fields[FIELD_Q]) == (0x1))); + res->fields_mask[FIELD_fmt_idx >> 6] |= 1LL << (FIELD_fmt_idx & 63); + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: 9383D61E +int vadd_float(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + res->group = INSN_GROUP_NEON; + /* Encoding T1 */ + /* pattern="111x,xx11,0,D.1,0,sz.1,Vn.4,Vd.4,1101,N.1,Q.1,M.1,0,Vm.4" width=32 stringency=17 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xE3A00F10)==0xE3000D00)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ADVSIMD)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_D] = (instr & 0x400000)>>22; + res->fields_mask[FIELD_D >> 6] |= 1LL << (FIELD_D & 63); + char D_width = 1; + res->fields[FIELD_sz] = (instr & 0x100000)>>20; + res->fields_mask[FIELD_sz >> 6] |= 1LL << (FIELD_sz & 63); + char sz_width = 1; + res->fields[FIELD_Vn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Vn >> 6] |= 1LL << (FIELD_Vn & 63); + char Vn_width = 4; + res->fields[FIELD_Vd] = (instr & 0xF000)>>12; + res->fields_mask[FIELD_Vd >> 6] |= 1LL << (FIELD_Vd & 63); + char Vd_width = 4; + res->fields[FIELD_N] = (instr & 0x80)>>7; + res->fields_mask[FIELD_N >> 6] |= 1LL << (FIELD_N & 63); + char N_width = 1; + res->fields[FIELD_Q] = (instr & 0x40)>>6; + res->fields_mask[FIELD_Q >> 6] |= 1LL << (FIELD_Q & 63); + char Q_width = 1; + res->fields[FIELD_M] = (instr & 0x20)>>5; + res->fields_mask[FIELD_M >> 6] |= 1LL << (FIELD_M & 63); + char M_width = 1; + res->fields[FIELD_Vm] = instr & 0xF; + res->fields_mask[FIELD_Vm >> 6] |= 1LL << (FIELD_Vm & 63); + char Vm_width = 4; + + static const instruction_format instr_formats[] = + { + { /* VADD<c>.F32 <Dd>,<Dn>,<Dm> */ + "vadd.f32", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_F32, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_n,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_m,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + { /* VADD<c>.F32 <Qd>,<Qn>,<Qm> */ + "vadd.f32", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_F32, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"q","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_n,FIELD_UNINIT,"q","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_m,FIELD_UNINIT,"q","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 2; + res->mnem = armv7::ARMV7_VADD; + + /* pcode: if Q == '1' && (Vd<0> == '1' || Vn<0> == '1' || Vm<0> == '1') then UNDEFINED */ + if(((res->fields[FIELD_Q]) == (0x1)) && ((((((res->fields[FIELD_Vd] & 1)) == (0x1)) || (((res->fields[FIELD_Vn] & 1)) == (0x1))) || (((res->fields[FIELD_Vm] & 1)) == (0x1))))) { + res->status |= STATUS_UNDEFINED; + } + /* pcode: if sz == '1' then UNDEFINED */ + if((res->fields[FIELD_sz]) == (0x1)) { + res->status |= STATUS_UNDEFINED; + } + /* pcode: advsimd = TRUE */ + res->fields[FIELD_advsimd] = 1; + res->fields_mask[FIELD_advsimd >> 6] |= 1LL << (FIELD_advsimd & 63); + /* pcode: esize = 32 */ + res->fields[FIELD_esize] = 32; + res->fields_mask[FIELD_esize >> 6] |= 1LL << (FIELD_esize & 63); + /* pcode: elements = 2 */ + res->fields[FIELD_elements] = 2; + res->fields_mask[FIELD_elements >> 6] |= 1LL << (FIELD_elements & 63); + /* pcode: d = UInt(D:Vd) */ + res->fields[FIELD_d] = ((res->fields[FIELD_D]<<Vd_width)|(res->fields[FIELD_Vd])); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: n = UInt(N:Vn) */ + res->fields[FIELD_n] = ((res->fields[FIELD_N]<<Vn_width)|(res->fields[FIELD_Vn])); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: m = UInt(M:Vm) */ + res->fields[FIELD_m] = ((res->fields[FIELD_M]<<Vm_width)|(res->fields[FIELD_Vm])); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + /* pcode: regs = if Q == '0' then 1 else 2 */ + if((res->fields[FIELD_Q]) == (0x0)) { + res->fields[FIELD_regs] = 1; + res->fields_mask[FIELD_regs >> 6] |= 1LL << (FIELD_regs & 63); + } + else { + res->fields[FIELD_regs] = 2; + res->fields_mask[FIELD_regs >> 6] |= 1LL << (FIELD_regs & 63); + } + /* pcode: fmt_idx = (Q == '1') */ + res->fields[FIELD_fmt_idx] = ((res->fields[FIELD_Q]) == (0x1)); + res->fields_mask[FIELD_fmt_idx >> 6] |= 1LL << (FIELD_fmt_idx & 63); + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* Encoding T2 */ + /* pattern="cond.4,11100,D.1,11,Vn.4,Vd.4,101,sz.1,N.1,0,M.1,0,Vm.4" width=32 stringency=16 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFB00E50)==0xE300A00)) { + res->instrSize = 32; + if(!(req->arch & ARCH_VFPv2) && !(req->arch & ARCH_VFPv3)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = (instr & 0xF0000000)>>28; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + char cond_width = 4; + res->fields[FIELD_D] = (instr & 0x400000)>>22; + res->fields_mask[FIELD_D >> 6] |= 1LL << (FIELD_D & 63); + char D_width = 1; + res->fields[FIELD_Vn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Vn >> 6] |= 1LL << (FIELD_Vn & 63); + char Vn_width = 4; + res->fields[FIELD_Vd] = (instr & 0xF000)>>12; + res->fields_mask[FIELD_Vd >> 6] |= 1LL << (FIELD_Vd & 63); + char Vd_width = 4; + res->fields[FIELD_sz] = (instr & 0x100)>>8; + res->fields_mask[FIELD_sz >> 6] |= 1LL << (FIELD_sz & 63); + char sz_width = 1; + res->fields[FIELD_N] = (instr & 0x80)>>7; + res->fields_mask[FIELD_N >> 6] |= 1LL << (FIELD_N & 63); + char N_width = 1; + res->fields[FIELD_M] = (instr & 0x20)>>5; + res->fields_mask[FIELD_M >> 6] |= 1LL << (FIELD_M & 63); + char M_width = 1; + res->fields[FIELD_Vm] = instr & 0xF; + res->fields_mask[FIELD_Vm >> 6] |= 1LL << (FIELD_Vm & 63); + char Vm_width = 4; + + static const instruction_format instr_formats[] = + { + { /* VADD<c>.F32 <Sd>,<Sn>,<Sm> */ + "vadd.f32", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_F32, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"s","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_n,FIELD_UNINIT,"s","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_m,FIELD_UNINIT,"s","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + { /* VADD<c>.F64 <Dd>,<Dn>,<Dm> */ + "vadd.f64", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_F64, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_n,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_m,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 2; + res->mnem = armv7::ARMV7_VADD; + + /* pcode: advsimd = FALSE */ + res->fields[FIELD_advsimd] = 0; + res->fields_mask[FIELD_advsimd >> 6] |= 1LL << (FIELD_advsimd & 63); + /* pcode: dp_operation = (sz == '1') */ + res->fields[FIELD_dp_operation] = ((res->fields[FIELD_sz]) == (0x1)); + res->fields_mask[FIELD_dp_operation >> 6] |= 1LL << (FIELD_dp_operation & 63); + /* pcode: d = if dp_operation then UInt(D:Vd) else UInt(Vd:D) */ + if(res->fields[FIELD_dp_operation]) { + res->fields[FIELD_d] = ((res->fields[FIELD_D]<<Vd_width)|(res->fields[FIELD_Vd])); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + } + else { + res->fields[FIELD_d] = ((res->fields[FIELD_Vd]<<D_width)|(res->fields[FIELD_D])); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + } + /* pcode: n = if dp_operation then UInt(N:Vn) else UInt(Vn:N) */ + if(res->fields[FIELD_dp_operation]) { + res->fields[FIELD_n] = ((res->fields[FIELD_N]<<Vn_width)|(res->fields[FIELD_Vn])); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + } + else { + res->fields[FIELD_n] = ((res->fields[FIELD_Vn]<<N_width)|(res->fields[FIELD_N])); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + } + /* pcode: m = if dp_operation then UInt(M:Vm) else UInt(Vm:M) */ + if(res->fields[FIELD_dp_operation]) { + res->fields[FIELD_m] = ((res->fields[FIELD_M]<<Vm_width)|(res->fields[FIELD_Vm])); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + } + else { + res->fields[FIELD_m] = ((res->fields[FIELD_Vm]<<M_width)|(res->fields[FIELD_M])); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + } + /* pcode: fmt_idx = (sz == '1') */ + res->fields[FIELD_fmt_idx] = ((res->fields[FIELD_sz]) == (0x1)); + res->fields_mask[FIELD_fmt_idx >> 6] |= 1LL << (FIELD_fmt_idx & 63); + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: 54B500C9 +int vadd_integer(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + res->group = INSN_GROUP_NEON; + /* Encoding T1 */ + /* pattern="111x,xx1x,0,D.1,size.2,Vn.4,Vd.4,1000,N.1,Q.1,M.1,0,Vm.4" width=32 stringency=14 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xE2800F10)==0xE2000800)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ADVSIMD)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_D] = (instr & 0x400000)>>22; + res->fields_mask[FIELD_D >> 6] |= 1LL << (FIELD_D & 63); + char D_width = 1; + res->fields[FIELD_size] = (instr & 0x300000)>>20; + res->fields_mask[FIELD_size >> 6] |= 1LL << (FIELD_size & 63); + char size_width = 2; + res->fields[FIELD_Vn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Vn >> 6] |= 1LL << (FIELD_Vn & 63); + char Vn_width = 4; + res->fields[FIELD_Vd] = (instr & 0xF000)>>12; + res->fields_mask[FIELD_Vd >> 6] |= 1LL << (FIELD_Vd & 63); + char Vd_width = 4; + res->fields[FIELD_N] = (instr & 0x80)>>7; + res->fields_mask[FIELD_N >> 6] |= 1LL << (FIELD_N & 63); + char N_width = 1; + res->fields[FIELD_Q] = (instr & 0x40)>>6; + res->fields_mask[FIELD_Q >> 6] |= 1LL << (FIELD_Q & 63); + char Q_width = 1; + res->fields[FIELD_M] = (instr & 0x20)>>5; + res->fields_mask[FIELD_M >> 6] |= 1LL << (FIELD_M & 63); + char M_width = 1; + res->fields[FIELD_Vm] = instr & 0xF; + res->fields_mask[FIELD_Vm >> 6] |= 1LL << (FIELD_Vm & 63); + char Vm_width = 4; + + static const instruction_format instr_formats[] = + { + { /* VADD<c>.<dt> <Dd>,<Dn>,<Dm> */ + "vadd", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_VFP_DATA_SIZE, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_n,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_m,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + { /* VADD<c>.<dt> <Qd>,<Qn>,<Qm> */ + "vadd", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_VFP_DATA_SIZE, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"q","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_n,FIELD_UNINIT,"q","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_m,FIELD_UNINIT,"q","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 2; + res->mnem = armv7::ARMV7_VADD; + + /* pcode: if Q == '1' && (Vd<0> == '1' || Vn<0> == '1' || Vm<0> == '1') then UNDEFINED */ + if(((res->fields[FIELD_Q]) == (0x1)) && ((((((res->fields[FIELD_Vd] & 1)) == (0x1)) || (((res->fields[FIELD_Vn] & 1)) == (0x1))) || (((res->fields[FIELD_Vm] & 1)) == (0x1))))) { + res->status |= STATUS_UNDEFINED; + } + /* pcode: esize = 8 << UInt(size) */ + res->fields[FIELD_esize] = (8) << ((res->fields[FIELD_size])); + res->fields_mask[FIELD_esize >> 6] |= 1LL << (FIELD_esize & 63); + /* pcode: elements = 64 DIV esize */ + res->fields[FIELD_elements] = ((res->fields[FIELD_esize]) ? ((64) / (res->fields[FIELD_esize])) : 0); + res->fields_mask[FIELD_elements >> 6] |= 1LL << (FIELD_elements & 63); + /* pcode: d = UInt(D:Vd) */ + res->fields[FIELD_d] = ((res->fields[FIELD_D]<<Vd_width)|(res->fields[FIELD_Vd])); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: n = UInt(N:Vn) */ + res->fields[FIELD_n] = ((res->fields[FIELD_N]<<Vn_width)|(res->fields[FIELD_Vn])); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: m = UInt(M:Vm) */ + res->fields[FIELD_m] = ((res->fields[FIELD_M]<<Vm_width)|(res->fields[FIELD_Vm])); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + /* pcode: regs = if Q == '0' then 1 else 2 */ + if((res->fields[FIELD_Q]) == (0x0)) { + res->fields[FIELD_regs] = 1; + res->fields_mask[FIELD_regs >> 6] |= 1LL << (FIELD_regs & 63); + } + else { + res->fields[FIELD_regs] = 2; + res->fields_mask[FIELD_regs >> 6] |= 1LL << (FIELD_regs & 63); + } + /* pcode: iword = TRUE */ + res->fields[FIELD_iword] = 1; + res->fields_mask[FIELD_iword >> 6] |= 1LL << (FIELD_iword & 63); + /* pcode: fmt_idx = (Q == '1') */ + res->fields[FIELD_fmt_idx] = ((res->fields[FIELD_Q]) == (0x1)); + res->fields_mask[FIELD_fmt_idx >> 6] |= 1LL << (FIELD_fmt_idx & 63); + /* pcode: dt = UInt(size) */ + res->fields[FIELD_dt] = (res->fields[FIELD_size]); + res->fields_mask[FIELD_dt >> 6] |= 1LL << (FIELD_dt & 63); + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: 9C731A28 +int vaddhn(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + res->group = INSN_GROUP_NEON; + /* Encoding T1 */ + /* pattern="1110,xx1x,1,D.1,size.2,Vn.4,Vd.4,0100,N.1,0,M.1,0,Vm.4" width=32 stringency=15 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xF2800F50)==0xE2800400)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ADVSIMD)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_D] = (instr & 0x400000)>>22; + res->fields_mask[FIELD_D >> 6] |= 1LL << (FIELD_D & 63); + char D_width = 1; + res->fields[FIELD_size] = (instr & 0x300000)>>20; + res->fields_mask[FIELD_size >> 6] |= 1LL << (FIELD_size & 63); + char size_width = 2; + res->fields[FIELD_Vn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Vn >> 6] |= 1LL << (FIELD_Vn & 63); + char Vn_width = 4; + res->fields[FIELD_Vd] = (instr & 0xF000)>>12; + res->fields_mask[FIELD_Vd >> 6] |= 1LL << (FIELD_Vd & 63); + char Vd_width = 4; + res->fields[FIELD_N] = (instr & 0x80)>>7; + res->fields_mask[FIELD_N >> 6] |= 1LL << (FIELD_N & 63); + char N_width = 1; + res->fields[FIELD_M] = (instr & 0x20)>>5; + res->fields_mask[FIELD_M >> 6] |= 1LL << (FIELD_M & 63); + char M_width = 1; + res->fields[FIELD_Vm] = instr & 0xF; + res->fields_mask[FIELD_Vm >> 6] |= 1LL << (FIELD_Vm & 63); + char Vm_width = 4; + + static const instruction_format instr_formats[] = + { + { /* VADDHN<c>.<dt> <Dd>,<Qn>,<Qm> */ + "vaddhn", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_VFP_DATA_SIZE, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_n,FIELD_UNINIT,"q","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_m,FIELD_UNINIT,"q","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_VADDHN; + + /* pcode: if size == '11' then SEE "Advanced SIMD Data Proc" */ + if((res->fields[FIELD_size]) == (0x3)) { + + return advanced_simd_data_proc(req, res); + } + /* pcode: if Vn<0> == '1' || Vm<0> == '1' then UNDEFINED */ + if((((res->fields[FIELD_Vn] & 1)) == (0x1)) || (((res->fields[FIELD_Vm] & 1)) == (0x1))) { + res->status |= STATUS_UNDEFINED; + } + /* pcode: esize = 8 << UInt(size) */ + res->fields[FIELD_esize] = (8) << ((res->fields[FIELD_size])); + res->fields_mask[FIELD_esize >> 6] |= 1LL << (FIELD_esize & 63); + /* pcode: elements = 64 DIV esize */ + res->fields[FIELD_elements] = ((res->fields[FIELD_esize]) ? ((64) / (res->fields[FIELD_esize])) : 0); + res->fields_mask[FIELD_elements >> 6] |= 1LL << (FIELD_elements & 63); + /* pcode: d = UInt(D:Vd) */ + res->fields[FIELD_d] = ((res->fields[FIELD_D]<<Vd_width)|(res->fields[FIELD_Vd])); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: n = UInt(N:Vn) */ + res->fields[FIELD_n] = ((res->fields[FIELD_N]<<Vn_width)|(res->fields[FIELD_Vn])); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: m = UInt(M:Vm) */ + res->fields[FIELD_m] = ((res->fields[FIELD_M]<<Vm_width)|(res->fields[FIELD_Vm])); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + /* pcode: iword = TRUE */ + res->fields[FIELD_iword] = 1; + res->fields_mask[FIELD_iword >> 6] |= 1LL << (FIELD_iword & 63); + /* pcode: dt = UInt(size+1) */ + res->fields[FIELD_dt] = ((res->fields[FIELD_size]) + (1)); + res->fields_mask[FIELD_dt >> 6] |= 1LL << (FIELD_dt & 63); + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: C747A580 +int vaddlw(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + res->group = INSN_GROUP_NEON; + /* Encoding T1 */ + /* pattern="111,U.1,1111,1,D.1,size.2,Vn.4,Vd.4,000,op.1,N.1,0,M.1,0,Vm.4" width=32 stringency=18 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xEF800E50)==0xEF800000)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ADVSIMD)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_U] = (instr & 0x10000000)>>28; + res->fields_mask[FIELD_U >> 6] |= 1LL << (FIELD_U & 63); + char U_width = 1; + res->fields[FIELD_D] = (instr & 0x400000)>>22; + res->fields_mask[FIELD_D >> 6] |= 1LL << (FIELD_D & 63); + char D_width = 1; + res->fields[FIELD_size] = (instr & 0x300000)>>20; + res->fields_mask[FIELD_size >> 6] |= 1LL << (FIELD_size & 63); + char size_width = 2; + res->fields[FIELD_Vn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Vn >> 6] |= 1LL << (FIELD_Vn & 63); + char Vn_width = 4; + res->fields[FIELD_Vd] = (instr & 0xF000)>>12; + res->fields_mask[FIELD_Vd >> 6] |= 1LL << (FIELD_Vd & 63); + char Vd_width = 4; + res->fields[FIELD_op] = (instr & 0x100)>>8; + res->fields_mask[FIELD_op >> 6] |= 1LL << (FIELD_op & 63); + char op_width = 1; + res->fields[FIELD_N] = (instr & 0x80)>>7; + res->fields_mask[FIELD_N >> 6] |= 1LL << (FIELD_N & 63); + char N_width = 1; + res->fields[FIELD_M] = (instr & 0x20)>>5; + res->fields_mask[FIELD_M >> 6] |= 1LL << (FIELD_M & 63); + char M_width = 1; + res->fields[FIELD_Vm] = instr & 0xF; + res->fields_mask[FIELD_Vm >> 6] |= 1LL << (FIELD_Vm & 63); + char Vm_width = 4; + + static const instruction_format instr_formats[] = + { + { /* VADDL<c>.<dt> <Qd>,<Dn>,<Dm> */ + "vaddl", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_VFP_DATA_SIZE, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"q","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_n,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_m,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + { /* VADDW<c>.<dt> <Qd>,<Qn>,<Dm> */ + "vaddw", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_VFP_DATA_SIZE, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"q","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_n,FIELD_UNINIT,"q","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_m,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 2; + res->mnem = armv7::ARMV7_VADDL; + + /* pcode: if size == '11' then SEE "Advanced SIMD Data Proc" */ + if((res->fields[FIELD_size]) == (0x3)) { + + return advanced_simd_data_proc(req, res); + } + /* pcode: if Vd<0> == '1' || (op == '1' && Vn<0> == '1') then UNDEFINED */ + if((((res->fields[FIELD_Vd] & 1)) == (0x1)) || ((((res->fields[FIELD_op]) == (0x1)) && (((res->fields[FIELD_Vn] & 1)) == (0x1))))) { + res->status |= STATUS_UNDEFINED; + } + /* pcode: unsigned = (U == '1') */ + res->fields[FIELD_unsigned] = ((res->fields[FIELD_U]) == (0x1)); + res->fields_mask[FIELD_unsigned >> 6] |= 1LL << (FIELD_unsigned & 63); + /* pcode: esize = 8 << UInt(size) */ + res->fields[FIELD_esize] = (8) << ((res->fields[FIELD_size])); + res->fields_mask[FIELD_esize >> 6] |= 1LL << (FIELD_esize & 63); + /* pcode: elements = 64 DIV esize */ + res->fields[FIELD_elements] = ((res->fields[FIELD_esize]) ? ((64) / (res->fields[FIELD_esize])) : 0); + res->fields_mask[FIELD_elements >> 6] |= 1LL << (FIELD_elements & 63); + /* pcode: d = UInt(D:Vd) */ + res->fields[FIELD_d] = ((res->fields[FIELD_D]<<Vd_width)|(res->fields[FIELD_Vd])); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: n = UInt(N:Vn) */ + res->fields[FIELD_n] = ((res->fields[FIELD_N]<<Vn_width)|(res->fields[FIELD_Vn])); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: m = UInt(M:Vm) */ + res->fields[FIELD_m] = ((res->fields[FIELD_M]<<Vm_width)|(res->fields[FIELD_Vm])); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + /* pcode: fmt_idx = (op == '1') */ + res->fields[FIELD_fmt_idx] = ((res->fields[FIELD_op]) == (0x1)); + res->fields_mask[FIELD_fmt_idx >> 6] |= 1LL << (FIELD_fmt_idx & 63); + /* pcode: dt = UInt(U:size) */ + res->fields[FIELD_dt] = ((res->fields[FIELD_U]<<size_width)|(res->fields[FIELD_size])); + res->fields_mask[FIELD_dt >> 6] |= 1LL << (FIELD_dt & 63); + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: 06BB6BED +int vand(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + /* Encoding T1 */ + /* pattern="111x,xx1x,0,D.1,00,Vn.4,Vd.4,0001,N.1,Q.1,M.1,1,Vm.4" width=32 stringency=16 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xE2B00F10)==0xE2000110)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ADVSIMD)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_D] = (instr & 0x400000)>>22; + res->fields_mask[FIELD_D >> 6] |= 1LL << (FIELD_D & 63); + char D_width = 1; + res->fields[FIELD_Vn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Vn >> 6] |= 1LL << (FIELD_Vn & 63); + char Vn_width = 4; + res->fields[FIELD_Vd] = (instr & 0xF000)>>12; + res->fields_mask[FIELD_Vd >> 6] |= 1LL << (FIELD_Vd & 63); + char Vd_width = 4; + res->fields[FIELD_N] = (instr & 0x80)>>7; + res->fields_mask[FIELD_N >> 6] |= 1LL << (FIELD_N & 63); + char N_width = 1; + res->fields[FIELD_Q] = (instr & 0x40)>>6; + res->fields_mask[FIELD_Q >> 6] |= 1LL << (FIELD_Q & 63); + char Q_width = 1; + res->fields[FIELD_M] = (instr & 0x20)>>5; + res->fields_mask[FIELD_M >> 6] |= 1LL << (FIELD_M & 63); + char M_width = 1; + res->fields[FIELD_Vm] = instr & 0xF; + res->fields_mask[FIELD_Vm >> 6] |= 1LL << (FIELD_Vm & 63); + char Vm_width = 4; + + static const instruction_format instr_formats[] = + { + { /* VAND<c> <Dd>,<Dn>,<Dm> */ + "vand", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_n,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_m,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + { /* VAND<c> <Qd>,<Qn>,<Qm> */ + "vand", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"q","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_n,FIELD_UNINIT,"q","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_m,FIELD_UNINIT,"q","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 2; + res->mnem = armv7::ARMV7_VAND; + + /* pcode: if Q == '1' && (Vd<0> == '1' || Vn<0> == '1' || Vm<0> == '1') then UNDEFINED */ + if(((res->fields[FIELD_Q]) == (0x1)) && ((((((res->fields[FIELD_Vd] & 1)) == (0x1)) || (((res->fields[FIELD_Vn] & 1)) == (0x1))) || (((res->fields[FIELD_Vm] & 1)) == (0x1))))) { + res->status |= STATUS_UNDEFINED; + } + /* pcode: d = UInt(D:Vd) */ + res->fields[FIELD_d] = ((res->fields[FIELD_D]<<Vd_width)|(res->fields[FIELD_Vd])); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: n = UInt(N:Vn) */ + res->fields[FIELD_n] = ((res->fields[FIELD_N]<<Vn_width)|(res->fields[FIELD_Vn])); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: m = UInt(M:Vm) */ + res->fields[FIELD_m] = ((res->fields[FIELD_M]<<Vm_width)|(res->fields[FIELD_Vm])); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + /* pcode: regs = if Q == '0' then 1 else 2 */ + if((res->fields[FIELD_Q]) == (0x0)) { + res->fields[FIELD_regs] = 1; + res->fields_mask[FIELD_regs >> 6] |= 1LL << (FIELD_regs & 63); + } + else { + res->fields[FIELD_regs] = 2; + res->fields_mask[FIELD_regs >> 6] |= 1LL << (FIELD_regs & 63); + } + /* pcode: fmt_idx = (Q == '1') */ + res->fields[FIELD_fmt_idx] = ((res->fields[FIELD_Q]) == (0x1)); + res->fields_mask[FIELD_fmt_idx >> 6] |= 1LL << (FIELD_fmt_idx & 63); + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: A489C601 +int vbic_immediate(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + /* Encoding T1 */ + /* pattern="111,i.1,1111,1,D.1,000,imm3.3,Vd.4,cmode.4,0,Q.1,1,1,imm4.4" width=32 stringency=17 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xEFB800B0)==0xEF800030)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ADVSIMD)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_i] = (instr & 0x10000000)>>28; + res->fields_mask[FIELD_i >> 6] |= 1LL << (FIELD_i & 63); + char i_width = 1; + res->fields[FIELD_D] = (instr & 0x400000)>>22; + res->fields_mask[FIELD_D >> 6] |= 1LL << (FIELD_D & 63); + char D_width = 1; + res->fields[FIELD_imm3] = (instr & 0x70000)>>16; + res->fields_mask[FIELD_imm3 >> 6] |= 1LL << (FIELD_imm3 & 63); + char imm3_width = 3; + res->fields[FIELD_Vd] = (instr & 0xF000)>>12; + res->fields_mask[FIELD_Vd >> 6] |= 1LL << (FIELD_Vd & 63); + char Vd_width = 4; + res->fields[FIELD_cmode] = (instr & 0xF00)>>8; + res->fields_mask[FIELD_cmode >> 6] |= 1LL << (FIELD_cmode & 63); + char cmode_width = 4; + res->fields[FIELD_Q] = (instr & 0x40)>>6; + res->fields_mask[FIELD_Q >> 6] |= 1LL << (FIELD_Q & 63); + char Q_width = 1; + res->fields[FIELD_imm4] = instr & 0xF; + res->fields_mask[FIELD_imm4 >> 6] |= 1LL << (FIELD_imm4 & 63); + char imm4_width = 4; + + static const instruction_format instr_formats[] = + { + { /* VBIC<c>.<dt> <Dd>,#<imm64> */ + "vbic", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_VFP_DATA_SIZE, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_IMM64,FIELD_UNINIT,FIELD_UNINIT,"#","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + { /* VBIC<c>.<dt> <Qd>,#<imm64> */ + "vbic", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_VFP_DATA_SIZE, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"q","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_IMM64,FIELD_UNINIT,FIELD_UNINIT,"#","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 2; + res->mnem = armv7::ARMV7_VBIC; + + /* pcode: if (cmode<0> == '0') || (cmode<3:2> == '11') then SEE advsimd_one_reg_mod_imm */ + if(((((res->fields[FIELD_cmode] & 1)) == (0x0))) || (((((res->fields[FIELD_cmode] >> 2) & 0x3)) == (0x3)))) { + + return advsimd_one_reg_mod_imm(req, res); + } + /* pcode: if (Q == '1' && Vd<0> == '1') then UNDEFINED */ + if((((res->fields[FIELD_Q]) == (0x1)) && (((res->fields[FIELD_Vd] & 1)) == (0x1)))) { + res->status |= STATUS_UNDEFINED; + } + /* pcode: imm64l = AdvSIMDExpandImm('1', cmode, i:imm3:imm4, 1) */ + res->fields[FIELD_imm64l] = AdvSIMDExpandImm(0x1, res->fields[FIELD_cmode], (res->fields[FIELD_i]<<(4+3))|(res->fields[FIELD_imm3]<<4)|(res->fields[FIELD_imm4]), 1); + res->fields_mask[FIELD_imm64l >> 6] |= 1LL << (FIELD_imm64l & 63); + /* pcode: imm64h = AdvSIMDExpandImm('1', cmode, i:imm3:imm4, 0) */ + res->fields[FIELD_imm64h] = AdvSIMDExpandImm(0x1, res->fields[FIELD_cmode], (res->fields[FIELD_i]<<(4+3))|(res->fields[FIELD_imm3]<<4)|(res->fields[FIELD_imm4]), 0); + res->fields_mask[FIELD_imm64h >> 6] |= 1LL << (FIELD_imm64h & 63); + /* pcode: d = UInt(D:Vd) */ + res->fields[FIELD_d] = ((res->fields[FIELD_D]<<Vd_width)|(res->fields[FIELD_Vd])); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: regs = if Q == '0' then 1 else 2 */ + if((res->fields[FIELD_Q]) == (0x0)) { + res->fields[FIELD_regs] = 1; + res->fields_mask[FIELD_regs >> 6] |= 1LL << (FIELD_regs & 63); + } + else { + res->fields[FIELD_regs] = 2; + res->fields_mask[FIELD_regs >> 6] |= 1LL << (FIELD_regs & 63); + } + /* pcode: iword = TRUE */ + res->fields[FIELD_iword] = 1; + res->fields_mask[FIELD_iword >> 6] |= 1LL << (FIELD_iword & 63); + /* pcode: fmt_idx = (Q == '1') */ + res->fields[FIELD_fmt_idx] = ((res->fields[FIELD_Q]) == (0x1)); + res->fields_mask[FIELD_fmt_idx >> 6] |= 1LL << (FIELD_fmt_idx & 63); + /* pcode: dt = (D == '1') + 1 */ + res->fields[FIELD_dt] = (((res->fields[FIELD_D]) == (0x1))) + (1); + res->fields_mask[FIELD_dt >> 6] |= 1LL << (FIELD_dt & 63); + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: 63975992 +int vbic_register(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + /* Encoding T1 */ + /* pattern="111x,xx1x,0,D.1,01,Vn.4,Vd.4,0001,N.1,Q.1,M.1,1,Vm.4" width=32 stringency=16 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xE2B00F10)==0xE2100110)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ADVSIMD)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_D] = (instr & 0x400000)>>22; + res->fields_mask[FIELD_D >> 6] |= 1LL << (FIELD_D & 63); + char D_width = 1; + res->fields[FIELD_Vn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Vn >> 6] |= 1LL << (FIELD_Vn & 63); + char Vn_width = 4; + res->fields[FIELD_Vd] = (instr & 0xF000)>>12; + res->fields_mask[FIELD_Vd >> 6] |= 1LL << (FIELD_Vd & 63); + char Vd_width = 4; + res->fields[FIELD_N] = (instr & 0x80)>>7; + res->fields_mask[FIELD_N >> 6] |= 1LL << (FIELD_N & 63); + char N_width = 1; + res->fields[FIELD_Q] = (instr & 0x40)>>6; + res->fields_mask[FIELD_Q >> 6] |= 1LL << (FIELD_Q & 63); + char Q_width = 1; + res->fields[FIELD_M] = (instr & 0x20)>>5; + res->fields_mask[FIELD_M >> 6] |= 1LL << (FIELD_M & 63); + char M_width = 1; + res->fields[FIELD_Vm] = instr & 0xF; + res->fields_mask[FIELD_Vm >> 6] |= 1LL << (FIELD_Vm & 63); + char Vm_width = 4; + + static const instruction_format instr_formats[] = + { + { /* VBIC<c> <Dd>,<Dn>,<Dm> */ + "vbic", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_n,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_m,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + { /* VBIC<c> <Qd>,<Qn>,<Qm> */ + "vbic", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"q","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_n,FIELD_UNINIT,"q","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_m,FIELD_UNINIT,"q","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 2; + res->mnem = armv7::ARMV7_VBIC; + + /* pcode: if Q == '1' && (Vd<0> == '1' || Vn<0> == '1' || Vm<0> == '1') then UNDEFINED */ + if(((res->fields[FIELD_Q]) == (0x1)) && ((((((res->fields[FIELD_Vd] & 1)) == (0x1)) || (((res->fields[FIELD_Vn] & 1)) == (0x1))) || (((res->fields[FIELD_Vm] & 1)) == (0x1))))) { + res->status |= STATUS_UNDEFINED; + } + /* pcode: d = UInt(D:Vd) */ + res->fields[FIELD_d] = ((res->fields[FIELD_D]<<Vd_width)|(res->fields[FIELD_Vd])); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: n = UInt(N:Vn) */ + res->fields[FIELD_n] = ((res->fields[FIELD_N]<<Vn_width)|(res->fields[FIELD_Vn])); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: m = UInt(M:Vm) */ + res->fields[FIELD_m] = ((res->fields[FIELD_M]<<Vm_width)|(res->fields[FIELD_Vm])); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + /* pcode: regs = if Q == '0' then 1 else 2 */ + if((res->fields[FIELD_Q]) == (0x0)) { + res->fields[FIELD_regs] = 1; + res->fields_mask[FIELD_regs >> 6] |= 1LL << (FIELD_regs & 63); + } + else { + res->fields[FIELD_regs] = 2; + res->fields_mask[FIELD_regs >> 6] |= 1LL << (FIELD_regs & 63); + } + /* pcode: fmt_idx = (Q == '1') */ + res->fields[FIELD_fmt_idx] = ((res->fields[FIELD_Q]) == (0x1)); + res->fields_mask[FIELD_fmt_idx >> 6] |= 1LL << (FIELD_fmt_idx & 63); + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: 246B41D5 +int vbif(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + /* Encoding T1 */ + /* pattern="1111,xx11,0,D.1,11,Vn.4,Vd.4,0001,N.1,Q.1,M.1,1,Vm.4" width=32 stringency=18 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xF3B00F10)==0xF3300110)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ADVSIMD)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_D] = (instr & 0x400000)>>22; + res->fields_mask[FIELD_D >> 6] |= 1LL << (FIELD_D & 63); + char D_width = 1; + res->fields[FIELD_Vn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Vn >> 6] |= 1LL << (FIELD_Vn & 63); + char Vn_width = 4; + res->fields[FIELD_Vd] = (instr & 0xF000)>>12; + res->fields_mask[FIELD_Vd >> 6] |= 1LL << (FIELD_Vd & 63); + char Vd_width = 4; + res->fields[FIELD_N] = (instr & 0x80)>>7; + res->fields_mask[FIELD_N >> 6] |= 1LL << (FIELD_N & 63); + char N_width = 1; + res->fields[FIELD_Q] = (instr & 0x40)>>6; + res->fields_mask[FIELD_Q >> 6] |= 1LL << (FIELD_Q & 63); + char Q_width = 1; + res->fields[FIELD_M] = (instr & 0x20)>>5; + res->fields_mask[FIELD_M >> 6] |= 1LL << (FIELD_M & 63); + char M_width = 1; + res->fields[FIELD_Vm] = instr & 0xF; + res->fields_mask[FIELD_Vm >> 6] |= 1LL << (FIELD_Vm & 63); + char Vm_width = 4; + + static const instruction_format instr_formats[] = + { + { /* VBIF<c> <Dd>,<Dn>,<Dm> */ + "vbif", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_n,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_m,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + { /* VBIF<c> <Qd>,<Qn>,<Qm> */ + "vbif", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"q","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_n,FIELD_UNINIT,"q","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_m,FIELD_UNINIT,"q","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 2; + res->mnem = armv7::ARMV7_VBIF; + + /* pcode: if Q == '1' && (Vd<0> == '1' || Vn<0> == '1' || Vm<0> == '1') then UNDEFINED */ + if(((res->fields[FIELD_Q]) == (0x1)) && ((((((res->fields[FIELD_Vd] & 1)) == (0x1)) || (((res->fields[FIELD_Vn] & 1)) == (0x1))) || (((res->fields[FIELD_Vm] & 1)) == (0x1))))) { + res->status |= STATUS_UNDEFINED; + } + /* pcode: d = UInt(D:Vd) */ + res->fields[FIELD_d] = ((res->fields[FIELD_D]<<Vd_width)|(res->fields[FIELD_Vd])); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: n = UInt(N:Vn) */ + res->fields[FIELD_n] = ((res->fields[FIELD_N]<<Vn_width)|(res->fields[FIELD_Vn])); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: m = UInt(M:Vm) */ + res->fields[FIELD_m] = ((res->fields[FIELD_M]<<Vm_width)|(res->fields[FIELD_Vm])); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + /* pcode: regs = if Q == '0' then 1 else 2 */ + if((res->fields[FIELD_Q]) == (0x0)) { + res->fields[FIELD_regs] = 1; + res->fields_mask[FIELD_regs >> 6] |= 1LL << (FIELD_regs & 63); + } + else { + res->fields[FIELD_regs] = 2; + res->fields_mask[FIELD_regs >> 6] |= 1LL << (FIELD_regs & 63); + } + /* pcode: fmt_idx = (Q == '1') */ + res->fields[FIELD_fmt_idx] = ((res->fields[FIELD_Q]) == (0x1)); + res->fields_mask[FIELD_fmt_idx >> 6] |= 1LL << (FIELD_fmt_idx & 63); + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: FE886552 +int vbit(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + /* Encoding T1 */ + /* pattern="1111,xx11,0,D.1,10,Vn.4,Vd.4,0001,N.1,Q.1,M.1,1,Vm.4" width=32 stringency=18 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xF3B00F10)==0xF3200110)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ADVSIMD)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_D] = (instr & 0x400000)>>22; + res->fields_mask[FIELD_D >> 6] |= 1LL << (FIELD_D & 63); + char D_width = 1; + res->fields[FIELD_Vn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Vn >> 6] |= 1LL << (FIELD_Vn & 63); + char Vn_width = 4; + res->fields[FIELD_Vd] = (instr & 0xF000)>>12; + res->fields_mask[FIELD_Vd >> 6] |= 1LL << (FIELD_Vd & 63); + char Vd_width = 4; + res->fields[FIELD_N] = (instr & 0x80)>>7; + res->fields_mask[FIELD_N >> 6] |= 1LL << (FIELD_N & 63); + char N_width = 1; + res->fields[FIELD_Q] = (instr & 0x40)>>6; + res->fields_mask[FIELD_Q >> 6] |= 1LL << (FIELD_Q & 63); + char Q_width = 1; + res->fields[FIELD_M] = (instr & 0x20)>>5; + res->fields_mask[FIELD_M >> 6] |= 1LL << (FIELD_M & 63); + char M_width = 1; + res->fields[FIELD_Vm] = instr & 0xF; + res->fields_mask[FIELD_Vm >> 6] |= 1LL << (FIELD_Vm & 63); + char Vm_width = 4; + + static const instruction_format instr_formats[] = + { + { /* VBIT<c> <Dd>,<Dn>,<Dm> */ + "vbit", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_n,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_m,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + { /* VBIT<c> <Qd>,<Qn>,<Qm> */ + "vbit", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"q","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_n,FIELD_UNINIT,"q","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_m,FIELD_UNINIT,"q","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 2; + res->mnem = armv7::ARMV7_VBIT; + + /* pcode: if Q == '1' && (Vd<0> == '1' || Vn<0> == '1' || Vm<0> == '1') then UNDEFINED */ + if(((res->fields[FIELD_Q]) == (0x1)) && ((((((res->fields[FIELD_Vd] & 1)) == (0x1)) || (((res->fields[FIELD_Vn] & 1)) == (0x1))) || (((res->fields[FIELD_Vm] & 1)) == (0x1))))) { + res->status |= STATUS_UNDEFINED; + } + /* pcode: d = UInt(D:Vd) */ + res->fields[FIELD_d] = ((res->fields[FIELD_D]<<Vd_width)|(res->fields[FIELD_Vd])); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: n = UInt(N:Vn) */ + res->fields[FIELD_n] = ((res->fields[FIELD_N]<<Vn_width)|(res->fields[FIELD_Vn])); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: m = UInt(M:Vm) */ + res->fields[FIELD_m] = ((res->fields[FIELD_M]<<Vm_width)|(res->fields[FIELD_Vm])); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + /* pcode: regs = if Q == '0' then 1 else 2 */ + if((res->fields[FIELD_Q]) == (0x0)) { + res->fields[FIELD_regs] = 1; + res->fields_mask[FIELD_regs >> 6] |= 1LL << (FIELD_regs & 63); + } + else { + res->fields[FIELD_regs] = 2; + res->fields_mask[FIELD_regs >> 6] |= 1LL << (FIELD_regs & 63); + } + /* pcode: fmt_idx = (Q == '1') */ + res->fields[FIELD_fmt_idx] = ((res->fields[FIELD_Q]) == (0x1)); + res->fields_mask[FIELD_fmt_idx >> 6] |= 1LL << (FIELD_fmt_idx & 63); + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: 4EE2A828 +int vbsl(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + /* Encoding T1 */ + /* pattern="1111,xx11,0,D.1,01,Vn.4,Vd.4,0001,N.1,Q.1,M.1,1,Vm.4" width=32 stringency=18 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xF3B00F10)==0xF3100110)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ADVSIMD)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_D] = (instr & 0x400000)>>22; + res->fields_mask[FIELD_D >> 6] |= 1LL << (FIELD_D & 63); + char D_width = 1; + res->fields[FIELD_Vn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Vn >> 6] |= 1LL << (FIELD_Vn & 63); + char Vn_width = 4; + res->fields[FIELD_Vd] = (instr & 0xF000)>>12; + res->fields_mask[FIELD_Vd >> 6] |= 1LL << (FIELD_Vd & 63); + char Vd_width = 4; + res->fields[FIELD_N] = (instr & 0x80)>>7; + res->fields_mask[FIELD_N >> 6] |= 1LL << (FIELD_N & 63); + char N_width = 1; + res->fields[FIELD_Q] = (instr & 0x40)>>6; + res->fields_mask[FIELD_Q >> 6] |= 1LL << (FIELD_Q & 63); + char Q_width = 1; + res->fields[FIELD_M] = (instr & 0x20)>>5; + res->fields_mask[FIELD_M >> 6] |= 1LL << (FIELD_M & 63); + char M_width = 1; + res->fields[FIELD_Vm] = instr & 0xF; + res->fields_mask[FIELD_Vm >> 6] |= 1LL << (FIELD_Vm & 63); + char Vm_width = 4; + + static const instruction_format instr_formats[] = + { + { /* VBSL<c> <Dd>,<Dn>,<Dm> */ + "vbsl", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_n,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_m,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + { /* VBSL<c> <Qd>,<Qn>,<Qm> */ + "vbsl", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"q","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_n,FIELD_UNINIT,"q","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_m,FIELD_UNINIT,"q","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 2; + res->mnem = armv7::ARMV7_VBSL; + + /* pcode: if Q == '1' && (Vd<0> == '1' || Vn<0> == '1' || Vm<0> == '1') then UNDEFINED */ + if(((res->fields[FIELD_Q]) == (0x1)) && ((((((res->fields[FIELD_Vd] & 1)) == (0x1)) || (((res->fields[FIELD_Vn] & 1)) == (0x1))) || (((res->fields[FIELD_Vm] & 1)) == (0x1))))) { + res->status |= STATUS_UNDEFINED; + } + /* pcode: d = UInt(D:Vd) */ + res->fields[FIELD_d] = ((res->fields[FIELD_D]<<Vd_width)|(res->fields[FIELD_Vd])); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: n = UInt(N:Vn) */ + res->fields[FIELD_n] = ((res->fields[FIELD_N]<<Vn_width)|(res->fields[FIELD_Vn])); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: m = UInt(M:Vm) */ + res->fields[FIELD_m] = ((res->fields[FIELD_M]<<Vm_width)|(res->fields[FIELD_Vm])); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + /* pcode: regs = if Q == '0' then 1 else 2 */ + if((res->fields[FIELD_Q]) == (0x0)) { + res->fields[FIELD_regs] = 1; + res->fields_mask[FIELD_regs >> 6] |= 1LL << (FIELD_regs & 63); + } + else { + res->fields[FIELD_regs] = 2; + res->fields_mask[FIELD_regs >> 6] |= 1LL << (FIELD_regs & 63); + } + /* pcode: fmt_idx = (Q == '1') */ + res->fields[FIELD_fmt_idx] = ((res->fields[FIELD_Q]) == (0x1)); + res->fields_mask[FIELD_fmt_idx >> 6] |= 1LL << (FIELD_fmt_idx & 63); + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: 1C12E4C5 +int vceq_immediate(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + res->group = INSN_GROUP_NEON; + /* Encoding T1 */ + /* pattern="1111,1111,1,D.1,11,size.2,01,Vd.4,0,F.1,010,Q.1,M.1,0,Vm.4" width=32 stringency=22 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFFB30B90)==0xFFB10100)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ADVSIMD)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_D] = (instr & 0x400000)>>22; + res->fields_mask[FIELD_D >> 6] |= 1LL << (FIELD_D & 63); + char D_width = 1; + res->fields[FIELD_size] = (instr & 0xC0000)>>18; + res->fields_mask[FIELD_size >> 6] |= 1LL << (FIELD_size & 63); + char size_width = 2; + res->fields[FIELD_Vd] = (instr & 0xF000)>>12; + res->fields_mask[FIELD_Vd >> 6] |= 1LL << (FIELD_Vd & 63); + char Vd_width = 4; + res->fields[FIELD_F] = (instr & 0x400)>>10; + res->fields_mask[FIELD_F >> 6] |= 1LL << (FIELD_F & 63); + char F_width = 1; + res->fields[FIELD_Q] = (instr & 0x40)>>6; + res->fields_mask[FIELD_Q >> 6] |= 1LL << (FIELD_Q & 63); + char Q_width = 1; + res->fields[FIELD_M] = (instr & 0x20)>>5; + res->fields_mask[FIELD_M >> 6] |= 1LL << (FIELD_M & 63); + char M_width = 1; + res->fields[FIELD_Vm] = instr & 0xF; + res->fields_mask[FIELD_Vm >> 6] |= 1LL << (FIELD_Vm & 63); + char Vm_width = 4; + + static const instruction_format instr_formats[] = + { + { /* VCEQ<c>.<dt> <Dd>,<Dm>,#0 */ + "vceq", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_VFP_DATA_SIZE, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_m,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_ZERO,FIELD_UNINIT,FIELD_UNINIT,"#0","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + { /* VCEQ<c>.<dt> <Qd>,<Qm>,#0 */ + "vceq", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_VFP_DATA_SIZE, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"q","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_m,FIELD_UNINIT,"q","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_ZERO,FIELD_UNINIT,FIELD_UNINIT,"#0","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 2; + res->mnem = armv7::ARMV7_VCEQ; + + /* pcode: if (size == '11' || (F == '1' && size != '10')) then UNDEFINED */ + if((((res->fields[FIELD_size]) == (0x3)) || ((((res->fields[FIELD_F]) == (0x1)) && ((res->fields[FIELD_size]) != (0x2)))))) { + res->status |= STATUS_UNDEFINED; + } + /* pcode: if (Q == '1' && (Vd<0> == '1' || Vm<0> == '1')) then UNDEFINED */ + if((((res->fields[FIELD_Q]) == (0x1)) && (((((res->fields[FIELD_Vd] & 1)) == (0x1)) || (((res->fields[FIELD_Vm] & 1)) == (0x1)))))) { + res->status |= STATUS_UNDEFINED; + } + /* pcode: esize = 8 << UInt(size) */ + res->fields[FIELD_esize] = (8) << ((res->fields[FIELD_size])); + res->fields_mask[FIELD_esize >> 6] |= 1LL << (FIELD_esize & 63); + /* pcode: elements = 64 DIV esize */ + res->fields[FIELD_elements] = ((res->fields[FIELD_esize]) ? ((64) / (res->fields[FIELD_esize])) : 0); + res->fields_mask[FIELD_elements >> 6] |= 1LL << (FIELD_elements & 63); + /* pcode: d = UInt(D:Vd) */ + res->fields[FIELD_d] = ((res->fields[FIELD_D]<<Vd_width)|(res->fields[FIELD_Vd])); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: m = UInt(M:Vm) */ + res->fields[FIELD_m] = ((res->fields[FIELD_M]<<Vm_width)|(res->fields[FIELD_Vm])); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + /* pcode: regs = if Q == '0' then 1 else 2 */ + if((res->fields[FIELD_Q]) == (0x0)) { + res->fields[FIELD_regs] = 1; + res->fields_mask[FIELD_regs >> 6] |= 1LL << (FIELD_regs & 63); + } + else { + res->fields[FIELD_regs] = 2; + res->fields_mask[FIELD_regs >> 6] |= 1LL << (FIELD_regs & 63); + } + /* pcode: fmt_idx = (Q == '1') */ + res->fields[FIELD_fmt_idx] = ((res->fields[FIELD_Q]) == (0x1)); + res->fields_mask[FIELD_fmt_idx >> 6] |= 1LL << (FIELD_fmt_idx & 63); + /* pcode: iword = TRUE */ + res->fields[FIELD_iword] = 1; + res->fields_mask[FIELD_iword >> 6] |= 1LL << (FIELD_iword & 63); + /* pcode: dt = 4 */ + res->fields[FIELD_dt] = 4; + res->fields_mask[FIELD_dt >> 6] |= 1LL << (FIELD_dt & 63); + /* pcode: if F == '0' then dt = size */ + if((res->fields[FIELD_F]) == (0x0)) { + res->fields[FIELD_dt] = res->fields[FIELD_size]; + res->fields_mask[FIELD_dt >> 6] |= 1LL << (FIELD_dt & 63); + } + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: 9D4F4D13 +int vceq_register(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + res->group = INSN_GROUP_NEON; + /* Encoding T2 */ + /* pattern="1110,0010,0,D.1,0,sz.1,Vn.4,Vd.4,1110,N.1,Q.1,M.1,0,Vm.4" width=32 stringency=20 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFFA00F10)==0xE2000E00)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ADVSIMD)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_D] = (instr & 0x400000)>>22; + res->fields_mask[FIELD_D >> 6] |= 1LL << (FIELD_D & 63); + char D_width = 1; + res->fields[FIELD_sz] = (instr & 0x100000)>>20; + res->fields_mask[FIELD_sz >> 6] |= 1LL << (FIELD_sz & 63); + char sz_width = 1; + res->fields[FIELD_Vn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Vn >> 6] |= 1LL << (FIELD_Vn & 63); + char Vn_width = 4; + res->fields[FIELD_Vd] = (instr & 0xF000)>>12; + res->fields_mask[FIELD_Vd >> 6] |= 1LL << (FIELD_Vd & 63); + char Vd_width = 4; + res->fields[FIELD_N] = (instr & 0x80)>>7; + res->fields_mask[FIELD_N >> 6] |= 1LL << (FIELD_N & 63); + char N_width = 1; + res->fields[FIELD_Q] = (instr & 0x40)>>6; + res->fields_mask[FIELD_Q >> 6] |= 1LL << (FIELD_Q & 63); + char Q_width = 1; + res->fields[FIELD_M] = (instr & 0x20)>>5; + res->fields_mask[FIELD_M >> 6] |= 1LL << (FIELD_M & 63); + char M_width = 1; + res->fields[FIELD_Vm] = instr & 0xF; + res->fields_mask[FIELD_Vm >> 6] |= 1LL << (FIELD_Vm & 63); + char Vm_width = 4; + + static const instruction_format instr_formats[] = + { + { /* VCEQ<c>.F32 <Dd>,<Dn>,<Dm> */ + "vceq.f32", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_F32, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_n,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_m,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + { /* VCEQ<c>.F32 <Qd>,<Qn>,<Qm> */ + "vceq.f32", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_F32, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"q","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_n,FIELD_UNINIT,"q","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_m,FIELD_UNINIT,"q","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 2; + res->mnem = armv7::ARMV7_VCEQ; + + /* pcode: if (Q == '1' && (Vd<0> == '1' || Vn<0> == '1' || Vm<0> == '1')) then UNDEFINED */ + if((((res->fields[FIELD_Q]) == (0x1)) && ((((((res->fields[FIELD_Vd] & 1)) == (0x1)) || (((res->fields[FIELD_Vn] & 1)) == (0x1))) || (((res->fields[FIELD_Vm] & 1)) == (0x1)))))) { + res->status |= STATUS_UNDEFINED; + } + /* pcode: if sz == '1' then UNDEFINED */ + if((res->fields[FIELD_sz]) == (0x1)) { + res->status |= STATUS_UNDEFINED; + } + /* pcode: esize = 32 */ + res->fields[FIELD_esize] = 32; + res->fields_mask[FIELD_esize >> 6] |= 1LL << (FIELD_esize & 63); + /* pcode: elements = 2 */ + res->fields[FIELD_elements] = 2; + res->fields_mask[FIELD_elements >> 6] |= 1LL << (FIELD_elements & 63); + /* pcode: d = UInt(D:Vd) */ + res->fields[FIELD_d] = ((res->fields[FIELD_D]<<Vd_width)|(res->fields[FIELD_Vd])); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: n = UInt(N:Vn) */ + res->fields[FIELD_n] = ((res->fields[FIELD_N]<<Vn_width)|(res->fields[FIELD_Vn])); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: m = UInt(M:Vm) */ + res->fields[FIELD_m] = ((res->fields[FIELD_M]<<Vm_width)|(res->fields[FIELD_Vm])); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + /* pcode: regs = if Q == '0' then 1 else 2 */ + if((res->fields[FIELD_Q]) == (0x0)) { + res->fields[FIELD_regs] = 1; + res->fields_mask[FIELD_regs >> 6] |= 1LL << (FIELD_regs & 63); + } + else { + res->fields[FIELD_regs] = 2; + res->fields_mask[FIELD_regs >> 6] |= 1LL << (FIELD_regs & 63); + } + /* pcode: fmt_idx = (Q == '1') */ + res->fields[FIELD_fmt_idx] = ((res->fields[FIELD_Q]) == (0x1)); + res->fields_mask[FIELD_fmt_idx >> 6] |= 1LL << (FIELD_fmt_idx & 63); + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* Encoding T1 */ + /* pattern="1111,1111,0,D.1,size.2,Vn.4,Vd.4,1000,N.1,Q.1,M.1,1,Vm.4" width=32 stringency=18 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFF800F10)==0xFF000810)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ADVSIMD)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_D] = (instr & 0x400000)>>22; + res->fields_mask[FIELD_D >> 6] |= 1LL << (FIELD_D & 63); + char D_width = 1; + res->fields[FIELD_size] = (instr & 0x300000)>>20; + res->fields_mask[FIELD_size >> 6] |= 1LL << (FIELD_size & 63); + char size_width = 2; + res->fields[FIELD_Vn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Vn >> 6] |= 1LL << (FIELD_Vn & 63); + char Vn_width = 4; + res->fields[FIELD_Vd] = (instr & 0xF000)>>12; + res->fields_mask[FIELD_Vd >> 6] |= 1LL << (FIELD_Vd & 63); + char Vd_width = 4; + res->fields[FIELD_N] = (instr & 0x80)>>7; + res->fields_mask[FIELD_N >> 6] |= 1LL << (FIELD_N & 63); + char N_width = 1; + res->fields[FIELD_Q] = (instr & 0x40)>>6; + res->fields_mask[FIELD_Q >> 6] |= 1LL << (FIELD_Q & 63); + char Q_width = 1; + res->fields[FIELD_M] = (instr & 0x20)>>5; + res->fields_mask[FIELD_M >> 6] |= 1LL << (FIELD_M & 63); + char M_width = 1; + res->fields[FIELD_Vm] = instr & 0xF; + res->fields_mask[FIELD_Vm >> 6] |= 1LL << (FIELD_Vm & 63); + char Vm_width = 4; + + static const instruction_format instr_formats[] = + { + { /* VCEQ<c>.<dt> <Dd>,<Dn>,<Dm> */ + "vceq", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_VFP_DATA_SIZE, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_n,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_m,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + { /* VCEQ<c>.<dt> <Qd>,<Qn>,<Qm> */ + "vceq", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_VFP_DATA_SIZE, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"q","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_n,FIELD_UNINIT,"q","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_m,FIELD_UNINIT,"q","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 2; + res->mnem = armv7::ARMV7_VCEQ; + + /* pcode: if (Q == '1' && (Vd<0> == '1' || Vn<0> == '1' || Vm<0> == '1')) then UNDEFINED */ + if((((res->fields[FIELD_Q]) == (0x1)) && ((((((res->fields[FIELD_Vd] & 1)) == (0x1)) || (((res->fields[FIELD_Vn] & 1)) == (0x1))) || (((res->fields[FIELD_Vm] & 1)) == (0x1)))))) { + res->status |= STATUS_UNDEFINED; + } + /* pcode: if size == '11' then UNDEFINED */ + if((res->fields[FIELD_size]) == (0x3)) { + res->status |= STATUS_UNDEFINED; + } + /* pcode: esize = 8 << UInt(size) */ + res->fields[FIELD_esize] = (8) << ((res->fields[FIELD_size])); + res->fields_mask[FIELD_esize >> 6] |= 1LL << (FIELD_esize & 63); + /* pcode: elements = 64 DIV esize */ + res->fields[FIELD_elements] = ((res->fields[FIELD_esize]) ? ((64) / (res->fields[FIELD_esize])) : 0); + res->fields_mask[FIELD_elements >> 6] |= 1LL << (FIELD_elements & 63); + /* pcode: d = UInt(D:Vd) */ + res->fields[FIELD_d] = ((res->fields[FIELD_D]<<Vd_width)|(res->fields[FIELD_Vd])); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: n = UInt(N:Vn) */ + res->fields[FIELD_n] = ((res->fields[FIELD_N]<<Vn_width)|(res->fields[FIELD_Vn])); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: m = UInt(M:Vm) */ + res->fields[FIELD_m] = ((res->fields[FIELD_M]<<Vm_width)|(res->fields[FIELD_Vm])); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + /* pcode: regs = if Q == '0' then 1 else 2 */ + if((res->fields[FIELD_Q]) == (0x0)) { + res->fields[FIELD_regs] = 1; + res->fields_mask[FIELD_regs >> 6] |= 1LL << (FIELD_regs & 63); + } + else { + res->fields[FIELD_regs] = 2; + res->fields_mask[FIELD_regs >> 6] |= 1LL << (FIELD_regs & 63); + } + /* pcode: fmt_idx = (Q == '1') */ + res->fields[FIELD_fmt_idx] = ((res->fields[FIELD_Q]) == (0x1)); + res->fields_mask[FIELD_fmt_idx >> 6] |= 1LL << (FIELD_fmt_idx & 63); + /* pcode: dt = UInt(size) */ + res->fields[FIELD_dt] = (res->fields[FIELD_size]); + res->fields_mask[FIELD_dt >> 6] |= 1LL << (FIELD_dt & 63); + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: C247D48E +int vcge_immediate(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + res->group = INSN_GROUP_NEON; + /* Encoding T1 */ + /* pattern="1111,1111,1,D.1,11,size.2,01,Vd.4,0,F.1,001,Q.1,M.1,0,Vm.4" width=32 stringency=22 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFFB30B90)==0xFFB10080)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ADVSIMD)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_D] = (instr & 0x400000)>>22; + res->fields_mask[FIELD_D >> 6] |= 1LL << (FIELD_D & 63); + char D_width = 1; + res->fields[FIELD_size] = (instr & 0xC0000)>>18; + res->fields_mask[FIELD_size >> 6] |= 1LL << (FIELD_size & 63); + char size_width = 2; + res->fields[FIELD_Vd] = (instr & 0xF000)>>12; + res->fields_mask[FIELD_Vd >> 6] |= 1LL << (FIELD_Vd & 63); + char Vd_width = 4; + res->fields[FIELD_F] = (instr & 0x400)>>10; + res->fields_mask[FIELD_F >> 6] |= 1LL << (FIELD_F & 63); + char F_width = 1; + res->fields[FIELD_Q] = (instr & 0x40)>>6; + res->fields_mask[FIELD_Q >> 6] |= 1LL << (FIELD_Q & 63); + char Q_width = 1; + res->fields[FIELD_M] = (instr & 0x20)>>5; + res->fields_mask[FIELD_M >> 6] |= 1LL << (FIELD_M & 63); + char M_width = 1; + res->fields[FIELD_Vm] = instr & 0xF; + res->fields_mask[FIELD_Vm >> 6] |= 1LL << (FIELD_Vm & 63); + char Vm_width = 4; + + static const instruction_format instr_formats[] = + { + { /* VCGE<c>.<dt> <Dd>,<Dm>,#0 */ + "vcge", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_VFP_DATA_SIZE, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_m,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_ZERO,FIELD_UNINIT,FIELD_UNINIT,"#0","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + { /* VCGE<c>.<dt> <Qd>,<Qm>,#0 */ + "vcge", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_VFP_DATA_SIZE, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"q","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_m,FIELD_UNINIT,"q","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_ZERO,FIELD_UNINIT,FIELD_UNINIT,"#0","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 2; + res->mnem = armv7::ARMV7_VCGE; + + /* pcode: if (size == '11' || (F == '1' && size != '10')) then UNDEFINED */ + if((((res->fields[FIELD_size]) == (0x3)) || ((((res->fields[FIELD_F]) == (0x1)) && ((res->fields[FIELD_size]) != (0x2)))))) { + res->status |= STATUS_UNDEFINED; + } + /* pcode: if (Q == '1' && (Vd<0> == '1' || Vm<0> == '1')) then UNDEFINED */ + if((((res->fields[FIELD_Q]) == (0x1)) && (((((res->fields[FIELD_Vd] & 1)) == (0x1)) || (((res->fields[FIELD_Vm] & 1)) == (0x1)))))) { + res->status |= STATUS_UNDEFINED; + } + /* pcode: esize = 8 << UInt(size) */ + res->fields[FIELD_esize] = (8) << ((res->fields[FIELD_size])); + res->fields_mask[FIELD_esize >> 6] |= 1LL << (FIELD_esize & 63); + /* pcode: elements = 64 DIV esize */ + res->fields[FIELD_elements] = ((res->fields[FIELD_esize]) ? ((64) / (res->fields[FIELD_esize])) : 0); + res->fields_mask[FIELD_elements >> 6] |= 1LL << (FIELD_elements & 63); + /* pcode: d = UInt(D:Vd) */ + res->fields[FIELD_d] = ((res->fields[FIELD_D]<<Vd_width)|(res->fields[FIELD_Vd])); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: m = UInt(M:Vm) */ + res->fields[FIELD_m] = ((res->fields[FIELD_M]<<Vm_width)|(res->fields[FIELD_Vm])); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + /* pcode: regs = if Q == '0' then 1 else 2 */ + if((res->fields[FIELD_Q]) == (0x0)) { + res->fields[FIELD_regs] = 1; + res->fields_mask[FIELD_regs >> 6] |= 1LL << (FIELD_regs & 63); + } + else { + res->fields[FIELD_regs] = 2; + res->fields_mask[FIELD_regs >> 6] |= 1LL << (FIELD_regs & 63); + } + /* pcode: fmt_idx = (Q == '1') */ + res->fields[FIELD_fmt_idx] = ((res->fields[FIELD_Q]) == (0x1)); + res->fields_mask[FIELD_fmt_idx >> 6] |= 1LL << (FIELD_fmt_idx & 63); + /* pcode: dt = size */ + res->fields[FIELD_dt] = res->fields[FIELD_size]; + res->fields_mask[FIELD_dt >> 6] |= 1LL << (FIELD_dt & 63); + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: 74E027A9 +int vcge_register(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + res->group = INSN_GROUP_NEON; + /* Encoding T2 */ + /* pattern="1111,1111,0,D.1,0,sz.1,Vn.4,Vd.4,1110,N.1,Q.1,M.1,0,Vm.4" width=32 stringency=20 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFFA00F10)==0xFF000E00)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ADVSIMD)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_D] = (instr & 0x400000)>>22; + res->fields_mask[FIELD_D >> 6] |= 1LL << (FIELD_D & 63); + char D_width = 1; + res->fields[FIELD_sz] = (instr & 0x100000)>>20; + res->fields_mask[FIELD_sz >> 6] |= 1LL << (FIELD_sz & 63); + char sz_width = 1; + res->fields[FIELD_Vn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Vn >> 6] |= 1LL << (FIELD_Vn & 63); + char Vn_width = 4; + res->fields[FIELD_Vd] = (instr & 0xF000)>>12; + res->fields_mask[FIELD_Vd >> 6] |= 1LL << (FIELD_Vd & 63); + char Vd_width = 4; + res->fields[FIELD_N] = (instr & 0x80)>>7; + res->fields_mask[FIELD_N >> 6] |= 1LL << (FIELD_N & 63); + char N_width = 1; + res->fields[FIELD_Q] = (instr & 0x40)>>6; + res->fields_mask[FIELD_Q >> 6] |= 1LL << (FIELD_Q & 63); + char Q_width = 1; + res->fields[FIELD_M] = (instr & 0x20)>>5; + res->fields_mask[FIELD_M >> 6] |= 1LL << (FIELD_M & 63); + char M_width = 1; + res->fields[FIELD_Vm] = instr & 0xF; + res->fields_mask[FIELD_Vm >> 6] |= 1LL << (FIELD_Vm & 63); + char Vm_width = 4; + + static const instruction_format instr_formats[] = + { + { /* VCGE<c>.F32 <Dd>,<Dn>,<Dm> */ + "vcge.f32", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_F32, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_n,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_m,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + { /* VCGE<c>.F32 <Qd>,<Qn>,<Qm> */ + "vcge.f32", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_F32, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"q","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_n,FIELD_UNINIT,"q","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_m,FIELD_UNINIT,"q","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 2; + res->mnem = armv7::ARMV7_VCGE; + + /* pcode: if (Q == '1' && (Vd<0> == '1' || Vn<0> == '1' || Vm<0> == '1')) then UNDEFINED */ + if((((res->fields[FIELD_Q]) == (0x1)) && ((((((res->fields[FIELD_Vd] & 1)) == (0x1)) || (((res->fields[FIELD_Vn] & 1)) == (0x1))) || (((res->fields[FIELD_Vm] & 1)) == (0x1)))))) { + res->status |= STATUS_UNDEFINED; + } + /* pcode: if sz == '1' then UNDEFINED */ + if((res->fields[FIELD_sz]) == (0x1)) { + res->status |= STATUS_UNDEFINED; + } + /* pcode: esize = 32 */ + res->fields[FIELD_esize] = 32; + res->fields_mask[FIELD_esize >> 6] |= 1LL << (FIELD_esize & 63); + /* pcode: elements = 2 */ + res->fields[FIELD_elements] = 2; + res->fields_mask[FIELD_elements >> 6] |= 1LL << (FIELD_elements & 63); + /* pcode: d = UInt(D:Vd) */ + res->fields[FIELD_d] = ((res->fields[FIELD_D]<<Vd_width)|(res->fields[FIELD_Vd])); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: n = UInt(N:Vn) */ + res->fields[FIELD_n] = ((res->fields[FIELD_N]<<Vn_width)|(res->fields[FIELD_Vn])); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: m = UInt(M:Vm) */ + res->fields[FIELD_m] = ((res->fields[FIELD_M]<<Vm_width)|(res->fields[FIELD_Vm])); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + /* pcode: regs = if Q == '0' then 1 else 2 */ + if((res->fields[FIELD_Q]) == (0x0)) { + res->fields[FIELD_regs] = 1; + res->fields_mask[FIELD_regs >> 6] |= 1LL << (FIELD_regs & 63); + } + else { + res->fields[FIELD_regs] = 2; + res->fields_mask[FIELD_regs >> 6] |= 1LL << (FIELD_regs & 63); + } + /* pcode: fmt_idx = (Q == '1') */ + res->fields[FIELD_fmt_idx] = ((res->fields[FIELD_Q]) == (0x1)); + res->fields_mask[FIELD_fmt_idx >> 6] |= 1LL << (FIELD_fmt_idx & 63); + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* Encoding T1 */ + /* pattern="111,U.1,1111,0,D.1,size.2,Vn.4,Vd.4,0011,N.1,Q.1,M.1,1,Vm.4" width=32 stringency=18 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xEF800F10)==0xEF000310)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ADVSIMD)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_U] = (instr & 0x10000000)>>28; + res->fields_mask[FIELD_U >> 6] |= 1LL << (FIELD_U & 63); + char U_width = 1; + res->fields[FIELD_D] = (instr & 0x400000)>>22; + res->fields_mask[FIELD_D >> 6] |= 1LL << (FIELD_D & 63); + char D_width = 1; + res->fields[FIELD_size] = (instr & 0x300000)>>20; + res->fields_mask[FIELD_size >> 6] |= 1LL << (FIELD_size & 63); + char size_width = 2; + res->fields[FIELD_Vn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Vn >> 6] |= 1LL << (FIELD_Vn & 63); + char Vn_width = 4; + res->fields[FIELD_Vd] = (instr & 0xF000)>>12; + res->fields_mask[FIELD_Vd >> 6] |= 1LL << (FIELD_Vd & 63); + char Vd_width = 4; + res->fields[FIELD_N] = (instr & 0x80)>>7; + res->fields_mask[FIELD_N >> 6] |= 1LL << (FIELD_N & 63); + char N_width = 1; + res->fields[FIELD_Q] = (instr & 0x40)>>6; + res->fields_mask[FIELD_Q >> 6] |= 1LL << (FIELD_Q & 63); + char Q_width = 1; + res->fields[FIELD_M] = (instr & 0x20)>>5; + res->fields_mask[FIELD_M >> 6] |= 1LL << (FIELD_M & 63); + char M_width = 1; + res->fields[FIELD_Vm] = instr & 0xF; + res->fields_mask[FIELD_Vm >> 6] |= 1LL << (FIELD_Vm & 63); + char Vm_width = 4; + + static const instruction_format instr_formats[] = + { + { /* VCGE<c>.<dt> <Dd>,<Dn>,<Dm> */ + "vcge", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_VFP_DATA_SIZE, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_n,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_m,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + { /* VCGE<c>.<dt> <Qd>,<Qn>,<Qm> */ + "vcge", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_VFP_DATA_SIZE, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"q","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_n,FIELD_UNINIT,"q","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_m,FIELD_UNINIT,"q","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 2; + res->mnem = armv7::ARMV7_VCGE; + + /* pcode: if (Q == '1' && (Vd<0> == '1' || Vn<0> == '1' || Vm<0> == '1')) then UNDEFINED */ + if((((res->fields[FIELD_Q]) == (0x1)) && ((((((res->fields[FIELD_Vd] & 1)) == (0x1)) || (((res->fields[FIELD_Vn] & 1)) == (0x1))) || (((res->fields[FIELD_Vm] & 1)) == (0x1)))))) { + res->status |= STATUS_UNDEFINED; + } + /* pcode: if size == '11' then UNDEFINED */ + if((res->fields[FIELD_size]) == (0x3)) { + res->status |= STATUS_UNDEFINED; + } + /* pcode: esize = 8 << UInt(size) */ + res->fields[FIELD_esize] = (8) << ((res->fields[FIELD_size])); + res->fields_mask[FIELD_esize >> 6] |= 1LL << (FIELD_esize & 63); + /* pcode: elements = 64 DIV esize */ + res->fields[FIELD_elements] = ((res->fields[FIELD_esize]) ? ((64) / (res->fields[FIELD_esize])) : 0); + res->fields_mask[FIELD_elements >> 6] |= 1LL << (FIELD_elements & 63); + /* pcode: d = UInt(D:Vd) */ + res->fields[FIELD_d] = ((res->fields[FIELD_D]<<Vd_width)|(res->fields[FIELD_Vd])); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: n = UInt(N:Vn) */ + res->fields[FIELD_n] = ((res->fields[FIELD_N]<<Vn_width)|(res->fields[FIELD_Vn])); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: m = UInt(M:Vm) */ + res->fields[FIELD_m] = ((res->fields[FIELD_M]<<Vm_width)|(res->fields[FIELD_Vm])); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + /* pcode: regs = if Q == '0' then 1 else 2 */ + if((res->fields[FIELD_Q]) == (0x0)) { + res->fields[FIELD_regs] = 1; + res->fields_mask[FIELD_regs >> 6] |= 1LL << (FIELD_regs & 63); + } + else { + res->fields[FIELD_regs] = 2; + res->fields_mask[FIELD_regs >> 6] |= 1LL << (FIELD_regs & 63); + } + /* pcode: unsigned = (U == '1') */ + res->fields[FIELD_unsigned] = ((res->fields[FIELD_U]) == (0x1)); + res->fields_mask[FIELD_unsigned >> 6] |= 1LL << (FIELD_unsigned & 63); + /* pcode: fmt_idx = (Q == '1') */ + res->fields[FIELD_fmt_idx] = ((res->fields[FIELD_Q]) == (0x1)); + res->fields_mask[FIELD_fmt_idx >> 6] |= 1LL << (FIELD_fmt_idx & 63); + /* pcode: dt = UInt(U:size) */ + res->fields[FIELD_dt] = ((res->fields[FIELD_U]<<size_width)|(res->fields[FIELD_size])); + res->fields_mask[FIELD_dt >> 6] |= 1LL << (FIELD_dt & 63); + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: 97835DF1 +int vcgt_immediate(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + res->group = INSN_GROUP_NEON; + /* Encoding T1 */ + /* pattern="1111,1111,1,D.1,11,size.2,01,Vd.4,0,F.1,000,Q.1,M.1,0,Vm.4" width=32 stringency=22 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFFB30B90)==0xFFB10000)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ADVSIMD)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_D] = (instr & 0x400000)>>22; + res->fields_mask[FIELD_D >> 6] |= 1LL << (FIELD_D & 63); + char D_width = 1; + res->fields[FIELD_size] = (instr & 0xC0000)>>18; + res->fields_mask[FIELD_size >> 6] |= 1LL << (FIELD_size & 63); + char size_width = 2; + res->fields[FIELD_Vd] = (instr & 0xF000)>>12; + res->fields_mask[FIELD_Vd >> 6] |= 1LL << (FIELD_Vd & 63); + char Vd_width = 4; + res->fields[FIELD_F] = (instr & 0x400)>>10; + res->fields_mask[FIELD_F >> 6] |= 1LL << (FIELD_F & 63); + char F_width = 1; + res->fields[FIELD_Q] = (instr & 0x40)>>6; + res->fields_mask[FIELD_Q >> 6] |= 1LL << (FIELD_Q & 63); + char Q_width = 1; + res->fields[FIELD_M] = (instr & 0x20)>>5; + res->fields_mask[FIELD_M >> 6] |= 1LL << (FIELD_M & 63); + char M_width = 1; + res->fields[FIELD_Vm] = instr & 0xF; + res->fields_mask[FIELD_Vm >> 6] |= 1LL << (FIELD_Vm & 63); + char Vm_width = 4; + + static const instruction_format instr_formats[] = + { + { /* VCGT<c>.<dt> <Dd>,<Dm>,#0 */ + "vcgt", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_VFP_DATA_SIZE, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_m,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_ZERO,FIELD_UNINIT,FIELD_UNINIT,"#0","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + { /* VCGT<c>.<dt> <Qd>,<Qm>,#0 */ + "vcgt", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_VFP_DATA_SIZE, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"q","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_m,FIELD_UNINIT,"q","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_ZERO,FIELD_UNINIT,FIELD_UNINIT,"#0","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 2; + res->mnem = armv7::ARMV7_VCGT; + + /* pcode: if (size == '11' || (F == '1' && size != '10')) then UNDEFINED */ + if((((res->fields[FIELD_size]) == (0x3)) || ((((res->fields[FIELD_F]) == (0x1)) && ((res->fields[FIELD_size]) != (0x2)))))) { + res->status |= STATUS_UNDEFINED; + } + /* pcode: if (Q == '1' && (Vd<0> == '1' || Vm<0> == '1')) then UNDEFINED */ + if((((res->fields[FIELD_Q]) == (0x1)) && (((((res->fields[FIELD_Vd] & 1)) == (0x1)) || (((res->fields[FIELD_Vm] & 1)) == (0x1)))))) { + res->status |= STATUS_UNDEFINED; + } + /* pcode: esize = 8 << UInt(size) */ + res->fields[FIELD_esize] = (8) << ((res->fields[FIELD_size])); + res->fields_mask[FIELD_esize >> 6] |= 1LL << (FIELD_esize & 63); + /* pcode: elements = 64 DIV esize */ + res->fields[FIELD_elements] = ((res->fields[FIELD_esize]) ? ((64) / (res->fields[FIELD_esize])) : 0); + res->fields_mask[FIELD_elements >> 6] |= 1LL << (FIELD_elements & 63); + /* pcode: d = UInt(D:Vd) */ + res->fields[FIELD_d] = ((res->fields[FIELD_D]<<Vd_width)|(res->fields[FIELD_Vd])); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: m = UInt(M:Vm) */ + res->fields[FIELD_m] = ((res->fields[FIELD_M]<<Vm_width)|(res->fields[FIELD_Vm])); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + /* pcode: regs = if Q == '0' then 1 else 2 */ + if((res->fields[FIELD_Q]) == (0x0)) { + res->fields[FIELD_regs] = 1; + res->fields_mask[FIELD_regs >> 6] |= 1LL << (FIELD_regs & 63); + } + else { + res->fields[FIELD_regs] = 2; + res->fields_mask[FIELD_regs >> 6] |= 1LL << (FIELD_regs & 63); + } + /* pcode: fmt_idx = (Q == '1') */ + res->fields[FIELD_fmt_idx] = ((res->fields[FIELD_Q]) == (0x1)); + res->fields_mask[FIELD_fmt_idx >> 6] |= 1LL << (FIELD_fmt_idx & 63); + /* pcode: dt = size + F */ + res->fields[FIELD_dt] = (res->fields[FIELD_size]) + (res->fields[FIELD_F]); + res->fields_mask[FIELD_dt >> 6] |= 1LL << (FIELD_dt & 63); + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: 744FCB97 +int vcgt_register(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + res->group = INSN_GROUP_NEON; + /* Encoding T2 */ + /* pattern="1111,1111,0,D.1,1,sz.1,Vn.4,Vd.4,1110,N.1,Q.1,M.1,0,Vm.4" width=32 stringency=20 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFFA00F10)==0xFF200E00)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ADVSIMD)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_D] = (instr & 0x400000)>>22; + res->fields_mask[FIELD_D >> 6] |= 1LL << (FIELD_D & 63); + char D_width = 1; + res->fields[FIELD_sz] = (instr & 0x100000)>>20; + res->fields_mask[FIELD_sz >> 6] |= 1LL << (FIELD_sz & 63); + char sz_width = 1; + res->fields[FIELD_Vn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Vn >> 6] |= 1LL << (FIELD_Vn & 63); + char Vn_width = 4; + res->fields[FIELD_Vd] = (instr & 0xF000)>>12; + res->fields_mask[FIELD_Vd >> 6] |= 1LL << (FIELD_Vd & 63); + char Vd_width = 4; + res->fields[FIELD_N] = (instr & 0x80)>>7; + res->fields_mask[FIELD_N >> 6] |= 1LL << (FIELD_N & 63); + char N_width = 1; + res->fields[FIELD_Q] = (instr & 0x40)>>6; + res->fields_mask[FIELD_Q >> 6] |= 1LL << (FIELD_Q & 63); + char Q_width = 1; + res->fields[FIELD_M] = (instr & 0x20)>>5; + res->fields_mask[FIELD_M >> 6] |= 1LL << (FIELD_M & 63); + char M_width = 1; + res->fields[FIELD_Vm] = instr & 0xF; + res->fields_mask[FIELD_Vm >> 6] |= 1LL << (FIELD_Vm & 63); + char Vm_width = 4; + + static const instruction_format instr_formats[] = + { + { /* VCGT<c>.F32 <Dd>,<Dn>,<Dm> */ + "vcgt.f32", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_F32, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_n,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_m,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + { /* VCGT<c>.F32 <Qd>,<Qn>,<Qm> */ + "vcgt.f32", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_F32, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"q","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_n,FIELD_UNINIT,"q","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_m,FIELD_UNINIT,"q","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 2; + res->mnem = armv7::ARMV7_VCGT; + + /* pcode: if (Q == '1' && (Vd<0> == '1' || Vn<0> == '1' || Vm<0> == '1')) then UNDEFINED */ + if((((res->fields[FIELD_Q]) == (0x1)) && ((((((res->fields[FIELD_Vd] & 1)) == (0x1)) || (((res->fields[FIELD_Vn] & 1)) == (0x1))) || (((res->fields[FIELD_Vm] & 1)) == (0x1)))))) { + res->status |= STATUS_UNDEFINED; + } + /* pcode: if sz == '1' then UNDEFINED */ + if((res->fields[FIELD_sz]) == (0x1)) { + res->status |= STATUS_UNDEFINED; + } + /* pcode: esize = 32 */ + res->fields[FIELD_esize] = 32; + res->fields_mask[FIELD_esize >> 6] |= 1LL << (FIELD_esize & 63); + /* pcode: elements = 2 */ + res->fields[FIELD_elements] = 2; + res->fields_mask[FIELD_elements >> 6] |= 1LL << (FIELD_elements & 63); + /* pcode: d = UInt(D:Vd) */ + res->fields[FIELD_d] = ((res->fields[FIELD_D]<<Vd_width)|(res->fields[FIELD_Vd])); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: n = UInt(N:Vn) */ + res->fields[FIELD_n] = ((res->fields[FIELD_N]<<Vn_width)|(res->fields[FIELD_Vn])); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: m = UInt(M:Vm) */ + res->fields[FIELD_m] = ((res->fields[FIELD_M]<<Vm_width)|(res->fields[FIELD_Vm])); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + /* pcode: regs = if Q == '0' then 1 else 2 */ + if((res->fields[FIELD_Q]) == (0x0)) { + res->fields[FIELD_regs] = 1; + res->fields_mask[FIELD_regs >> 6] |= 1LL << (FIELD_regs & 63); + } + else { + res->fields[FIELD_regs] = 2; + res->fields_mask[FIELD_regs >> 6] |= 1LL << (FIELD_regs & 63); + } + /* pcode: fmt_idx = (Q == '1') */ + res->fields[FIELD_fmt_idx] = ((res->fields[FIELD_Q]) == (0x1)); + res->fields_mask[FIELD_fmt_idx >> 6] |= 1LL << (FIELD_fmt_idx & 63); + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* Encoding T1 */ + /* pattern="111,U.1,1111,0,D.1,size.2,Vn.4,Vd.4,0011,N.1,Q.1,M.1,0,Vm.4" width=32 stringency=18 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xEF800F10)==0xEF000300)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ADVSIMD)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_U] = (instr & 0x10000000)>>28; + res->fields_mask[FIELD_U >> 6] |= 1LL << (FIELD_U & 63); + char U_width = 1; + res->fields[FIELD_D] = (instr & 0x400000)>>22; + res->fields_mask[FIELD_D >> 6] |= 1LL << (FIELD_D & 63); + char D_width = 1; + res->fields[FIELD_size] = (instr & 0x300000)>>20; + res->fields_mask[FIELD_size >> 6] |= 1LL << (FIELD_size & 63); + char size_width = 2; + res->fields[FIELD_Vn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Vn >> 6] |= 1LL << (FIELD_Vn & 63); + char Vn_width = 4; + res->fields[FIELD_Vd] = (instr & 0xF000)>>12; + res->fields_mask[FIELD_Vd >> 6] |= 1LL << (FIELD_Vd & 63); + char Vd_width = 4; + res->fields[FIELD_N] = (instr & 0x80)>>7; + res->fields_mask[FIELD_N >> 6] |= 1LL << (FIELD_N & 63); + char N_width = 1; + res->fields[FIELD_Q] = (instr & 0x40)>>6; + res->fields_mask[FIELD_Q >> 6] |= 1LL << (FIELD_Q & 63); + char Q_width = 1; + res->fields[FIELD_M] = (instr & 0x20)>>5; + res->fields_mask[FIELD_M >> 6] |= 1LL << (FIELD_M & 63); + char M_width = 1; + res->fields[FIELD_Vm] = instr & 0xF; + res->fields_mask[FIELD_Vm >> 6] |= 1LL << (FIELD_Vm & 63); + char Vm_width = 4; + + static const instruction_format instr_formats[] = + { + { /* VCGT<c>.<dt> <Dd>,<Dn>,<Dm> */ + "vcgt", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_VFP_DATA_SIZE, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_n,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_m,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + { /* VCGT<c>.<dt> <Qd>,<Qn>,<Qm> */ + "vcgt", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_VFP_DATA_SIZE, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"q","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_n,FIELD_UNINIT,"q","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_m,FIELD_UNINIT,"q","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 2; + res->mnem = armv7::ARMV7_VCGT; + + /* pcode: if (Q == '1' && (Vd<0> == '1' || Vn<0> == '1' || Vm<0> == '1')) then UNDEFINED */ + if((((res->fields[FIELD_Q]) == (0x1)) && ((((((res->fields[FIELD_Vd] & 1)) == (0x1)) || (((res->fields[FIELD_Vn] & 1)) == (0x1))) || (((res->fields[FIELD_Vm] & 1)) == (0x1)))))) { + res->status |= STATUS_UNDEFINED; + } + /* pcode: if size == '11' then UNDEFINED */ + if((res->fields[FIELD_size]) == (0x3)) { + res->status |= STATUS_UNDEFINED; + } + /* pcode: esize = 8 << UInt(size) */ + res->fields[FIELD_esize] = (8) << ((res->fields[FIELD_size])); + res->fields_mask[FIELD_esize >> 6] |= 1LL << (FIELD_esize & 63); + /* pcode: elements = 64 DIV esize */ + res->fields[FIELD_elements] = ((res->fields[FIELD_esize]) ? ((64) / (res->fields[FIELD_esize])) : 0); + res->fields_mask[FIELD_elements >> 6] |= 1LL << (FIELD_elements & 63); + /* pcode: d = UInt(D:Vd) */ + res->fields[FIELD_d] = ((res->fields[FIELD_D]<<Vd_width)|(res->fields[FIELD_Vd])); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: n = UInt(N:Vn) */ + res->fields[FIELD_n] = ((res->fields[FIELD_N]<<Vn_width)|(res->fields[FIELD_Vn])); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: m = UInt(M:Vm) */ + res->fields[FIELD_m] = ((res->fields[FIELD_M]<<Vm_width)|(res->fields[FIELD_Vm])); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + /* pcode: regs = if Q == '0' then 1 else 2 */ + if((res->fields[FIELD_Q]) == (0x0)) { + res->fields[FIELD_regs] = 1; + res->fields_mask[FIELD_regs >> 6] |= 1LL << (FIELD_regs & 63); + } + else { + res->fields[FIELD_regs] = 2; + res->fields_mask[FIELD_regs >> 6] |= 1LL << (FIELD_regs & 63); + } + /* pcode: unsigned = (U == '1') */ + res->fields[FIELD_unsigned] = ((res->fields[FIELD_U]) == (0x1)); + res->fields_mask[FIELD_unsigned >> 6] |= 1LL << (FIELD_unsigned & 63); + /* pcode: fmt_idx = (Q == '1') */ + res->fields[FIELD_fmt_idx] = ((res->fields[FIELD_Q]) == (0x1)); + res->fields_mask[FIELD_fmt_idx >> 6] |= 1LL << (FIELD_fmt_idx & 63); + /* pcode: dt = UInt(U:size) */ + res->fields[FIELD_dt] = ((res->fields[FIELD_U]<<size_width)|(res->fields[FIELD_size])); + res->fields_mask[FIELD_dt >> 6] |= 1LL << (FIELD_dt & 63); + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: 2ED105D8 +int vcle_immediate(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + res->group = INSN_GROUP_NEON; + /* Encoding T1 */ + /* pattern="1111,1111,1,D.1,11,size.2,01,Vd.4,0,F.1,011,Q.1,M.1,0,Vm.4" width=32 stringency=22 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFFB30B90)==0xFFB10180)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ADVSIMD)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_D] = (instr & 0x400000)>>22; + res->fields_mask[FIELD_D >> 6] |= 1LL << (FIELD_D & 63); + char D_width = 1; + res->fields[FIELD_size] = (instr & 0xC0000)>>18; + res->fields_mask[FIELD_size >> 6] |= 1LL << (FIELD_size & 63); + char size_width = 2; + res->fields[FIELD_Vd] = (instr & 0xF000)>>12; + res->fields_mask[FIELD_Vd >> 6] |= 1LL << (FIELD_Vd & 63); + char Vd_width = 4; + res->fields[FIELD_F] = (instr & 0x400)>>10; + res->fields_mask[FIELD_F >> 6] |= 1LL << (FIELD_F & 63); + char F_width = 1; + res->fields[FIELD_Q] = (instr & 0x40)>>6; + res->fields_mask[FIELD_Q >> 6] |= 1LL << (FIELD_Q & 63); + char Q_width = 1; + res->fields[FIELD_M] = (instr & 0x20)>>5; + res->fields_mask[FIELD_M >> 6] |= 1LL << (FIELD_M & 63); + char M_width = 1; + res->fields[FIELD_Vm] = instr & 0xF; + res->fields_mask[FIELD_Vm >> 6] |= 1LL << (FIELD_Vm & 63); + char Vm_width = 4; + + static const instruction_format instr_formats[] = + { + { /* VCLE<c>.<dt> <Dd>,<Dm>,#0 */ + "vcle", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_VFP_DATA_SIZE, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_m,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_ZERO,FIELD_UNINIT,FIELD_UNINIT,"#0","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + { /* VCLE<c>.<dt> <Qd>,<Qm>,#0 */ + "vcle", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_VFP_DATA_SIZE, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"q","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_m,FIELD_UNINIT,"q","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_ZERO,FIELD_UNINIT,FIELD_UNINIT,"#0","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 2; + res->mnem = armv7::ARMV7_VCLE; + + /* pcode: if (size == '11' || (F == '1' && size != '10')) then UNDEFINED */ + if((((res->fields[FIELD_size]) == (0x3)) || ((((res->fields[FIELD_F]) == (0x1)) && ((res->fields[FIELD_size]) != (0x2)))))) { + res->status |= STATUS_UNDEFINED; + } + /* pcode: if (Q == '1' && (Vd<0> == '1' || Vm<0> == '1')) then UNDEFINED */ + if((((res->fields[FIELD_Q]) == (0x1)) && (((((res->fields[FIELD_Vd] & 1)) == (0x1)) || (((res->fields[FIELD_Vm] & 1)) == (0x1)))))) { + res->status |= STATUS_UNDEFINED; + } + /* pcode: esize = 8 << UInt(size) */ + res->fields[FIELD_esize] = (8) << ((res->fields[FIELD_size])); + res->fields_mask[FIELD_esize >> 6] |= 1LL << (FIELD_esize & 63); + /* pcode: elements = 64 DIV esize */ + res->fields[FIELD_elements] = ((res->fields[FIELD_esize]) ? ((64) / (res->fields[FIELD_esize])) : 0); + res->fields_mask[FIELD_elements >> 6] |= 1LL << (FIELD_elements & 63); + /* pcode: d = UInt(D:Vd) */ + res->fields[FIELD_d] = ((res->fields[FIELD_D]<<Vd_width)|(res->fields[FIELD_Vd])); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: m = UInt(M:Vm) */ + res->fields[FIELD_m] = ((res->fields[FIELD_M]<<Vm_width)|(res->fields[FIELD_Vm])); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + /* pcode: regs = if Q == '0' then 1 else 2 */ + if((res->fields[FIELD_Q]) == (0x0)) { + res->fields[FIELD_regs] = 1; + res->fields_mask[FIELD_regs >> 6] |= 1LL << (FIELD_regs & 63); + } + else { + res->fields[FIELD_regs] = 2; + res->fields_mask[FIELD_regs >> 6] |= 1LL << (FIELD_regs & 63); + } + /* pcode: fmt_idx = (Q == '1') */ + res->fields[FIELD_fmt_idx] = ((res->fields[FIELD_Q]) == (0x1)); + res->fields_mask[FIELD_fmt_idx >> 6] |= 1LL << (FIELD_fmt_idx & 63); + /* pcode: dt = size + F */ + res->fields[FIELD_dt] = (res->fields[FIELD_size]) + (res->fields[FIELD_F]); + res->fields_mask[FIELD_dt >> 6] |= 1LL << (FIELD_dt & 63); + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: 750DF79F +int vcls(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + res->group = INSN_GROUP_NEON; + /* Encoding T1 */ + /* pattern="1111,xx11,1,D.1,11,size.2,00,Vd.4,0,1000,Q.1,M.1,0,Vm.4" width=32 stringency=20 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xF3B30F90)==0xF3B00400)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ADVSIMD)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_D] = (instr & 0x400000)>>22; + res->fields_mask[FIELD_D >> 6] |= 1LL << (FIELD_D & 63); + char D_width = 1; + res->fields[FIELD_size] = (instr & 0xC0000)>>18; + res->fields_mask[FIELD_size >> 6] |= 1LL << (FIELD_size & 63); + char size_width = 2; + res->fields[FIELD_Vd] = (instr & 0xF000)>>12; + res->fields_mask[FIELD_Vd >> 6] |= 1LL << (FIELD_Vd & 63); + char Vd_width = 4; + res->fields[FIELD_Q] = (instr & 0x40)>>6; + res->fields_mask[FIELD_Q >> 6] |= 1LL << (FIELD_Q & 63); + char Q_width = 1; + res->fields[FIELD_M] = (instr & 0x20)>>5; + res->fields_mask[FIELD_M >> 6] |= 1LL << (FIELD_M & 63); + char M_width = 1; + res->fields[FIELD_Vm] = instr & 0xF; + res->fields_mask[FIELD_Vm >> 6] |= 1LL << (FIELD_Vm & 63); + char Vm_width = 4; + + static const instruction_format instr_formats[] = + { + { /* VCLS<c>.<dt> <Dd>,<Dm> */ + "vcls", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_VFP_DATA_SIZE, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_m,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + { /* VCLS<c>.<dt> <Qd>,<Qm> */ + "vcls", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_VFP_DATA_SIZE, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"q","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_m,FIELD_UNINIT,"q","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 2; + res->mnem = armv7::ARMV7_VCLS; + + /* pcode: if size == '11' then UNDEFINED */ + if((res->fields[FIELD_size]) == (0x3)) { + res->status |= STATUS_UNDEFINED; + } + /* pcode: if Q == '1' && (Vd<0> == '1' || Vm<0> == '1') then UNDEFINED */ + if(((res->fields[FIELD_Q]) == (0x1)) && (((((res->fields[FIELD_Vd] & 1)) == (0x1)) || (((res->fields[FIELD_Vm] & 1)) == (0x1))))) { + res->status |= STATUS_UNDEFINED; + } + /* pcode: esize = 8 << UInt(size) */ + res->fields[FIELD_esize] = (8) << ((res->fields[FIELD_size])); + res->fields_mask[FIELD_esize >> 6] |= 1LL << (FIELD_esize & 63); + /* pcode: elements = 64 DIV esize */ + res->fields[FIELD_elements] = ((res->fields[FIELD_esize]) ? ((64) / (res->fields[FIELD_esize])) : 0); + res->fields_mask[FIELD_elements >> 6] |= 1LL << (FIELD_elements & 63); + /* pcode: d = UInt(D:Vd) */ + res->fields[FIELD_d] = ((res->fields[FIELD_D]<<Vd_width)|(res->fields[FIELD_Vd])); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: m = UInt(M:Vm) */ + res->fields[FIELD_m] = ((res->fields[FIELD_M]<<Vm_width)|(res->fields[FIELD_Vm])); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + /* pcode: regs = if Q == '0' then 1 else 2 */ + if((res->fields[FIELD_Q]) == (0x0)) { + res->fields[FIELD_regs] = 1; + res->fields_mask[FIELD_regs >> 6] |= 1LL << (FIELD_regs & 63); + } + else { + res->fields[FIELD_regs] = 2; + res->fields_mask[FIELD_regs >> 6] |= 1LL << (FIELD_regs & 63); + } + /* pcode: fmt_idx = (Q == '1') */ + res->fields[FIELD_fmt_idx] = ((res->fields[FIELD_Q]) == (0x1)); + res->fields_mask[FIELD_fmt_idx >> 6] |= 1LL << (FIELD_fmt_idx & 63); + /* pcode: dt = size */ + res->fields[FIELD_dt] = res->fields[FIELD_size]; + res->fields_mask[FIELD_dt >> 6] |= 1LL << (FIELD_dt & 63); + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: C885994F +int vclt_immediate(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + res->group = INSN_GROUP_NEON; + /* Encoding T1 */ + /* pattern="1111,1111,1,D.1,11,size.2,01,Vd.4,0,F.1,100,Q.1,M.1,0,Vm.4" width=32 stringency=22 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFFB30B90)==0xFFB10200)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ADVSIMD)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_D] = (instr & 0x400000)>>22; + res->fields_mask[FIELD_D >> 6] |= 1LL << (FIELD_D & 63); + char D_width = 1; + res->fields[FIELD_size] = (instr & 0xC0000)>>18; + res->fields_mask[FIELD_size >> 6] |= 1LL << (FIELD_size & 63); + char size_width = 2; + res->fields[FIELD_Vd] = (instr & 0xF000)>>12; + res->fields_mask[FIELD_Vd >> 6] |= 1LL << (FIELD_Vd & 63); + char Vd_width = 4; + res->fields[FIELD_F] = (instr & 0x400)>>10; + res->fields_mask[FIELD_F >> 6] |= 1LL << (FIELD_F & 63); + char F_width = 1; + res->fields[FIELD_Q] = (instr & 0x40)>>6; + res->fields_mask[FIELD_Q >> 6] |= 1LL << (FIELD_Q & 63); + char Q_width = 1; + res->fields[FIELD_M] = (instr & 0x20)>>5; + res->fields_mask[FIELD_M >> 6] |= 1LL << (FIELD_M & 63); + char M_width = 1; + res->fields[FIELD_Vm] = instr & 0xF; + res->fields_mask[FIELD_Vm >> 6] |= 1LL << (FIELD_Vm & 63); + char Vm_width = 4; + + static const instruction_format instr_formats[] = + { + { /* VCLT<c>.<dt> <Dd>,<Dm>,#0 */ + "vclt", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_VFP_DATA_SIZE, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_m,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_ZERO,FIELD_UNINIT,FIELD_UNINIT,"#0","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + { /* VCLT<c>.<dt> <Qd>,<Qm>,#0 */ + "vclt", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_VFP_DATA_SIZE, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"q","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_m,FIELD_UNINIT,"q","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_ZERO,FIELD_UNINIT,FIELD_UNINIT,"#0","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 2; + res->mnem = armv7::ARMV7_VCLT; + + /* pcode: if (size == '11' || (F == '1' && size != '10')) then UNDEFINED */ + if((((res->fields[FIELD_size]) == (0x3)) || ((((res->fields[FIELD_F]) == (0x1)) && ((res->fields[FIELD_size]) != (0x2)))))) { + res->status |= STATUS_UNDEFINED; + } + /* pcode: if (Q == '1' && (Vd<0> == '1' || Vm<0> == '1')) then UNDEFINED */ + if((((res->fields[FIELD_Q]) == (0x1)) && (((((res->fields[FIELD_Vd] & 1)) == (0x1)) || (((res->fields[FIELD_Vm] & 1)) == (0x1)))))) { + res->status |= STATUS_UNDEFINED; + } + /* pcode: esize = 8 << UInt(size) */ + res->fields[FIELD_esize] = (8) << ((res->fields[FIELD_size])); + res->fields_mask[FIELD_esize >> 6] |= 1LL << (FIELD_esize & 63); + /* pcode: elements = 64 DIV esize */ + res->fields[FIELD_elements] = ((res->fields[FIELD_esize]) ? ((64) / (res->fields[FIELD_esize])) : 0); + res->fields_mask[FIELD_elements >> 6] |= 1LL << (FIELD_elements & 63); + /* pcode: d = UInt(D:Vd) */ + res->fields[FIELD_d] = ((res->fields[FIELD_D]<<Vd_width)|(res->fields[FIELD_Vd])); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: m = UInt(M:Vm) */ + res->fields[FIELD_m] = ((res->fields[FIELD_M]<<Vm_width)|(res->fields[FIELD_Vm])); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + /* pcode: regs = if Q == '0' then 1 else 2 */ + if((res->fields[FIELD_Q]) == (0x0)) { + res->fields[FIELD_regs] = 1; + res->fields_mask[FIELD_regs >> 6] |= 1LL << (FIELD_regs & 63); + } + else { + res->fields[FIELD_regs] = 2; + res->fields_mask[FIELD_regs >> 6] |= 1LL << (FIELD_regs & 63); + } + /* pcode: fmt_idx = (Q == '1') */ + res->fields[FIELD_fmt_idx] = ((res->fields[FIELD_Q]) == (0x1)); + res->fields_mask[FIELD_fmt_idx >> 6] |= 1LL << (FIELD_fmt_idx & 63); + /* pcode: dt = size + F */ + res->fields[FIELD_dt] = (res->fields[FIELD_size]) + (res->fields[FIELD_F]); + res->fields_mask[FIELD_dt >> 6] |= 1LL << (FIELD_dt & 63); + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: A06735D8 +int vclz(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + res->group = INSN_GROUP_NEON; + /* Encoding T1 */ + /* pattern="1111,xx11,1,D.1,11,size.2,00,Vd.4,0,1001,Q.1,M.1,0,Vm.4" width=32 stringency=20 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xF3B30F90)==0xF3B00480)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ADVSIMD)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_D] = (instr & 0x400000)>>22; + res->fields_mask[FIELD_D >> 6] |= 1LL << (FIELD_D & 63); + char D_width = 1; + res->fields[FIELD_size] = (instr & 0xC0000)>>18; + res->fields_mask[FIELD_size >> 6] |= 1LL << (FIELD_size & 63); + char size_width = 2; + res->fields[FIELD_Vd] = (instr & 0xF000)>>12; + res->fields_mask[FIELD_Vd >> 6] |= 1LL << (FIELD_Vd & 63); + char Vd_width = 4; + res->fields[FIELD_Q] = (instr & 0x40)>>6; + res->fields_mask[FIELD_Q >> 6] |= 1LL << (FIELD_Q & 63); + char Q_width = 1; + res->fields[FIELD_M] = (instr & 0x20)>>5; + res->fields_mask[FIELD_M >> 6] |= 1LL << (FIELD_M & 63); + char M_width = 1; + res->fields[FIELD_Vm] = instr & 0xF; + res->fields_mask[FIELD_Vm >> 6] |= 1LL << (FIELD_Vm & 63); + char Vm_width = 4; + + static const instruction_format instr_formats[] = + { + { /* VCLZ<c>.<dt> <Dd>,<Dm> */ + "vclz", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_VFP_DATA_SIZE, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_m,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + { /* VCLZ<c>.<dt> <Qd>,<Qm> */ + "vclz", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_VFP_DATA_SIZE, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"q","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_m,FIELD_UNINIT,"q","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 2; + res->mnem = armv7::ARMV7_VCLZ; + + /* pcode: if size == '11' then UNDEFINED */ + if((res->fields[FIELD_size]) == (0x3)) { + res->status |= STATUS_UNDEFINED; + } + /* pcode: if Q == '1' && (Vd<0> == '1' || Vm<0> == '1') then UNDEFINED */ + if(((res->fields[FIELD_Q]) == (0x1)) && (((((res->fields[FIELD_Vd] & 1)) == (0x1)) || (((res->fields[FIELD_Vm] & 1)) == (0x1))))) { + res->status |= STATUS_UNDEFINED; + } + /* pcode: esize = 8 << UInt(size) */ + res->fields[FIELD_esize] = (8) << ((res->fields[FIELD_size])); + res->fields_mask[FIELD_esize >> 6] |= 1LL << (FIELD_esize & 63); + /* pcode: elements = 64 DIV esize */ + res->fields[FIELD_elements] = ((res->fields[FIELD_esize]) ? ((64) / (res->fields[FIELD_esize])) : 0); + res->fields_mask[FIELD_elements >> 6] |= 1LL << (FIELD_elements & 63); + /* pcode: d = UInt(D:Vd) */ + res->fields[FIELD_d] = ((res->fields[FIELD_D]<<Vd_width)|(res->fields[FIELD_Vd])); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: m = UInt(M:Vm) */ + res->fields[FIELD_m] = ((res->fields[FIELD_M]<<Vm_width)|(res->fields[FIELD_Vm])); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + /* pcode: regs = if Q == '0' then 1 else 2 */ + if((res->fields[FIELD_Q]) == (0x0)) { + res->fields[FIELD_regs] = 1; + res->fields_mask[FIELD_regs >> 6] |= 1LL << (FIELD_regs & 63); + } + else { + res->fields[FIELD_regs] = 2; + res->fields_mask[FIELD_regs >> 6] |= 1LL << (FIELD_regs & 63); + } + /* pcode: iword = TRUE */ + res->fields[FIELD_iword] = 1; + res->fields_mask[FIELD_iword >> 6] |= 1LL << (FIELD_iword & 63); + /* pcode: fmt_idx = (Q == '1') */ + res->fields[FIELD_fmt_idx] = ((res->fields[FIELD_Q]) == (0x1)); + res->fields_mask[FIELD_fmt_idx >> 6] |= 1LL << (FIELD_fmt_idx & 63); + /* pcode: dt = size */ + res->fields[FIELD_dt] = res->fields[FIELD_size]; + res->fields_mask[FIELD_dt >> 6] |= 1LL << (FIELD_dt & 63); + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: CDC8045C +int vcmp(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + res->group = INSN_GROUP_NEON; + /* Encoding T2 */ + /* pattern="1110,11101,D.1,11,0101,Vd.4,101,sz.1,E.1,1,(0),0,(0)(0)(0)(0)" width=32 stringency=28 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFFBF0E50)==0xEEB50A40)) { + res->instrSize = 32; + if(!((instr & 0x2F)==0x0)) { + res->flags |= FLAG_UNPREDICTABLE; + } + if(!(req->arch & ARCH_ADVSIMD)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_D] = (instr & 0x400000)>>22; + res->fields_mask[FIELD_D >> 6] |= 1LL << (FIELD_D & 63); + char D_width = 1; + res->fields[FIELD_Vd] = (instr & 0xF000)>>12; + res->fields_mask[FIELD_Vd >> 6] |= 1LL << (FIELD_Vd & 63); + char Vd_width = 4; + res->fields[FIELD_sz] = (instr & 0x100)>>8; + res->fields_mask[FIELD_sz >> 6] |= 1LL << (FIELD_sz & 63); + char sz_width = 1; + res->fields[FIELD_E] = (instr & 0x80)>>7; + res->fields_mask[FIELD_E >> 6] |= 1LL << (FIELD_E & 63); + char E_width = 1; + + static const instruction_format instr_formats[] = + { + { /* VCMP<c>.F32 <Sd>,#0 */ + "vcmp.f32", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_F32, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"s","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_ZERO,FIELD_UNINIT,FIELD_UNINIT,"#0","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + { /* VCMP<c>.F64 <Dd>,#0 */ + "vcmp.f64", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_F64, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_ZERO,FIELD_UNINIT,FIELD_UNINIT,"#0","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + { /* VCMPE<c>.F32 <Sd>,#0 */ + "vcmpe.f32", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_F32, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"s","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_ZERO,FIELD_UNINIT,FIELD_UNINIT,"#0","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + { /* VCMPE<c>.F64 <Dd>,#0 */ + "vcmpe.f64", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_F64, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_ZERO,FIELD_UNINIT,FIELD_UNINIT,"#0","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 4; + res->mnem = armv7::ARMV7_VCMP; + + /* pcode: dp_operation = (sz == '1') */ + res->fields[FIELD_dp_operation] = ((res->fields[FIELD_sz]) == (0x1)); + res->fields_mask[FIELD_dp_operation >> 6] |= 1LL << (FIELD_dp_operation & 63); + /* pcode: d = if dp_operation then UInt(D:Vd) else UInt(Vd:D) */ + if(res->fields[FIELD_dp_operation]) { + res->fields[FIELD_d] = ((res->fields[FIELD_D]<<Vd_width)|(res->fields[FIELD_Vd])); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + } + else { + res->fields[FIELD_d] = ((res->fields[FIELD_Vd]<<D_width)|(res->fields[FIELD_D])); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + } + /* pcode: fmt_idx = ((E == '1') * 2) + (sz == '1') */ + res->fields[FIELD_fmt_idx] = (((((res->fields[FIELD_E]) == (0x1))) * (2))) + (((res->fields[FIELD_sz]) == (0x1))); + res->fields_mask[FIELD_fmt_idx >> 6] |= 1LL << (FIELD_fmt_idx & 63); + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* Encoding T1 */ + /* pattern="1110,11101,D.1,11,0100,Vd.4,101,sz.1,E.1,1,M.1,0,Vm.4" width=32 stringency=24 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFFBF0E50)==0xEEB40A40)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ADVSIMD)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_D] = (instr & 0x400000)>>22; + res->fields_mask[FIELD_D >> 6] |= 1LL << (FIELD_D & 63); + char D_width = 1; + res->fields[FIELD_Vd] = (instr & 0xF000)>>12; + res->fields_mask[FIELD_Vd >> 6] |= 1LL << (FIELD_Vd & 63); + char Vd_width = 4; + res->fields[FIELD_sz] = (instr & 0x100)>>8; + res->fields_mask[FIELD_sz >> 6] |= 1LL << (FIELD_sz & 63); + char sz_width = 1; + res->fields[FIELD_E] = (instr & 0x80)>>7; + res->fields_mask[FIELD_E >> 6] |= 1LL << (FIELD_E & 63); + char E_width = 1; + res->fields[FIELD_M] = (instr & 0x20)>>5; + res->fields_mask[FIELD_M >> 6] |= 1LL << (FIELD_M & 63); + char M_width = 1; + res->fields[FIELD_Vm] = instr & 0xF; + res->fields_mask[FIELD_Vm >> 6] |= 1LL << (FIELD_Vm & 63); + char Vm_width = 4; + + static const instruction_format instr_formats[] = + { + { /* VCMP<c>.F32 <Sd>,<Sm> */ + "vcmp.f32", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_F32, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"s","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_m,FIELD_UNINIT,"s","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + { /* VCMP<c>.F64 <Dd>,<Dm> */ + "vcmp.f64", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_F64, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_m,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + { /* VCMPE<c>.F32 <Sd>,<Sm> */ + "vcmpe.f32", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_F32, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"s","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_m,FIELD_UNINIT,"s","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + { /* VCMPE<c>.F64 <Dd>,<Dm> */ + "vcmpe.f64", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_F64, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_m,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 4; + res->mnem = armv7::ARMV7_VCMP; + + /* pcode: dp_operation = (sz == '1') */ + res->fields[FIELD_dp_operation] = ((res->fields[FIELD_sz]) == (0x1)); + res->fields_mask[FIELD_dp_operation >> 6] |= 1LL << (FIELD_dp_operation & 63); + /* pcode: d = if dp_operation then UInt(D:Vd) else UInt(Vd:D) */ + if(res->fields[FIELD_dp_operation]) { + res->fields[FIELD_d] = ((res->fields[FIELD_D]<<Vd_width)|(res->fields[FIELD_Vd])); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + } + else { + res->fields[FIELD_d] = ((res->fields[FIELD_Vd]<<D_width)|(res->fields[FIELD_D])); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + } + /* pcode: m = if dp_operation then UInt(M:Vm) else UInt(Vm:M) */ + if(res->fields[FIELD_dp_operation]) { + res->fields[FIELD_m] = ((res->fields[FIELD_M]<<Vm_width)|(res->fields[FIELD_Vm])); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + } + else { + res->fields[FIELD_m] = ((res->fields[FIELD_Vm]<<M_width)|(res->fields[FIELD_M])); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + } + /* pcode: fmt_idx = ((E == '1') * 2) + (sz == '1') */ + res->fields[FIELD_fmt_idx] = (((((res->fields[FIELD_E]) == (0x1))) * (2))) + (((res->fields[FIELD_sz]) == (0x1))); + res->fields_mask[FIELD_fmt_idx >> 6] |= 1LL << (FIELD_fmt_idx & 63); + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: 00844EE8 +int vcnt(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + res->group = INSN_GROUP_NEON; + /* Encoding T1 */ + /* pattern="1111,xx11,1,D.1,11,size.2,00,Vd.4,0,1010,Q.1,M.1,0,Vm.4" width=32 stringency=20 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xF3B30F90)==0xF3B00500)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ADVSIMD)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_D] = (instr & 0x400000)>>22; + res->fields_mask[FIELD_D >> 6] |= 1LL << (FIELD_D & 63); + char D_width = 1; + res->fields[FIELD_size] = (instr & 0xC0000)>>18; + res->fields_mask[FIELD_size >> 6] |= 1LL << (FIELD_size & 63); + char size_width = 2; + res->fields[FIELD_Vd] = (instr & 0xF000)>>12; + res->fields_mask[FIELD_Vd >> 6] |= 1LL << (FIELD_Vd & 63); + char Vd_width = 4; + res->fields[FIELD_Q] = (instr & 0x40)>>6; + res->fields_mask[FIELD_Q >> 6] |= 1LL << (FIELD_Q & 63); + char Q_width = 1; + res->fields[FIELD_M] = (instr & 0x20)>>5; + res->fields_mask[FIELD_M >> 6] |= 1LL << (FIELD_M & 63); + char M_width = 1; + res->fields[FIELD_Vm] = instr & 0xF; + res->fields_mask[FIELD_Vm >> 6] |= 1LL << (FIELD_Vm & 63); + char Vm_width = 4; + + static const instruction_format instr_formats[] = + { + { /* VCNT<c>.8 <Dd>,<Dm> */ + "vcnt.8", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_m,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + { /* VCNT<c>.8 <Qd>,<Qm> */ + "vcnt.8", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"q","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_m,FIELD_UNINIT,"q","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 2; + res->mnem = armv7::ARMV7_VCNT; + + /* pcode: if size != '00' then UNDEFINED */ + if((res->fields[FIELD_size]) != (0x0)) { + res->status |= STATUS_UNDEFINED; + } + /* pcode: if Q == '1' && (Vd<0> == '1' || Vm<0> == '1') then UNDEFINED */ + if(((res->fields[FIELD_Q]) == (0x1)) && (((((res->fields[FIELD_Vd] & 1)) == (0x1)) || (((res->fields[FIELD_Vm] & 1)) == (0x1))))) { + res->status |= STATUS_UNDEFINED; + } + /* pcode: esize = 8 */ + res->fields[FIELD_esize] = 8; + res->fields_mask[FIELD_esize >> 6] |= 1LL << (FIELD_esize & 63); + /* pcode: elements = 8 */ + res->fields[FIELD_elements] = 8; + res->fields_mask[FIELD_elements >> 6] |= 1LL << (FIELD_elements & 63); + /* pcode: d = UInt(D:Vd) */ + res->fields[FIELD_d] = ((res->fields[FIELD_D]<<Vd_width)|(res->fields[FIELD_Vd])); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: m = UInt(M:Vm) */ + res->fields[FIELD_m] = ((res->fields[FIELD_M]<<Vm_width)|(res->fields[FIELD_Vm])); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + /* pcode: regs = if Q == '0' then 1 else 2 */ + if((res->fields[FIELD_Q]) == (0x0)) { + res->fields[FIELD_regs] = 1; + res->fields_mask[FIELD_regs >> 6] |= 1LL << (FIELD_regs & 63); + } + else { + res->fields[FIELD_regs] = 2; + res->fields_mask[FIELD_regs >> 6] |= 1LL << (FIELD_regs & 63); + } + /* pcode: fmt_idx = (Q == '1') */ + res->fields[FIELD_fmt_idx] = ((res->fields[FIELD_Q]) == (0x1)); + res->fields_mask[FIELD_fmt_idx >> 6] |= 1LL << (FIELD_fmt_idx & 63); + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: AC1F246B +int vcvt_double_single(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + res->group = INSN_GROUP_NEON; + /* Encoding T1 */ + /* pattern="1110,1110,1,D.1,11,011,1,Vd.4,101,sz.1,1,1,M.1,0,Vm.4" width=32 stringency=24 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFFBF0ED0)==0xEEB70AC0)) { + res->instrSize = 32; + if(!(req->arch & ARCH_VFPv2) && !(req->arch & ARCH_VFPv3)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_D] = (instr & 0x400000)>>22; + res->fields_mask[FIELD_D >> 6] |= 1LL << (FIELD_D & 63); + char D_width = 1; + res->fields[FIELD_Vd] = (instr & 0xF000)>>12; + res->fields_mask[FIELD_Vd >> 6] |= 1LL << (FIELD_Vd & 63); + char Vd_width = 4; + res->fields[FIELD_sz] = (instr & 0x100)>>8; + res->fields_mask[FIELD_sz >> 6] |= 1LL << (FIELD_sz & 63); + char sz_width = 1; + res->fields[FIELD_M] = (instr & 0x20)>>5; + res->fields_mask[FIELD_M >> 6] |= 1LL << (FIELD_M & 63); + char M_width = 1; + res->fields[FIELD_Vm] = instr & 0xF; + res->fields_mask[FIELD_Vm >> 6] |= 1LL << (FIELD_Vm & 63); + char Vm_width = 4; + + static const instruction_format instr_formats[] = + { + { /* VCVT<c>.F64.F32 <Dd>,<Sm> */ + "vcvt.f64.f32", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_m,FIELD_UNINIT,"s","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + { /* VCVT<c>.F32.F64 <Sd>,<Dm> */ + "vcvt.f32.f64", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"s","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_m,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 2; + res->mnem = armv7::ARMV7_VCVT; + + /* pcode: double_to_single = (sz == '1') */ + res->fields[FIELD_double_to_single] = ((res->fields[FIELD_sz]) == (0x1)); + res->fields_mask[FIELD_double_to_single >> 6] |= 1LL << (FIELD_double_to_single & 63); + /* pcode: d = if double_to_single then UInt(Vd:D) else UInt(D:Vd) */ + if(res->fields[FIELD_double_to_single]) { + res->fields[FIELD_d] = ((res->fields[FIELD_Vd]<<D_width)|(res->fields[FIELD_D])); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + } + else { + res->fields[FIELD_d] = ((res->fields[FIELD_D]<<Vd_width)|(res->fields[FIELD_Vd])); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + } + /* pcode: m = if double_to_single then UInt(M:Vm) else UInt(Vm:M) */ + if(res->fields[FIELD_double_to_single]) { + res->fields[FIELD_m] = ((res->fields[FIELD_M]<<Vm_width)|(res->fields[FIELD_Vm])); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + } + else { + res->fields[FIELD_m] = ((res->fields[FIELD_Vm]<<M_width)|(res->fields[FIELD_M])); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + } + /* pcode: fmt_idx = double_to_single */ + res->fields[FIELD_fmt_idx] = res->fields[FIELD_double_to_single]; + res->fields_mask[FIELD_fmt_idx >> 6] |= 1LL << (FIELD_fmt_idx & 63); + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: 05BDBCC8 +int vcvt_float_fixed(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + res->group = INSN_GROUP_NEON; + /* Encoding T2 */ + /* pattern="1110,1110,1,D.1,11,1,op.1,1,U.1,Vd.4,101,sf.1,sx.1,1,i.1,0,imm4.4" width=32 stringency=24 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFFBA0E50)==0xEEBA0A40)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ADVSIMD)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_D] = (instr & 0x400000)>>22; + res->fields_mask[FIELD_D >> 6] |= 1LL << (FIELD_D & 63); + char D_width = 1; + res->fields[FIELD_op] = (instr & 0x40000)>>18; + res->fields_mask[FIELD_op >> 6] |= 1LL << (FIELD_op & 63); + char op_width = 1; + res->fields[FIELD_U] = (instr & 0x10000)>>16; + res->fields_mask[FIELD_U >> 6] |= 1LL << (FIELD_U & 63); + char U_width = 1; + res->fields[FIELD_Vd] = (instr & 0xF000)>>12; + res->fields_mask[FIELD_Vd >> 6] |= 1LL << (FIELD_Vd & 63); + char Vd_width = 4; + res->fields[FIELD_sf] = (instr & 0x100)>>8; + res->fields_mask[FIELD_sf >> 6] |= 1LL << (FIELD_sf & 63); + char sf_width = 1; + res->fields[FIELD_sx] = (instr & 0x80)>>7; + res->fields_mask[FIELD_sx >> 6] |= 1LL << (FIELD_sx & 63); + char sx_width = 1; + res->fields[FIELD_i] = (instr & 0x20)>>5; + res->fields_mask[FIELD_i >> 6] |= 1LL << (FIELD_i & 63); + char i_width = 1; + res->fields[FIELD_imm4] = instr & 0xF; + res->fields_mask[FIELD_imm4 >> 6] |= 1LL << (FIELD_imm4 & 63); + char imm4_width = 4; + + static const instruction_format instr_formats[] = + { + { /* VCVT<c>.F32.<dt> <Sd>,<Sd>,#<imm> */ + "vcvt.f32", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_VFP_DATA_SIZE|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_F32, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"s","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"s","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_IMM,FIELD_imm,FIELD_UNINIT,"#","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + { /* VCVT<c>.F64.<dt> <Dd>,<Dd>,#<imm> */ + "vcvt.f64", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_VFP_DATA_SIZE|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_F64, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_IMM,FIELD_imm,FIELD_UNINIT,"#","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + { /* VCVT<c>.<dt> <Sd>,<Sd>,#<imm> */ + "vcvt", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_VFP_DATA_SIZE, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"s","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"s","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_IMM,FIELD_imm,FIELD_UNINIT,"#","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + { /* VCVT<c>.<dt> <Dd>,<Dd>,#<imm> */ + "vcvt", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_VFP_DATA_SIZE, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_IMM,FIELD_imm,FIELD_UNINIT,"#","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 4; + res->mnem = armv7::ARMV7_VCVT; + + /* pcode: to_fixed = (op == '1') */ + res->fields[FIELD_to_fixed] = ((res->fields[FIELD_op]) == (0x1)); + res->fields_mask[FIELD_to_fixed >> 6] |= 1LL << (FIELD_to_fixed & 63); + /* pcode: dp_operation = (sf == '1') */ + res->fields[FIELD_dp_operation] = ((res->fields[FIELD_sf]) == (0x1)); + res->fields_mask[FIELD_dp_operation >> 6] |= 1LL << (FIELD_dp_operation & 63); + /* pcode: unsigned = (U == '1') */ + res->fields[FIELD_unsigned] = ((res->fields[FIELD_U]) == (0x1)); + res->fields_mask[FIELD_unsigned >> 6] |= 1LL << (FIELD_unsigned & 63); + /* pcode: size = (sx * 16) + 16 */ + res->fields[FIELD_size] = (((res->fields[FIELD_sx]) * (16))) + (16); + res->fields_mask[FIELD_size >> 6] |= 1LL << (FIELD_size & 63); + /* pcode: imm = size - UInt(imm4:i) */ + res->fields[FIELD_imm] = (res->fields[FIELD_size]) - (((res->fields[FIELD_imm4]<<i_width)|(res->fields[FIELD_i]))); + res->fields_mask[FIELD_imm >> 6] |= 1LL << (FIELD_imm & 63); + /* pcode: d = if dp_operation then UInt(D:Vd) else UInt(Vd:D) */ + if(res->fields[FIELD_dp_operation]) { + res->fields[FIELD_d] = ((res->fields[FIELD_D]<<Vd_width)|(res->fields[FIELD_Vd])); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + } + else { + res->fields[FIELD_d] = ((res->fields[FIELD_Vd]<<D_width)|(res->fields[FIELD_D])); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + } + /* pcode: if size < UInt(imm4:i) then UNPREDICTABLE */ + if((res->fields[FIELD_size]) < (((res->fields[FIELD_imm4]<<i_width)|(res->fields[FIELD_i])))) { + res->flags |= FLAG_UNPREDICTABLE; + } + /* pcode: fmt_idx = (op * 2) + sf */ + res->fields[FIELD_fmt_idx] = (((res->fields[FIELD_op]) * (2))) + (res->fields[FIELD_sf]); + res->fields_mask[FIELD_fmt_idx >> 6] |= 1LL << (FIELD_fmt_idx & 63); + /* pcode: if fmt_idx > 1 then dt_suffix = sf */ + if((res->fields[FIELD_fmt_idx]) > (1)) { + res->fields[FIELD_dt_suffix] = res->fields[FIELD_sf]; + res->fields_mask[FIELD_dt_suffix >> 6] |= 1LL << (FIELD_dt_suffix & 63); + } + /* pcode: dt = 1 + sx + (U * 4) */ + res->fields[FIELD_dt] = ((1) + (res->fields[FIELD_sx])) + (((res->fields[FIELD_U]) * (4))); + res->fields_mask[FIELD_dt >> 6] |= 1LL << (FIELD_dt & 63); + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* Encoding T1 */ + /* pattern="111,U.1,1111,1,D.1,imm6.6,Vd.4,111,op.1,0,Q.1,M.1,1,Vm.4" width=32 stringency=18 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xEF800E90)==0xEF800E10)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ADVSIMD)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_U] = (instr & 0x10000000)>>28; + res->fields_mask[FIELD_U >> 6] |= 1LL << (FIELD_U & 63); + char U_width = 1; + res->fields[FIELD_D] = (instr & 0x400000)>>22; + res->fields_mask[FIELD_D >> 6] |= 1LL << (FIELD_D & 63); + char D_width = 1; + res->fields[FIELD_imm6] = (instr & 0x3F0000)>>16; + res->fields_mask[FIELD_imm6 >> 6] |= 1LL << (FIELD_imm6 & 63); + char imm6_width = 6; + res->fields[FIELD_Vd] = (instr & 0xF000)>>12; + res->fields_mask[FIELD_Vd >> 6] |= 1LL << (FIELD_Vd & 63); + char Vd_width = 4; + res->fields[FIELD_op] = (instr & 0x100)>>8; + res->fields_mask[FIELD_op >> 6] |= 1LL << (FIELD_op & 63); + char op_width = 1; + res->fields[FIELD_Q] = (instr & 0x40)>>6; + res->fields_mask[FIELD_Q >> 6] |= 1LL << (FIELD_Q & 63); + char Q_width = 1; + res->fields[FIELD_M] = (instr & 0x20)>>5; + res->fields_mask[FIELD_M >> 6] |= 1LL << (FIELD_M & 63); + char M_width = 1; + res->fields[FIELD_Vm] = instr & 0xF; + res->fields_mask[FIELD_Vm >> 6] |= 1LL << (FIELD_Vm & 63); + char Vm_width = 4; + + static const instruction_format instr_formats[] = + { + { /* VCVT<c>.<dt> <Dd>,<Dm>,#<fbits> */ + "vcvt", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_VFP_DATA_SIZE, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_m,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_IMM,FIELD_fbits,FIELD_UNINIT,"#","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + { /* VCVT<c>.<dt> <Qd>,<Qm>,#<fbits> */ + "vcvt", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_VFP_DATA_SIZE, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"q","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_m,FIELD_UNINIT,"q","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_IMM,FIELD_fbits,FIELD_UNINIT,"#","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 2; + res->mnem = armv7::ARMV7_VCVT; + + /* pcode: if Q == '1' && (Vd<0> == '1' || Vm<0> == '1') then UNDEFINED */ + if(((res->fields[FIELD_Q]) == (0x1)) && (((((res->fields[FIELD_Vd] & 1)) == (0x1)) || (((res->fields[FIELD_Vm] & 1)) == (0x1))))) { + res->status |= STATUS_UNDEFINED; + } + /* pcode: to_fixed = (op == '1') */ + res->fields[FIELD_to_fixed] = ((res->fields[FIELD_op]) == (0x1)); + res->fields_mask[FIELD_to_fixed >> 6] |= 1LL << (FIELD_to_fixed & 63); + /* pcode: unsigned = (U == '1') */ + res->fields[FIELD_unsigned] = ((res->fields[FIELD_U]) == (0x1)); + res->fields_mask[FIELD_unsigned >> 6] |= 1LL << (FIELD_unsigned & 63); + /* pcode: if to_fixed == TRUE then round_zero = TRUE else round_nearest = TRUE */ + if((res->fields[FIELD_to_fixed]) == (1)) { + res->fields[FIELD_round_zero] = 1; + res->fields_mask[FIELD_round_zero >> 6] |= 1LL << (FIELD_round_zero & 63); + } + else { + res->fields[FIELD_round_nearest] = 1; + res->fields_mask[FIELD_round_nearest >> 6] |= 1LL << (FIELD_round_nearest & 63); + } + /* pcode: esize = 32 */ + res->fields[FIELD_esize] = 32; + res->fields_mask[FIELD_esize >> 6] |= 1LL << (FIELD_esize & 63); + /* pcode: fbits = 64 - UInt(imm6) */ + res->fields[FIELD_fbits] = (64) - ((res->fields[FIELD_imm6])); + res->fields_mask[FIELD_fbits >> 6] |= 1LL << (FIELD_fbits & 63); + /* pcode: elements = 2 */ + res->fields[FIELD_elements] = 2; + res->fields_mask[FIELD_elements >> 6] |= 1LL << (FIELD_elements & 63); + /* pcode: d = UInt(D:Vd) */ + res->fields[FIELD_d] = ((res->fields[FIELD_D]<<Vd_width)|(res->fields[FIELD_Vd])); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: m = UInt(M:Vm) */ + res->fields[FIELD_m] = ((res->fields[FIELD_M]<<Vm_width)|(res->fields[FIELD_Vm])); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + /* pcode: regs = if Q == '0' then 1 else 2 */ + if((res->fields[FIELD_Q]) == (0x0)) { + res->fields[FIELD_regs] = 1; + res->fields_mask[FIELD_regs >> 6] |= 1LL << (FIELD_regs & 63); + } + else { + res->fields[FIELD_regs] = 2; + res->fields_mask[FIELD_regs >> 6] |= 1LL << (FIELD_regs & 63); + } + /* pcode: td = TRUE */ + res->fields[FIELD_td] = 1; + res->fields_mask[FIELD_td >> 6] |= 1LL << (FIELD_td & 63); + /* pcode: fmt_idx = (Q == '1') */ + res->fields[FIELD_fmt_idx] = ((res->fields[FIELD_Q]) == (0x1)); + res->fields_mask[FIELD_fmt_idx >> 6] |= 1LL << (FIELD_fmt_idx & 63); + /* pcode: dt = UInt(op:U) */ + res->fields[FIELD_dt] = ((res->fields[FIELD_op]<<U_width)|(res->fields[FIELD_U])); + res->fields_mask[FIELD_dt >> 6] |= 1LL << (FIELD_dt & 63); + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: 3CB799A8 +int vcvt_float_int(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + res->group = INSN_GROUP_NEON; + /* Encoding T2 */ + /* pattern="1110,11101,D.1,11,1,opc1.1,opc2.1,opc3.1,Vd.4,101,sz.1,op.1,1,M.1,0,Vm.4" width=32 stringency=25 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFFB80E50)==0xEEB80A40)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ADVSIMD)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_D] = (instr & 0x400000)>>22; + res->fields_mask[FIELD_D >> 6] |= 1LL << (FIELD_D & 63); + char D_width = 1; + res->fields[FIELD_opc1] = (instr & 0x40000)>>18; + res->fields_mask[FIELD_opc1 >> 6] |= 1LL << (FIELD_opc1 & 63); + char opc1_width = 1; + res->fields[FIELD_opc2] = (instr & 0x20000)>>17; + res->fields_mask[FIELD_opc2 >> 6] |= 1LL << (FIELD_opc2 & 63); + char opc2_width = 1; + res->fields[FIELD_opc3] = (instr & 0x10000)>>16; + res->fields_mask[FIELD_opc3 >> 6] |= 1LL << (FIELD_opc3 & 63); + char opc3_width = 1; + res->fields[FIELD_Vd] = (instr & 0xF000)>>12; + res->fields_mask[FIELD_Vd >> 6] |= 1LL << (FIELD_Vd & 63); + char Vd_width = 4; + res->fields[FIELD_sz] = (instr & 0x100)>>8; + res->fields_mask[FIELD_sz >> 6] |= 1LL << (FIELD_sz & 63); + char sz_width = 1; + res->fields[FIELD_op] = (instr & 0x80)>>7; + res->fields_mask[FIELD_op >> 6] |= 1LL << (FIELD_op & 63); + char op_width = 1; + res->fields[FIELD_M] = (instr & 0x20)>>5; + res->fields_mask[FIELD_M >> 6] |= 1LL << (FIELD_M & 63); + char M_width = 1; + res->fields[FIELD_Vm] = instr & 0xF; + res->fields_mask[FIELD_Vm >> 6] |= 1LL << (FIELD_Vm & 63); + char Vm_width = 4; + + static const instruction_format instr_formats[] = + { + { /* VCVT<c>.F32.<dt> <Sd>,<Sm> */ + "vcvt.f32", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_VFP_DATA_SIZE|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_F32, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"s","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_m,FIELD_UNINIT,"s","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + { /* VCVT<c>.F64.<dt> <Dd>,<Sm> */ + "vcvt.f64", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_VFP_DATA_SIZE|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_F64, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_m,FIELD_UNINIT,"s","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + { /* VCVT<c>.U32.F32 <Sd>,<Sm> */ + "vcvt.u32.f32", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"s","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_m,FIELD_UNINIT,"s","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + { /* VCVT<c>.U32.F64 <Sd>,<Dm> */ + "vcvt.u32.f64", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"s","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_m,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + { /* VCVT<c>.S32.F32 <Sd>,<Sm> */ + "vcvt.s32.f32", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"s","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_m,FIELD_UNINIT,"s","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + { /* VCVT<c>.S32.F64 <Sd>,<Dm> */ + "vcvt.s32.f64", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"s","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_m,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + { /* VCVTR<c>.U32.F32 <Sd>,<Sm> */ + "vcvtr.u32.f32", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"s","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_m,FIELD_UNINIT,"s","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + { /* VCVTR<c>.U32.F64 <Sd>,<Dm> */ + "vcvtr.u32.f64", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"s","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_m,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + { /* VCVTR<c>.S32.F32 <Sd>,<Sm> */ + "vcvtr.s32.f32", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"s","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_m,FIELD_UNINIT,"s","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + { /* VCVTR<c>.S32.F64 <Sd>,<Dm> */ + "vcvtr.s32.f64", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"s","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_m,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 10; + res->mnem = armv7::ARMV7_VCVT; + + /* pcode: to_integer = (opc1 == '1') */ + res->fields[FIELD_to_integer] = ((res->fields[FIELD_opc1]) == (0x1)); + res->fields_mask[FIELD_to_integer >> 6] |= 1LL << (FIELD_to_integer & 63); + /* pcode: dp_operation = (sz == 1) */ + res->fields[FIELD_dp_operation] = ((res->fields[FIELD_sz]) == (1)); + res->fields_mask[FIELD_dp_operation >> 6] |= 1LL << (FIELD_dp_operation & 63); + /* pcode: unsigned = (op == '0') */ + res->fields[FIELD_unsigned] = ((res->fields[FIELD_op]) == (0x0)); + res->fields_mask[FIELD_unsigned >> 6] |= 1LL << (FIELD_unsigned & 63); + /* pcode: m = UInt(Vm:M) */ + res->fields[FIELD_m] = ((res->fields[FIELD_Vm]<<M_width)|(res->fields[FIELD_M])); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + /* pcode: d = if dp_operation then UInt(D:Vd) else UInt(Vd:D) */ + if(res->fields[FIELD_dp_operation]) { + res->fields[FIELD_d] = ((res->fields[FIELD_D]<<Vd_width)|(res->fields[FIELD_Vd])); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + } + else { + res->fields[FIELD_d] = ((res->fields[FIELD_Vd]<<D_width)|(res->fields[FIELD_D])); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + } + /* pcode: if (to_integer) then unsigned = (opc1 == '0') */ + if((res->fields[FIELD_to_integer])) { + res->fields[FIELD_unsigned] = ((res->fields[FIELD_opc1]) == (0x0)); + res->fields_mask[FIELD_unsigned >> 6] |= 1LL << (FIELD_unsigned & 63); + } + /* pcode: if (to_integer) then d = UInt(Vd:D) */ + if((res->fields[FIELD_to_integer])) { + res->fields[FIELD_d] = ((res->fields[FIELD_Vd]<<D_width)|(res->fields[FIELD_D])); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + } + /* pcode: if (to_integer) then m = if dp_operation then UInt(M:Vm) else UInt(Vm:M) */ + if((res->fields[FIELD_to_integer])) { + if(res->fields[FIELD_dp_operation]) { + res->fields[FIELD_m] = ((res->fields[FIELD_M]<<Vm_width)|(res->fields[FIELD_Vm])); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + } + else { + res->fields[FIELD_m] = ((res->fields[FIELD_Vm]<<M_width)|(res->fields[FIELD_M])); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + }; + } + /* pcode: fmt_idx = ((op == '0') * 4) + (opc3 * 2) + sz + 2 */ + res->fields[FIELD_fmt_idx] = (((((((res->fields[FIELD_op]) == (0x0))) * (4))) + (((res->fields[FIELD_opc3]) * (2)))) + (res->fields[FIELD_sz])) + (2); + res->fields_mask[FIELD_fmt_idx >> 6] |= 1LL << (FIELD_fmt_idx & 63); + /* pcode: if (opc1 == '0') then fmt_idx = sz */ + if((res->fields[FIELD_opc1]) == 0x0) { + res->fields[FIELD_fmt_idx] = res->fields[FIELD_sz]; + res->fields_mask[FIELD_fmt_idx >> 6] |= 1LL << (FIELD_fmt_idx & 63); + } + /* pcode: dt = ((op == '0') * 4) + 2 */ + res->fields[FIELD_dt] = (((((res->fields[FIELD_op]) == (0x0))) * (4))) + (2); + res->fields_mask[FIELD_dt >> 6] |= 1LL << (FIELD_dt & 63); + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* Encoding T1 */ + /* pattern="1111,xx11,1,D.1,11,size.2,11,Vd.4,0,11,op.2,Q.1,M.1,0,Vm.4" width=32 stringency=18 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xF3B30E10)==0xF3B30600)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ADVSIMD)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_D] = (instr & 0x400000)>>22; + res->fields_mask[FIELD_D >> 6] |= 1LL << (FIELD_D & 63); + char D_width = 1; + res->fields[FIELD_size] = (instr & 0xC0000)>>18; + res->fields_mask[FIELD_size >> 6] |= 1LL << (FIELD_size & 63); + char size_width = 2; + res->fields[FIELD_Vd] = (instr & 0xF000)>>12; + res->fields_mask[FIELD_Vd >> 6] |= 1LL << (FIELD_Vd & 63); + char Vd_width = 4; + res->fields[FIELD_op] = (instr & 0x180)>>7; + res->fields_mask[FIELD_op >> 6] |= 1LL << (FIELD_op & 63); + char op_width = 2; + res->fields[FIELD_Q] = (instr & 0x40)>>6; + res->fields_mask[FIELD_Q >> 6] |= 1LL << (FIELD_Q & 63); + char Q_width = 1; + res->fields[FIELD_M] = (instr & 0x20)>>5; + res->fields_mask[FIELD_M >> 6] |= 1LL << (FIELD_M & 63); + char M_width = 1; + res->fields[FIELD_Vm] = instr & 0xF; + res->fields_mask[FIELD_Vm >> 6] |= 1LL << (FIELD_Vm & 63); + char Vm_width = 4; + + static const instruction_format instr_formats[] = + { + { /* VCVT<c>.<dt> <Dd>,<Dm> */ + "vcvt", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_VFP_DATA_SIZE, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_m,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + { /* VCVT<c>.<dt> <Qd>,<Qm> */ + "vcvt", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_VFP_DATA_SIZE, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"q","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_m,FIELD_UNINIT,"q","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 2; + res->mnem = armv7::ARMV7_VCVT; + + /* pcode: if Q == '1' && (Vd<0> == '1' || Vm<0> == '1') then UNDEFINED */ + if(((res->fields[FIELD_Q]) == (0x1)) && (((((res->fields[FIELD_Vd] & 1)) == (0x1)) || (((res->fields[FIELD_Vm] & 1)) == (0x1))))) { + res->status |= STATUS_UNDEFINED; + } + /* pcode: if size != '10' then UNDEFINED */ + if((res->fields[FIELD_size]) != (0x2)) { + res->status |= STATUS_UNDEFINED; + } + /* pcode: to_integer = (op == '10' || op == '11') */ + res->fields[FIELD_to_integer] = (((res->fields[FIELD_op]) == (0x2)) || ((res->fields[FIELD_op]) == (0x3))); + res->fields_mask[FIELD_to_integer >> 6] |= 1LL << (FIELD_to_integer & 63); + /* pcode: unsigned = (op == '01' || op == '11') */ + res->fields[FIELD_unsigned] = (((res->fields[FIELD_op]) == (0x1)) || ((res->fields[FIELD_op]) == (0x3))); + res->fields_mask[FIELD_unsigned >> 6] |= 1LL << (FIELD_unsigned & 63); + /* pcode: esize = 32 */ + res->fields[FIELD_esize] = 32; + res->fields_mask[FIELD_esize >> 6] |= 1LL << (FIELD_esize & 63); + /* pcode: elements = 2 */ + res->fields[FIELD_elements] = 2; + res->fields_mask[FIELD_elements >> 6] |= 1LL << (FIELD_elements & 63); + /* pcode: round_nearest = (to_integer == FALSE) */ + res->fields[FIELD_round_nearest] = ((res->fields[FIELD_to_integer]) == (0)); + res->fields_mask[FIELD_round_nearest >> 6] |= 1LL << (FIELD_round_nearest & 63); + /* pcode: round_zero = to_integer */ + res->fields[FIELD_round_zero] = res->fields[FIELD_to_integer]; + res->fields_mask[FIELD_round_zero >> 6] |= 1LL << (FIELD_round_zero & 63); + /* pcode: d = UInt(D:Vd) */ + res->fields[FIELD_d] = ((res->fields[FIELD_D]<<Vd_width)|(res->fields[FIELD_Vd])); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: m = UInt(M:Vm) */ + res->fields[FIELD_m] = ((res->fields[FIELD_M]<<Vm_width)|(res->fields[FIELD_Vm])); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + /* pcode: regs = if Q == '0' then 1 else 2 */ + if((res->fields[FIELD_Q]) == (0x0)) { + res->fields[FIELD_regs] = 1; + res->fields_mask[FIELD_regs >> 6] |= 1LL << (FIELD_regs & 63); + } + else { + res->fields[FIELD_regs] = 2; + res->fields_mask[FIELD_regs >> 6] |= 1LL << (FIELD_regs & 63); + } + /* pcode: td = TRUE */ + res->fields[FIELD_td] = 1; + res->fields_mask[FIELD_td >> 6] |= 1LL << (FIELD_td & 63); + /* pcode: fmt_idx = (Q == '1') */ + res->fields[FIELD_fmt_idx] = ((res->fields[FIELD_Q]) == (0x1)); + res->fields_mask[FIELD_fmt_idx >> 6] |= 1LL << (FIELD_fmt_idx & 63); + /* pcode: dt = UInt(op) */ + res->fields[FIELD_dt] = (res->fields[FIELD_op]); + res->fields_mask[FIELD_dt >> 6] |= 1LL << (FIELD_dt & 63); + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: 24E377AF +int vcvt_half_single(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + res->group = INSN_GROUP_NEON; + /* Encoding T1 */ + /* pattern="1111,xx11,1,D.1,11,size.2,10,Vd.4,011,op.1,0,0,M.1,0,Vm.4" width=32 stringency=20 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xF3B30ED0)==0xF3B20600)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ADVSIMD)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_D] = (instr & 0x400000)>>22; + res->fields_mask[FIELD_D >> 6] |= 1LL << (FIELD_D & 63); + char D_width = 1; + res->fields[FIELD_size] = (instr & 0xC0000)>>18; + res->fields_mask[FIELD_size >> 6] |= 1LL << (FIELD_size & 63); + char size_width = 2; + res->fields[FIELD_Vd] = (instr & 0xF000)>>12; + res->fields_mask[FIELD_Vd >> 6] |= 1LL << (FIELD_Vd & 63); + char Vd_width = 4; + res->fields[FIELD_op] = (instr & 0x100)>>8; + res->fields_mask[FIELD_op >> 6] |= 1LL << (FIELD_op & 63); + char op_width = 1; + res->fields[FIELD_M] = (instr & 0x20)>>5; + res->fields_mask[FIELD_M >> 6] |= 1LL << (FIELD_M & 63); + char M_width = 1; + res->fields[FIELD_Vm] = instr & 0xF; + res->fields_mask[FIELD_Vm >> 6] |= 1LL << (FIELD_Vm & 63); + char Vm_width = 4; + + static const instruction_format instr_formats[] = + { + { /* VCVT<c>.F16.F32 <Dd>,<Qm> */ + "vcvt.f16.f32", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_m,FIELD_UNINIT,"q","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + { /* VCVT<c>.F32.F16 <Qd>,<Dm> */ + "vcvt.f32.f16", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"q","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_m,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 2; + res->mnem = armv7::ARMV7_VCVT; + + /* pcode: half_to_single = (op == '1') */ + res->fields[FIELD_half_to_single] = ((res->fields[FIELD_op]) == (0x1)); + res->fields_mask[FIELD_half_to_single >> 6] |= 1LL << (FIELD_half_to_single & 63); + /* pcode: if size != '01' then UNDEFINED */ + if((res->fields[FIELD_size]) != (0x1)) { + res->status |= STATUS_UNDEFINED; + } + /* pcode: if (half_to_single == TRUE && Vd<0> == '1') then UNDEFINED */ + if((((res->fields[FIELD_half_to_single]) == (1)) && (((res->fields[FIELD_Vd] & 1)) == (0x1)))) { + res->status |= STATUS_UNDEFINED; + } + /* pcode: if (half_to_single == FALSE && Vm<0> == '1') then UNDEFINED */ + if((((res->fields[FIELD_half_to_single]) == (0)) && (((res->fields[FIELD_Vm] & 1)) == (0x1)))) { + res->status |= STATUS_UNDEFINED; + } + /* pcode: esize = 16 */ + res->fields[FIELD_esize] = 16; + res->fields_mask[FIELD_esize >> 6] |= 1LL << (FIELD_esize & 63); + /* pcode: elements = 4 */ + res->fields[FIELD_elements] = 4; + res->fields_mask[FIELD_elements >> 6] |= 1LL << (FIELD_elements & 63); + /* pcode: m = UInt(M:Vm) */ + res->fields[FIELD_m] = ((res->fields[FIELD_M]<<Vm_width)|(res->fields[FIELD_Vm])); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + /* pcode: d = UInt(D:Vd) */ + res->fields[FIELD_d] = ((res->fields[FIELD_D]<<Vd_width)|(res->fields[FIELD_Vd])); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: td = TRUE */ + res->fields[FIELD_td] = 1; + res->fields_mask[FIELD_td >> 6] |= 1LL << (FIELD_td & 63); + /* pcode: fmt_idx = (op == '1') */ + res->fields[FIELD_fmt_idx] = ((res->fields[FIELD_op]) == (0x1)); + res->fields_mask[FIELD_fmt_idx >> 6] |= 1LL << (FIELD_fmt_idx & 63); + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: E44C7F9B +int vcvta(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + res->group = INSN_GROUP_NEON; + /* Encoding T1 */ + /* pattern="1111,11101,D.1,111,opc1.1,opc2.2,Vd.4,101,sz.1,op.1,1,M.1,0,Vm.4" width=32 stringency=23 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFFB80E50)==0xFEB80A40)) { + res->instrSize = 32; + if(!(req->arch & ARCH_VFPv3)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_D] = (instr & 0x400000)>>22; + res->fields_mask[FIELD_D >> 6] |= 1LL << (FIELD_D & 63); + char D_width = 1; + res->fields[FIELD_opc1] = (instr & 0x40000)>>18; + res->fields_mask[FIELD_opc1 >> 6] |= 1LL << (FIELD_opc1 & 63); + char opc1_width = 1; + res->fields[FIELD_opc2] = (instr & 0x30000)>>16; + res->fields_mask[FIELD_opc2 >> 6] |= 1LL << (FIELD_opc2 & 63); + char opc2_width = 2; + res->fields[FIELD_Vd] = (instr & 0xF000)>>12; + res->fields_mask[FIELD_Vd >> 6] |= 1LL << (FIELD_Vd & 63); + char Vd_width = 4; + res->fields[FIELD_sz] = (instr & 0x100)>>8; + res->fields_mask[FIELD_sz >> 6] |= 1LL << (FIELD_sz & 63); + char sz_width = 1; + res->fields[FIELD_op] = (instr & 0x80)>>7; + res->fields_mask[FIELD_op >> 6] |= 1LL << (FIELD_op & 63); + char op_width = 1; + res->fields[FIELD_M] = (instr & 0x20)>>5; + res->fields_mask[FIELD_M >> 6] |= 1LL << (FIELD_M & 63); + char M_width = 1; + res->fields[FIELD_Vm] = instr & 0xF; + res->fields_mask[FIELD_Vm >> 6] |= 1LL << (FIELD_Vm & 63); + char Vm_width = 4; + + static const instruction_format instr_formats[] = + { + { /* VCVTA<c>.S32.F32 <Sd>,<Sm> */ + "vcvta.s32.f32", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"s","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_m,FIELD_UNINIT,"s","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + { /* VCVTA<c>.S32.F64 <Sd>,<Dm> */ + "vcvta.s32.f64", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"s","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_m,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + { /* VCVTA<c>.U32.F32 <Sd>,<Sm> */ + "vcvta.u32.f32", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"s","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_m,FIELD_UNINIT,"s","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + { /* VCVTA<c>.U32.F64 <Sd>,<Dm> */ + "vcvta.u32.f64", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"s","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_m,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 4; + res->mnem = armv7::ARMV7_VCVTA; + + /* pcode: round_mode = opc2 */ + res->fields[FIELD_round_mode] = res->fields[FIELD_opc2]; + res->fields_mask[FIELD_round_mode >> 6] |= 1LL << (FIELD_round_mode & 63); + /* pcode: dp_operation = (sz == '1') */ + res->fields[FIELD_dp_operation] = ((res->fields[FIELD_sz]) == (0x1)); + res->fields_mask[FIELD_dp_operation >> 6] |= 1LL << (FIELD_dp_operation & 63); + /* pcode: unsigned = (op == '0') */ + res->fields[FIELD_unsigned] = ((res->fields[FIELD_op]) == (0x0)); + res->fields_mask[FIELD_unsigned >> 6] |= 1LL << (FIELD_unsigned & 63); + /* pcode: d = UInt(Vd:D) */ + res->fields[FIELD_d] = ((res->fields[FIELD_Vd]<<D_width)|(res->fields[FIELD_D])); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: m = if dp_operation then UInt(M:Vm) else UInt(Vm:M) */ + if(res->fields[FIELD_dp_operation]) { + res->fields[FIELD_m] = ((res->fields[FIELD_M]<<Vm_width)|(res->fields[FIELD_Vm])); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + } + else { + res->fields[FIELD_m] = ((res->fields[FIELD_Vm]<<M_width)|(res->fields[FIELD_M])); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + } + /* pcode: fmt_idx = (unsigned * 2) + dp_operation */ + res->fields[FIELD_fmt_idx] = (((res->fields[FIELD_unsigned]) * (2))) + (res->fields[FIELD_dp_operation]); + res->fields_mask[FIELD_fmt_idx >> 6] |= 1LL << (FIELD_fmt_idx & 63); + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: B87CE179 +int vcvtb(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + res->group = INSN_GROUP_NEON; + /* Encoding T1 */ + /* pattern="1110,11101,D.1,11001,op.1,Vd.4,101,sz.1,T.1,1,M.1,0,Vm.4" width=32 stringency=24 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFFBE0E50)==0xEEB20A40)) { + res->instrSize = 32; + if(!(req->arch & ARCH_VFPv3)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_D] = (instr & 0x400000)>>22; + res->fields_mask[FIELD_D >> 6] |= 1LL << (FIELD_D & 63); + char D_width = 1; + res->fields[FIELD_op] = (instr & 0x10000)>>16; + res->fields_mask[FIELD_op >> 6] |= 1LL << (FIELD_op & 63); + char op_width = 1; + res->fields[FIELD_Vd] = (instr & 0xF000)>>12; + res->fields_mask[FIELD_Vd >> 6] |= 1LL << (FIELD_Vd & 63); + char Vd_width = 4; + res->fields[FIELD_sz] = (instr & 0x100)>>8; + res->fields_mask[FIELD_sz >> 6] |= 1LL << (FIELD_sz & 63); + char sz_width = 1; + res->fields[FIELD_T] = (instr & 0x80)>>7; + res->fields_mask[FIELD_T >> 6] |= 1LL << (FIELD_T & 63); + char T_width = 1; + res->fields[FIELD_M] = (instr & 0x20)>>5; + res->fields_mask[FIELD_M >> 6] |= 1LL << (FIELD_M & 63); + char M_width = 1; + res->fields[FIELD_Vm] = instr & 0xF; + res->fields_mask[FIELD_Vm >> 6] |= 1LL << (FIELD_Vm & 63); + char Vm_width = 4; + + static const instruction_format instr_formats[] = + { + { /* VCVTB<c>.F32.F16 <Sd>,<Sm> */ + "vcvtb.f32.f16", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"s","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_m,FIELD_UNINIT,"s","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + { /* VCVTB<c>.F16.F32 <Sd>,<Sm> */ + "vcvtb.f16.f32", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"s","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_m,FIELD_UNINIT,"s","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + { /* VCVTB<c>.F64.F16 <Dd>,<Sm> */ + "vcvtb.f64.f16", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_m,FIELD_UNINIT,"s","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + { /* VCVTB<c>.F16.F64 <Sd>,<Dm> */ + "vcvtb.f16.f64", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"s","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_m,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + { /* VCVTT<c>.F32.F16 <Sd>,<Sm> */ + "vcvtt.f32.f16", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"s","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_m,FIELD_UNINIT,"s","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + { /* VCVTT<c>.F16.F32 <Sd>,<Sm> */ + "vcvtt.f16.f32", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"s","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_m,FIELD_UNINIT,"s","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + { /* VCVTT<c>.F64.F16 <Dd>,<Sm> */ + "vcvtt.f64.f16", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_m,FIELD_UNINIT,"s","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + { /* VCVTT<c>.F16.F64 <Sd>,<Dm> */ + "vcvtt.f16.f64", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"s","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_m,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 8; + res->mnem = armv7::ARMV7_VCVTB; + + /* pcode: dp_operation = (sz == '1') */ + res->fields[FIELD_dp_operation] = ((res->fields[FIELD_sz]) == (0x1)); + res->fields_mask[FIELD_dp_operation >> 6] |= 1LL << (FIELD_dp_operation & 63); + /* pcode: half_to_single = (op == '0') */ + res->fields[FIELD_half_to_single] = ((res->fields[FIELD_op]) == (0x0)); + res->fields_mask[FIELD_half_to_single >> 6] |= 1LL << (FIELD_half_to_single & 63); + /* pcode: lowbit = if T == '1' then 16 else 0 */ + if((res->fields[FIELD_T]) == (0x1)) { + res->fields[FIELD_lowbit] = 16; + res->fields_mask[FIELD_lowbit >> 6] |= 1LL << (FIELD_lowbit & 63); + } + else { + res->fields[FIELD_lowbit] = 0; + res->fields_mask[FIELD_lowbit >> 6] |= 1LL << (FIELD_lowbit & 63); + } + /* pcode: m = UInt(Vm:M) */ + res->fields[FIELD_m] = ((res->fields[FIELD_Vm]<<M_width)|(res->fields[FIELD_M])); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + /* pcode: d = UInt(Vd:D) */ + res->fields[FIELD_d] = ((res->fields[FIELD_Vd]<<D_width)|(res->fields[FIELD_D])); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: if (dp_operation && !half_to_single) then m = UInt(M:Vm) */ + if(((res->fields[FIELD_dp_operation]) && (!(res->fields[FIELD_half_to_single])))) { + res->fields[FIELD_m] = ((res->fields[FIELD_M]<<Vm_width)|(res->fields[FIELD_Vm])); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + } + /* pcode: if (dp_operation && half_to_single) then d = UInt(D:Vd) */ + if(((res->fields[FIELD_dp_operation]) && (res->fields[FIELD_half_to_single]))) { + res->fields[FIELD_d] = ((res->fields[FIELD_D]<<Vd_width)|(res->fields[FIELD_Vd])); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + } + /* pcode: fmt_idx = (T == '1') */ + res->fields[FIELD_fmt_idx] = ((res->fields[FIELD_T]) == (0x1)); + res->fields_mask[FIELD_fmt_idx >> 6] |= 1LL << (FIELD_fmt_idx & 63); + /* pcode: fmt_idx = fmt_idx * 4 */ + res->fields[FIELD_fmt_idx] = (res->fields[FIELD_fmt_idx]) * (4); + res->fields_mask[FIELD_fmt_idx >> 6] |= 1LL << (FIELD_fmt_idx & 63); + /* pcode: fmt_idx = fmt_idx + (sz * 2) */ + res->fields[FIELD_fmt_idx] = (res->fields[FIELD_fmt_idx]) + (((res->fields[FIELD_sz]) * (2))); + res->fields_mask[FIELD_fmt_idx >> 6] |= 1LL << (FIELD_fmt_idx & 63); + /* pcode: fmt_idx = fmt_idx + (op == '1') */ + res->fields[FIELD_fmt_idx] = (res->fields[FIELD_fmt_idx]) + (((res->fields[FIELD_op]) == (0x1))); + res->fields_mask[FIELD_fmt_idx >> 6] |= 1LL << (FIELD_fmt_idx & 63); + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: 028A48F1 +int vcvtm(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + res->group = INSN_GROUP_NEON; + /* Encoding T1 */ + /* pattern="1111,11101,D.1,111,opc1.1,opc2.2,Vd.4,101,sz.1,op.1,1,M.1,0,Vm.4" width=32 stringency=23 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFFB80E50)==0xFEB80A40)) { + res->instrSize = 32; + if(!(req->arch & ARCH_VFPv3)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_D] = (instr & 0x400000)>>22; + res->fields_mask[FIELD_D >> 6] |= 1LL << (FIELD_D & 63); + char D_width = 1; + res->fields[FIELD_opc1] = (instr & 0x40000)>>18; + res->fields_mask[FIELD_opc1 >> 6] |= 1LL << (FIELD_opc1 & 63); + char opc1_width = 1; + res->fields[FIELD_opc2] = (instr & 0x30000)>>16; + res->fields_mask[FIELD_opc2 >> 6] |= 1LL << (FIELD_opc2 & 63); + char opc2_width = 2; + res->fields[FIELD_Vd] = (instr & 0xF000)>>12; + res->fields_mask[FIELD_Vd >> 6] |= 1LL << (FIELD_Vd & 63); + char Vd_width = 4; + res->fields[FIELD_sz] = (instr & 0x100)>>8; + res->fields_mask[FIELD_sz >> 6] |= 1LL << (FIELD_sz & 63); + char sz_width = 1; + res->fields[FIELD_op] = (instr & 0x80)>>7; + res->fields_mask[FIELD_op >> 6] |= 1LL << (FIELD_op & 63); + char op_width = 1; + res->fields[FIELD_M] = (instr & 0x20)>>5; + res->fields_mask[FIELD_M >> 6] |= 1LL << (FIELD_M & 63); + char M_width = 1; + res->fields[FIELD_Vm] = instr & 0xF; + res->fields_mask[FIELD_Vm >> 6] |= 1LL << (FIELD_Vm & 63); + char Vm_width = 4; + + static const instruction_format instr_formats[] = + { + { /* VCVTM<c>.S32.F32 <Sd>,<Sm> */ + "vcvtm.s32.f32", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"s","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_m,FIELD_UNINIT,"s","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + { /* VCVTM<c>.S32.F64 <Sd>,<Dm> */ + "vcvtm.s32.f64", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"s","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_m,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + { /* VCVTM<c>.U32.F32 <Sd>,<Sm> */ + "vcvtm.u32.f32", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"s","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_m,FIELD_UNINIT,"s","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + { /* VCVTM<c>.U32.F64 <Sd>,<Dm> */ + "vcvtm.u32.f64", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"s","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_m,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 4; + res->mnem = armv7::ARMV7_VCVTM; + + /* pcode: round_mode = opc2 */ + res->fields[FIELD_round_mode] = res->fields[FIELD_opc2]; + res->fields_mask[FIELD_round_mode >> 6] |= 1LL << (FIELD_round_mode & 63); + /* pcode: dp_operation = (sz == '1') */ + res->fields[FIELD_dp_operation] = ((res->fields[FIELD_sz]) == (0x1)); + res->fields_mask[FIELD_dp_operation >> 6] |= 1LL << (FIELD_dp_operation & 63); + /* pcode: unsigned = (op == '0') */ + res->fields[FIELD_unsigned] = ((res->fields[FIELD_op]) == (0x0)); + res->fields_mask[FIELD_unsigned >> 6] |= 1LL << (FIELD_unsigned & 63); + /* pcode: d = UInt(Vd:D) */ + res->fields[FIELD_d] = ((res->fields[FIELD_Vd]<<D_width)|(res->fields[FIELD_D])); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: m = if dp_operation then UInt(M:Vm) else UInt(Vm:M) */ + if(res->fields[FIELD_dp_operation]) { + res->fields[FIELD_m] = ((res->fields[FIELD_M]<<Vm_width)|(res->fields[FIELD_Vm])); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + } + else { + res->fields[FIELD_m] = ((res->fields[FIELD_Vm]<<M_width)|(res->fields[FIELD_M])); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + } + /* pcode: fmt_idx = (unsigned * 2) + dp_operation */ + res->fields[FIELD_fmt_idx] = (((res->fields[FIELD_unsigned]) * (2))) + (res->fields[FIELD_dp_operation]); + res->fields_mask[FIELD_fmt_idx >> 6] |= 1LL << (FIELD_fmt_idx & 63); + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: D683460B +int vcvtn(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + res->group = INSN_GROUP_NEON; + /* Encoding T1 */ + /* pattern="1111,11101,D.1,111,opc1.1,opc2.2,Vd.4,101,sz.1,op.1,1,M.1,0,Vm.4" width=32 stringency=23 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFFB80E50)==0xFEB80A40)) { + res->instrSize = 32; + if(!(req->arch & ARCH_VFPv3)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_D] = (instr & 0x400000)>>22; + res->fields_mask[FIELD_D >> 6] |= 1LL << (FIELD_D & 63); + char D_width = 1; + res->fields[FIELD_opc1] = (instr & 0x40000)>>18; + res->fields_mask[FIELD_opc1 >> 6] |= 1LL << (FIELD_opc1 & 63); + char opc1_width = 1; + res->fields[FIELD_opc2] = (instr & 0x30000)>>16; + res->fields_mask[FIELD_opc2 >> 6] |= 1LL << (FIELD_opc2 & 63); + char opc2_width = 2; + res->fields[FIELD_Vd] = (instr & 0xF000)>>12; + res->fields_mask[FIELD_Vd >> 6] |= 1LL << (FIELD_Vd & 63); + char Vd_width = 4; + res->fields[FIELD_sz] = (instr & 0x100)>>8; + res->fields_mask[FIELD_sz >> 6] |= 1LL << (FIELD_sz & 63); + char sz_width = 1; + res->fields[FIELD_op] = (instr & 0x80)>>7; + res->fields_mask[FIELD_op >> 6] |= 1LL << (FIELD_op & 63); + char op_width = 1; + res->fields[FIELD_M] = (instr & 0x20)>>5; + res->fields_mask[FIELD_M >> 6] |= 1LL << (FIELD_M & 63); + char M_width = 1; + res->fields[FIELD_Vm] = instr & 0xF; + res->fields_mask[FIELD_Vm >> 6] |= 1LL << (FIELD_Vm & 63); + char Vm_width = 4; + + static const instruction_format instr_formats[] = + { + { /* VCVTN<c>.S32.F32 <Sd>,<Sm> */ + "vcvtn.s32.f32", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"s","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_m,FIELD_UNINIT,"s","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + { /* VCVTN<c>.S32.F64 <Sd>,<Dm> */ + "vcvtn.s32.f64", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"s","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_m,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + { /* VCVTN<c>.U32.F32 <Sd>,<Sm> */ + "vcvtn.u32.f32", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"s","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_m,FIELD_UNINIT,"s","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + { /* VCVTN<c>.U32.F64 <Sd>,<Dm> */ + "vcvtn.u32.f64", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"s","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_m,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 4; + res->mnem = armv7::ARMV7_VCVTN; + + /* pcode: round_mode = opc2 */ + res->fields[FIELD_round_mode] = res->fields[FIELD_opc2]; + res->fields_mask[FIELD_round_mode >> 6] |= 1LL << (FIELD_round_mode & 63); + /* pcode: dp_operation = (sz == '1') */ + res->fields[FIELD_dp_operation] = ((res->fields[FIELD_sz]) == (0x1)); + res->fields_mask[FIELD_dp_operation >> 6] |= 1LL << (FIELD_dp_operation & 63); + /* pcode: unsigned = (op == '0') */ + res->fields[FIELD_unsigned] = ((res->fields[FIELD_op]) == (0x0)); + res->fields_mask[FIELD_unsigned >> 6] |= 1LL << (FIELD_unsigned & 63); + /* pcode: d = UInt(Vd:D) */ + res->fields[FIELD_d] = ((res->fields[FIELD_Vd]<<D_width)|(res->fields[FIELD_D])); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: m = if dp_operation then UInt(M:Vm) else UInt(Vm:M) */ + if(res->fields[FIELD_dp_operation]) { + res->fields[FIELD_m] = ((res->fields[FIELD_M]<<Vm_width)|(res->fields[FIELD_Vm])); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + } + else { + res->fields[FIELD_m] = ((res->fields[FIELD_Vm]<<M_width)|(res->fields[FIELD_M])); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + } + /* pcode: fmt_idx = (unsigned * 2) + dp_operation */ + res->fields[FIELD_fmt_idx] = (((res->fields[FIELD_unsigned]) * (2))) + (res->fields[FIELD_dp_operation]); + res->fields_mask[FIELD_fmt_idx >> 6] |= 1LL << (FIELD_fmt_idx & 63); + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: B31D352B +int vcvtp(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + res->group = INSN_GROUP_NEON; + /* Encoding T1 */ + /* pattern="1111,11101,D.1,111,opc1.1,opc2.2,Vd.4,101,sz.1,op.1,1,M.1,0,Vm.4" width=32 stringency=23 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFFB80E50)==0xFEB80A40)) { + res->instrSize = 32; + if(!(req->arch & ARCH_VFPv3)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_D] = (instr & 0x400000)>>22; + res->fields_mask[FIELD_D >> 6] |= 1LL << (FIELD_D & 63); + char D_width = 1; + res->fields[FIELD_opc1] = (instr & 0x40000)>>18; + res->fields_mask[FIELD_opc1 >> 6] |= 1LL << (FIELD_opc1 & 63); + char opc1_width = 1; + res->fields[FIELD_opc2] = (instr & 0x30000)>>16; + res->fields_mask[FIELD_opc2 >> 6] |= 1LL << (FIELD_opc2 & 63); + char opc2_width = 2; + res->fields[FIELD_Vd] = (instr & 0xF000)>>12; + res->fields_mask[FIELD_Vd >> 6] |= 1LL << (FIELD_Vd & 63); + char Vd_width = 4; + res->fields[FIELD_sz] = (instr & 0x100)>>8; + res->fields_mask[FIELD_sz >> 6] |= 1LL << (FIELD_sz & 63); + char sz_width = 1; + res->fields[FIELD_op] = (instr & 0x80)>>7; + res->fields_mask[FIELD_op >> 6] |= 1LL << (FIELD_op & 63); + char op_width = 1; + res->fields[FIELD_M] = (instr & 0x20)>>5; + res->fields_mask[FIELD_M >> 6] |= 1LL << (FIELD_M & 63); + char M_width = 1; + res->fields[FIELD_Vm] = instr & 0xF; + res->fields_mask[FIELD_Vm >> 6] |= 1LL << (FIELD_Vm & 63); + char Vm_width = 4; + + static const instruction_format instr_formats[] = + { + { /* VCVTP<c>.S32.F32 <Sd>,<Sm> */ + "vcvtp.s32.f32", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"s","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_m,FIELD_UNINIT,"s","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + { /* VCVTP<c>.S32.F64 <Sd>,<Dm> */ + "vcvtp.s32.f64", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"s","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_m,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + { /* VCVTP<c>.U32.F32 <Sd>,<Sm> */ + "vcvtp.u32.f32", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"s","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_m,FIELD_UNINIT,"s","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + { /* VCVTP<c>.U32.F64 <Sd>,<Dm> */ + "vcvtp.u32.f64", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"s","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_m,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 4; + res->mnem = armv7::ARMV7_VCVTP; + + /* pcode: round_mode = opc2 */ + res->fields[FIELD_round_mode] = res->fields[FIELD_opc2]; + res->fields_mask[FIELD_round_mode >> 6] |= 1LL << (FIELD_round_mode & 63); + /* pcode: dp_operation = (sz == '1') */ + res->fields[FIELD_dp_operation] = ((res->fields[FIELD_sz]) == (0x1)); + res->fields_mask[FIELD_dp_operation >> 6] |= 1LL << (FIELD_dp_operation & 63); + /* pcode: unsigned = (op == '0') */ + res->fields[FIELD_unsigned] = ((res->fields[FIELD_op]) == (0x0)); + res->fields_mask[FIELD_unsigned >> 6] |= 1LL << (FIELD_unsigned & 63); + /* pcode: d = UInt(Vd:D) */ + res->fields[FIELD_d] = ((res->fields[FIELD_Vd]<<D_width)|(res->fields[FIELD_D])); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: m = if dp_operation then UInt(M:Vm) else UInt(Vm:M) */ + if(res->fields[FIELD_dp_operation]) { + res->fields[FIELD_m] = ((res->fields[FIELD_M]<<Vm_width)|(res->fields[FIELD_Vm])); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + } + else { + res->fields[FIELD_m] = ((res->fields[FIELD_Vm]<<M_width)|(res->fields[FIELD_M])); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + } + /* pcode: fmt_idx = (unsigned * 2) + dp_operation */ + res->fields[FIELD_fmt_idx] = (((res->fields[FIELD_unsigned]) * (2))) + (res->fields[FIELD_dp_operation]); + res->fields_mask[FIELD_fmt_idx >> 6] |= 1LL << (FIELD_fmt_idx & 63); + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: 6B413434 +int vdiv(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + res->group = INSN_GROUP_NEON; + /* Encoding T1 */ + /* pattern="1110,11101,D.1,00,Vn.4,Vd.4,101,sz.1,N.1,0,M.1,0,Vm.4" width=32 stringency=20 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFFB00E50)==0xEE800A00)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ADVSIMD)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_D] = (instr & 0x400000)>>22; + res->fields_mask[FIELD_D >> 6] |= 1LL << (FIELD_D & 63); + char D_width = 1; + res->fields[FIELD_Vn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Vn >> 6] |= 1LL << (FIELD_Vn & 63); + char Vn_width = 4; + res->fields[FIELD_Vd] = (instr & 0xF000)>>12; + res->fields_mask[FIELD_Vd >> 6] |= 1LL << (FIELD_Vd & 63); + char Vd_width = 4; + res->fields[FIELD_sz] = (instr & 0x100)>>8; + res->fields_mask[FIELD_sz >> 6] |= 1LL << (FIELD_sz & 63); + char sz_width = 1; + res->fields[FIELD_N] = (instr & 0x80)>>7; + res->fields_mask[FIELD_N >> 6] |= 1LL << (FIELD_N & 63); + char N_width = 1; + res->fields[FIELD_M] = (instr & 0x20)>>5; + res->fields_mask[FIELD_M >> 6] |= 1LL << (FIELD_M & 63); + char M_width = 1; + res->fields[FIELD_Vm] = instr & 0xF; + res->fields_mask[FIELD_Vm >> 6] |= 1LL << (FIELD_Vm & 63); + char Vm_width = 4; + + static const instruction_format instr_formats[] = + { + { /* VDIV<c>.F32 <Sd>,<Sn>,<Sm> */ + "vdiv.f32", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_F32, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"s","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_n,FIELD_UNINIT,"s","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_m,FIELD_UNINIT,"s","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + { /* VDIV<c>.F64 <Dd>,<Dn>,<Dm> */ + "vdiv.f64", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_F64, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_n,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_m,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 2; + res->mnem = armv7::ARMV7_VDIV; + + /* pcode: dp_operation = (sz == '1') */ + res->fields[FIELD_dp_operation] = ((res->fields[FIELD_sz]) == (0x1)); + res->fields_mask[FIELD_dp_operation >> 6] |= 1LL << (FIELD_dp_operation & 63); + /* pcode: d = if dp_operation then UInt(D:Vd) else UInt(Vd:D) */ + if(res->fields[FIELD_dp_operation]) { + res->fields[FIELD_d] = ((res->fields[FIELD_D]<<Vd_width)|(res->fields[FIELD_Vd])); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + } + else { + res->fields[FIELD_d] = ((res->fields[FIELD_Vd]<<D_width)|(res->fields[FIELD_D])); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + } + /* pcode: n = if dp_operation then UInt(N:Vn) else UInt(Vn:N) */ + if(res->fields[FIELD_dp_operation]) { + res->fields[FIELD_n] = ((res->fields[FIELD_N]<<Vn_width)|(res->fields[FIELD_Vn])); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + } + else { + res->fields[FIELD_n] = ((res->fields[FIELD_Vn]<<N_width)|(res->fields[FIELD_N])); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + } + /* pcode: m = if dp_operation then UInt(M:Vm) else UInt(Vm:M) */ + if(res->fields[FIELD_dp_operation]) { + res->fields[FIELD_m] = ((res->fields[FIELD_M]<<Vm_width)|(res->fields[FIELD_Vm])); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + } + else { + res->fields[FIELD_m] = ((res->fields[FIELD_Vm]<<M_width)|(res->fields[FIELD_M])); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + } + /* pcode: fmt_idx = dp_operation */ + res->fields[FIELD_fmt_idx] = res->fields[FIELD_dp_operation]; + res->fields_mask[FIELD_fmt_idx >> 6] |= 1LL << (FIELD_fmt_idx & 63); + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: 9227ADCC +int vdup_register(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + res->group = INSN_GROUP_NEON; + /* Encoding T1 */ + /* pattern="1110,1110,1,B.1,Q.1,0,Vd.4,Rt.4,1011,D.1,0,E.1,1,(0)(0)(0)(0)" width=32 stringency=24 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFF900F50)==0xEE800B10)) { + res->instrSize = 32; + if(!((instr & 0xF)==0x0)) { + res->flags |= FLAG_UNPREDICTABLE; + } + if(!(req->arch & ARCH_ADVSIMD)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_B] = (instr & 0x400000)>>22; + res->fields_mask[FIELD_B >> 6] |= 1LL << (FIELD_B & 63); + char B_width = 1; + res->fields[FIELD_Q] = (instr & 0x200000)>>21; + res->fields_mask[FIELD_Q >> 6] |= 1LL << (FIELD_Q & 63); + char Q_width = 1; + res->fields[FIELD_Vd] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Vd >> 6] |= 1LL << (FIELD_Vd & 63); + char Vd_width = 4; + res->fields[FIELD_Rt] = (instr & 0xF000)>>12; + res->fields_mask[FIELD_Rt >> 6] |= 1LL << (FIELD_Rt & 63); + char Rt_width = 4; + res->fields[FIELD_D] = (instr & 0x80)>>7; + res->fields_mask[FIELD_D >> 6] |= 1LL << (FIELD_D & 63); + char D_width = 1; + res->fields[FIELD_E] = (instr & 0x20)>>5; + res->fields_mask[FIELD_E >> 6] |= 1LL << (FIELD_E & 63); + char E_width = 1; + + static const instruction_format instr_formats[] = + { + { /* VDUP<c>.<size> <Dd>,<Rt> */ + "vdup", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_NEON_SIZE, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG,FIELD_Rt,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + { /* VDUP<c>.<size> <Qd>,<Rt> */ + "vdup", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_NEON_SIZE, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"q","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG,FIELD_Rt,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 2; + res->mnem = armv7::ARMV7_VDUP; + + /* pcode: if (Q == '1' && Vd<0> == '1') then UNDEFINED */ + if((((res->fields[FIELD_Q]) == (0x1)) && (((res->fields[FIELD_Vd] & 1)) == (0x1)))) { + res->status |= STATUS_UNDEFINED; + } + /* pcode: d = UInt(D:Vd) */ + res->fields[FIELD_d] = ((res->fields[FIELD_D]<<Vd_width)|(res->fields[FIELD_Vd])); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: t = UInt(Rt) */ + res->fields[FIELD_t] = (res->fields[FIELD_Rt]); + res->fields_mask[FIELD_t >> 6] |= 1LL << (FIELD_t & 63); + /* pcode: regs = if Q == '0' then 1 else 2 */ + if((res->fields[FIELD_Q]) == (0x0)) { + res->fields[FIELD_regs] = 1; + res->fields_mask[FIELD_regs >> 6] |= 1LL << (FIELD_regs & 63); + } + else { + res->fields[FIELD_regs] = 2; + res->fields_mask[FIELD_regs >> 6] |= 1LL << (FIELD_regs & 63); + } + /* pcode: if (B == '0' && E == '0') then esize = 32 */ + if((((res->fields[FIELD_B]) == (0x0)) && ((res->fields[FIELD_E]) == (0x0)))) { + res->fields[FIELD_esize] = 32; + res->fields_mask[FIELD_esize >> 6] |= 1LL << (FIELD_esize & 63); + } + /* pcode: if (B == '0' && E == '1') then esize = 16 */ + if((((res->fields[FIELD_B]) == (0x0)) && ((res->fields[FIELD_E]) == (0x1)))) { + res->fields[FIELD_esize] = 16; + res->fields_mask[FIELD_esize >> 6] |= 1LL << (FIELD_esize & 63); + } + /* pcode: if (B == '1' && E == '0') then esize = 8 */ + if((((res->fields[FIELD_B]) == (0x1)) && ((res->fields[FIELD_E]) == (0x0)))) { + res->fields[FIELD_esize] = 8; + res->fields_mask[FIELD_esize >> 6] |= 1LL << (FIELD_esize & 63); + } + /* pcode: if (B == '1' && E == '1') then UNDEFINED */ + if((((res->fields[FIELD_B]) == (0x1)) && ((res->fields[FIELD_E]) == (0x1)))) { + res->status |= STATUS_UNDEFINED; + } + /* pcode: if (B == '0' && E == '0') then size = 2 */ + if((((res->fields[FIELD_B]) == (0x0)) && ((res->fields[FIELD_E]) == (0x0)))) { + res->fields[FIELD_size] = 2; + res->fields_mask[FIELD_size >> 6] |= 1LL << (FIELD_size & 63); + } + /* pcode: if (B == '0' && E == '1') then size = 1 */ + if((((res->fields[FIELD_B]) == (0x0)) && ((res->fields[FIELD_E]) == (0x1)))) { + res->fields[FIELD_size] = 1; + res->fields_mask[FIELD_size >> 6] |= 1LL << (FIELD_size & 63); + } + /* pcode: if (B == '1' && E == '0') then size = 0 */ + if((((res->fields[FIELD_B]) == (0x1)) && ((res->fields[FIELD_E]) == (0x0)))) { + res->fields[FIELD_size] = 0; + res->fields_mask[FIELD_size >> 6] |= 1LL << (FIELD_size & 63); + } + /* pcode: elements = 64 DIV esize */ + res->fields[FIELD_elements] = ((res->fields[FIELD_esize]) ? ((64) / (res->fields[FIELD_esize])) : 0); + res->fields_mask[FIELD_elements >> 6] |= 1LL << (FIELD_elements & 63); + /* pcode: fmt_idx = (Q == '1') */ + res->fields[FIELD_fmt_idx] = ((res->fields[FIELD_Q]) == (0x1)); + res->fields_mask[FIELD_fmt_idx >> 6] |= 1LL << (FIELD_fmt_idx & 63); + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: F606BB52 +int vdup_scalar(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + res->group = INSN_GROUP_NEON; + /* Encoding T1 */ + /* pattern="1111,xx11,1,D.1,11,imm4.4,Vd.4,110,0,0,Q.1,M.1,0,Vm.4" width=32 stringency=18 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xF3B00F90)==0xF3B00C00)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ADVSIMD)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_D] = (instr & 0x400000)>>22; + res->fields_mask[FIELD_D >> 6] |= 1LL << (FIELD_D & 63); + char D_width = 1; + res->fields[FIELD_imm4] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_imm4 >> 6] |= 1LL << (FIELD_imm4 & 63); + char imm4_width = 4; + res->fields[FIELD_Vd] = (instr & 0xF000)>>12; + res->fields_mask[FIELD_Vd >> 6] |= 1LL << (FIELD_Vd & 63); + char Vd_width = 4; + res->fields[FIELD_Q] = (instr & 0x40)>>6; + res->fields_mask[FIELD_Q >> 6] |= 1LL << (FIELD_Q & 63); + char Q_width = 1; + res->fields[FIELD_M] = (instr & 0x20)>>5; + res->fields_mask[FIELD_M >> 6] |= 1LL << (FIELD_M & 63); + char M_width = 1; + res->fields[FIELD_Vm] = instr & 0xF; + res->fields_mask[FIELD_Vm >> 6] |= 1LL << (FIELD_Vm & 63); + char Vm_width = 4; + + static const instruction_format instr_formats[] = + { + { /* VDUP<c>.<size> <Dd>,<Dm[x]> */ + "vdup", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_NEON_SIZE, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_INDEX,FIELD_m,FIELD_x,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + { /* VDUP<c>.<size> <Qd>,<Dm[x]> */ + "vdup", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_NEON_SIZE, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"q","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_INDEX,FIELD_m,FIELD_x,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 2; + res->mnem = armv7::ARMV7_VDUP; + + /* pcode: if (imm4 == '0000' || imm4 == '1000') then UNDEFINED */ + if((((res->fields[FIELD_imm4]) == (0x0)) || ((res->fields[FIELD_imm4]) == (0x8)))) { + res->status |= STATUS_UNDEFINED; + } + /* pcode: if (Q == '1' && Vd<0> == '1') then UNDEFINED */ + if((((res->fields[FIELD_Q]) == (0x1)) && (((res->fields[FIELD_Vd] & 1)) == (0x1)))) { + res->status |= STATUS_UNDEFINED; + } + /* pcode: esize = 8 */ + res->fields[FIELD_esize] = 8; + res->fields_mask[FIELD_esize >> 6] |= 1LL << (FIELD_esize & 63); + /* pcode: if (imm4 == '1110' || imm4 == '1010' || imm4 == '0110' || imm4 == '0010') then esize = 16 */ + if((((((res->fields[FIELD_imm4]) == (0xE)) || ((res->fields[FIELD_imm4]) == (0xA))) || ((res->fields[FIELD_imm4]) == (0x6))) || ((res->fields[FIELD_imm4]) == (0x2)))) { + res->fields[FIELD_esize] = 16; + res->fields_mask[FIELD_esize >> 6] |= 1LL << (FIELD_esize & 63); + } + /* pcode: if (imm4 == '1100' || imm4 == '0100') then esize = 32 */ + if((((res->fields[FIELD_imm4]) == (0xC)) || ((res->fields[FIELD_imm4]) == (0x4)))) { + res->fields[FIELD_esize] = 32; + res->fields_mask[FIELD_esize >> 6] |= 1LL << (FIELD_esize & 63); + } + /* pcode: d = UInt(D:Vd) */ + res->fields[FIELD_d] = ((res->fields[FIELD_D]<<Vd_width)|(res->fields[FIELD_Vd])); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: m = UInt(M:Vm) */ + res->fields[FIELD_m] = ((res->fields[FIELD_M]<<Vm_width)|(res->fields[FIELD_Vm])); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + /* pcode: regs = if Q == '0' then 1 else 2 */ + if((res->fields[FIELD_Q]) == (0x0)) { + res->fields[FIELD_regs] = 1; + res->fields_mask[FIELD_regs >> 6] |= 1LL << (FIELD_regs & 63); + } + else { + res->fields[FIELD_regs] = 2; + res->fields_mask[FIELD_regs >> 6] |= 1LL << (FIELD_regs & 63); + } + /* pcode: if esize == 8 then size = 0 */ + if((res->fields[FIELD_esize]) == (8)) { + res->fields[FIELD_size] = 0; + res->fields_mask[FIELD_size >> 6] |= 1LL << (FIELD_size & 63); + } + /* pcode: if esize == 16 then size = 1 */ + if((res->fields[FIELD_esize]) == (16)) { + res->fields[FIELD_size] = 1; + res->fields_mask[FIELD_size >> 6] |= 1LL << (FIELD_size & 63); + } + /* pcode: if esize == 32 then size = 2 */ + if((res->fields[FIELD_esize]) == (32)) { + res->fields[FIELD_size] = 2; + res->fields_mask[FIELD_size >> 6] |= 1LL << (FIELD_size & 63); + } + /* pcode: if esize == 8 then x = UInt(imm4) >> 1 */ + if((res->fields[FIELD_esize]) == (8)) { + res->fields[FIELD_x] = ((res->fields[FIELD_imm4])) >> (1); + res->fields_mask[FIELD_x >> 6] |= 1LL << (FIELD_x & 63); + } + /* pcode: if esize == 16 then x = UInt(imm4) >> 2 */ + if((res->fields[FIELD_esize]) == (16)) { + res->fields[FIELD_x] = ((res->fields[FIELD_imm4])) >> (2); + res->fields_mask[FIELD_x >> 6] |= 1LL << (FIELD_x & 63); + } + /* pcode: if esize == 32 then x = UInt(imm4) >> 3 */ + if((res->fields[FIELD_esize]) == (32)) { + res->fields[FIELD_x] = ((res->fields[FIELD_imm4])) >> (3); + res->fields_mask[FIELD_x >> 6] |= 1LL << (FIELD_x & 63); + } + /* pcode: fmt_idx = (Q == '1') */ + res->fields[FIELD_fmt_idx] = ((res->fields[FIELD_Q]) == (0x1)); + res->fields_mask[FIELD_fmt_idx >> 6] |= 1LL << (FIELD_fmt_idx & 63); + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: BD04C7EE +int veor(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + /* Encoding T1 */ + /* pattern="1111,xx11,0,D.1,00,Vn.4,Vd.4,0001,N.1,Q.1,M.1,1,Vm.4" width=32 stringency=18 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xF3B00F10)==0xF3000110)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ADVSIMD)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_D] = (instr & 0x400000)>>22; + res->fields_mask[FIELD_D >> 6] |= 1LL << (FIELD_D & 63); + char D_width = 1; + res->fields[FIELD_Vn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Vn >> 6] |= 1LL << (FIELD_Vn & 63); + char Vn_width = 4; + res->fields[FIELD_Vd] = (instr & 0xF000)>>12; + res->fields_mask[FIELD_Vd >> 6] |= 1LL << (FIELD_Vd & 63); + char Vd_width = 4; + res->fields[FIELD_N] = (instr & 0x80)>>7; + res->fields_mask[FIELD_N >> 6] |= 1LL << (FIELD_N & 63); + char N_width = 1; + res->fields[FIELD_Q] = (instr & 0x40)>>6; + res->fields_mask[FIELD_Q >> 6] |= 1LL << (FIELD_Q & 63); + char Q_width = 1; + res->fields[FIELD_M] = (instr & 0x20)>>5; + res->fields_mask[FIELD_M >> 6] |= 1LL << (FIELD_M & 63); + char M_width = 1; + res->fields[FIELD_Vm] = instr & 0xF; + res->fields_mask[FIELD_Vm >> 6] |= 1LL << (FIELD_Vm & 63); + char Vm_width = 4; + + static const instruction_format instr_formats[] = + { + { /* VEOR<c> <Dd>,<Dn>,<Dm> */ + "veor", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_n,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_m,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + { /* VEOR<c> <Qd>,<Qn>,<Qm> */ + "veor", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"q","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_n,FIELD_UNINIT,"q","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_m,FIELD_UNINIT,"q","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 2; + res->mnem = armv7::ARMV7_VEOR; + + /* pcode: if Q == '1' && (Vd<0> == '1' || Vn<0> == '1' || Vm<0> == '1') then UNDEFINED */ + if(((res->fields[FIELD_Q]) == (0x1)) && ((((((res->fields[FIELD_Vd] & 1)) == (0x1)) || (((res->fields[FIELD_Vn] & 1)) == (0x1))) || (((res->fields[FIELD_Vm] & 1)) == (0x1))))) { + res->status |= STATUS_UNDEFINED; + } + /* pcode: d = UInt(D:Vd) */ + res->fields[FIELD_d] = ((res->fields[FIELD_D]<<Vd_width)|(res->fields[FIELD_Vd])); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: n = UInt(N:Vn) */ + res->fields[FIELD_n] = ((res->fields[FIELD_N]<<Vn_width)|(res->fields[FIELD_Vn])); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: m = UInt(M:Vm) */ + res->fields[FIELD_m] = ((res->fields[FIELD_M]<<Vm_width)|(res->fields[FIELD_Vm])); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + /* pcode: regs = if Q == '0' then 1 else 2 */ + if((res->fields[FIELD_Q]) == (0x0)) { + res->fields[FIELD_regs] = 1; + res->fields_mask[FIELD_regs >> 6] |= 1LL << (FIELD_regs & 63); + } + else { + res->fields[FIELD_regs] = 2; + res->fields_mask[FIELD_regs >> 6] |= 1LL << (FIELD_regs & 63); + } + /* pcode: fmt_idx = (Q == '1') */ + res->fields[FIELD_fmt_idx] = ((res->fields[FIELD_Q]) == (0x1)); + res->fields_mask[FIELD_fmt_idx >> 6] |= 1LL << (FIELD_fmt_idx & 63); + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: 99018336 +int vext(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + res->group = INSN_GROUP_NEON; + /* Encoding T1 */ + /* pattern="111x,xx1x,1,D.1,11,Vn.4,Vd.4,imm4.4,N.1,Q.1,M.1,0,Vm.4" width=32 stringency=12 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xE2B00010)==0xE2B00000)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ADVSIMD)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_D] = (instr & 0x400000)>>22; + res->fields_mask[FIELD_D >> 6] |= 1LL << (FIELD_D & 63); + char D_width = 1; + res->fields[FIELD_Vn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Vn >> 6] |= 1LL << (FIELD_Vn & 63); + char Vn_width = 4; + res->fields[FIELD_Vd] = (instr & 0xF000)>>12; + res->fields_mask[FIELD_Vd >> 6] |= 1LL << (FIELD_Vd & 63); + char Vd_width = 4; + res->fields[FIELD_imm4] = (instr & 0xF00)>>8; + res->fields_mask[FIELD_imm4 >> 6] |= 1LL << (FIELD_imm4 & 63); + char imm4_width = 4; + res->fields[FIELD_N] = (instr & 0x80)>>7; + res->fields_mask[FIELD_N >> 6] |= 1LL << (FIELD_N & 63); + char N_width = 1; + res->fields[FIELD_Q] = (instr & 0x40)>>6; + res->fields_mask[FIELD_Q >> 6] |= 1LL << (FIELD_Q & 63); + char Q_width = 1; + res->fields[FIELD_M] = (instr & 0x20)>>5; + res->fields_mask[FIELD_M >> 6] |= 1LL << (FIELD_M & 63); + char M_width = 1; + res->fields[FIELD_Vm] = instr & 0xF; + res->fields_mask[FIELD_Vm >> 6] |= 1LL << (FIELD_Vm & 63); + char Vm_width = 4; + + static const instruction_format instr_formats[] = + { + { /* VEXT<c>.8 <Dd>,<Dn>,<Dm>,#<imm> */ + "vext.8", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_n,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_m,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_IMM,FIELD_imm,FIELD_UNINIT,"#","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 4 /* .operandCount */ + }, + { /* VEXT<c>.8 <Qd>,<Qn>,<Qm>,#<imm> */ + "vext.8", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"q","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_n,FIELD_UNINIT,"q","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_m,FIELD_UNINIT,"q","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_IMM,FIELD_imm,FIELD_UNINIT,"#","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 4 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 2; + res->mnem = armv7::ARMV7_VEXT; + + /* pcode: if (Q == '1' && (Vd<0> == '1' || Vn<0> == '1' || Vm<0> == '1')) then UNDEFINED */ + if((((res->fields[FIELD_Q]) == (0x1)) && ((((((res->fields[FIELD_Vd] & 1)) == (0x1)) || (((res->fields[FIELD_Vn] & 1)) == (0x1))) || (((res->fields[FIELD_Vm] & 1)) == (0x1)))))) { + res->status |= STATUS_UNDEFINED; + } + /* pcode: if (Q == '0' && ((imm4 >> 3) == '1')) then UNDEFINED */ + if((((res->fields[FIELD_Q]) == (0x0)) && (((((res->fields[FIELD_imm4]) >> (3))) == (0x1))))) { + res->status |= STATUS_UNDEFINED; + } + /* pcode: quadword_operation = (Q == '1') */ + res->fields[FIELD_quadword_operation] = ((res->fields[FIELD_Q]) == (0x1)); + res->fields_mask[FIELD_quadword_operation >> 6] |= 1LL << (FIELD_quadword_operation & 63); + /* pcode: position = 8 * UInt(imm4) */ + res->fields[FIELD_position] = (8) * ((res->fields[FIELD_imm4])); + res->fields_mask[FIELD_position >> 6] |= 1LL << (FIELD_position & 63); + /* pcode: d = UInt(D:Vd) */ + res->fields[FIELD_d] = ((res->fields[FIELD_D]<<Vd_width)|(res->fields[FIELD_Vd])); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: n = UInt(N:Vn) */ + res->fields[FIELD_n] = ((res->fields[FIELD_N]<<Vn_width)|(res->fields[FIELD_Vn])); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: m = UInt(M:Vm) */ + res->fields[FIELD_m] = ((res->fields[FIELD_M]<<Vm_width)|(res->fields[FIELD_Vm])); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + /* pcode: imm = imm4 */ + res->fields[FIELD_imm] = res->fields[FIELD_imm4]; + res->fields_mask[FIELD_imm >> 6] |= 1LL << (FIELD_imm & 63); + /* pcode: fmt_idx = (Q == '1') */ + res->fields[FIELD_fmt_idx] = ((res->fields[FIELD_Q]) == (0x1)); + res->fields_mask[FIELD_fmt_idx >> 6] |= 1LL << (FIELD_fmt_idx & 63); + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: F12B5DC3 +int vfma(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + res->group = INSN_GROUP_NEON; + /* Encoding T2 */ + /* pattern="1110,11101,D.1,10,Vn.4,Vd.4,101,sz.1,N.1,op.1,M.1,0,Vm.4" width=32 stringency=20 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFFB00E10)==0xEEA00A00)) { + res->instrSize = 32; + if(!(req->arch & ARCH_VFPv2)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_D] = (instr & 0x400000)>>22; + res->fields_mask[FIELD_D >> 6] |= 1LL << (FIELD_D & 63); + char D_width = 1; + res->fields[FIELD_Vn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Vn >> 6] |= 1LL << (FIELD_Vn & 63); + char Vn_width = 4; + res->fields[FIELD_Vd] = (instr & 0xF000)>>12; + res->fields_mask[FIELD_Vd >> 6] |= 1LL << (FIELD_Vd & 63); + char Vd_width = 4; + res->fields[FIELD_sz] = (instr & 0x100)>>8; + res->fields_mask[FIELD_sz >> 6] |= 1LL << (FIELD_sz & 63); + char sz_width = 1; + res->fields[FIELD_N] = (instr & 0x80)>>7; + res->fields_mask[FIELD_N >> 6] |= 1LL << (FIELD_N & 63); + char N_width = 1; + res->fields[FIELD_op] = (instr & 0x40)>>6; + res->fields_mask[FIELD_op >> 6] |= 1LL << (FIELD_op & 63); + char op_width = 1; + res->fields[FIELD_M] = (instr & 0x20)>>5; + res->fields_mask[FIELD_M >> 6] |= 1LL << (FIELD_M & 63); + char M_width = 1; + res->fields[FIELD_Vm] = instr & 0xF; + res->fields_mask[FIELD_Vm >> 6] |= 1LL << (FIELD_Vm & 63); + char Vm_width = 4; + + static const instruction_format instr_formats[] = + { + { /* VFMA<c>.F32 <Sd>,<Sn>,<Sm> */ + "vfma.f32", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_F32, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"s","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_n,FIELD_UNINIT,"s","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_m,FIELD_UNINIT,"s","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + { /* VFMA<c>.F64 <Dd>,<Dn>,<Dm> */ + "vfma.f64", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_F64, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_n,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_m,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + { /* VFMS<c>.F32 <Sd>,<Sn>,<Sm> */ + "vfms.f32", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_F32, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"s","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_n,FIELD_UNINIT,"s","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_m,FIELD_UNINIT,"s","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + { /* VFMS<c>.F64 <Dd>,<Dn>,<Dm> */ + "vfms.f64", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_F64, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_n,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_m,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 4; + res->mnem = armv7::ARMV7_VFMA; + + /* pcode: advsimd = FALSE */ + res->fields[FIELD_advsimd] = 0; + res->fields_mask[FIELD_advsimd >> 6] |= 1LL << (FIELD_advsimd & 63); + /* pcode: dp_operation = (sz == '1') */ + res->fields[FIELD_dp_operation] = ((res->fields[FIELD_sz]) == (0x1)); + res->fields_mask[FIELD_dp_operation >> 6] |= 1LL << (FIELD_dp_operation & 63); + /* pcode: op1_neg = (op == '1') */ + res->fields[FIELD_op1_neg] = ((res->fields[FIELD_op]) == (0x1)); + res->fields_mask[FIELD_op1_neg >> 6] |= 1LL << (FIELD_op1_neg & 63); + /* pcode: d = if dp_operation then UInt(D:Vd) else UInt(Vd:D) */ + if(res->fields[FIELD_dp_operation]) { + res->fields[FIELD_d] = ((res->fields[FIELD_D]<<Vd_width)|(res->fields[FIELD_Vd])); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + } + else { + res->fields[FIELD_d] = ((res->fields[FIELD_Vd]<<D_width)|(res->fields[FIELD_D])); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + } + /* pcode: n = if dp_operation then UInt(N:Vn) else UInt(Vn:N) */ + if(res->fields[FIELD_dp_operation]) { + res->fields[FIELD_n] = ((res->fields[FIELD_N]<<Vn_width)|(res->fields[FIELD_Vn])); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + } + else { + res->fields[FIELD_n] = ((res->fields[FIELD_Vn]<<N_width)|(res->fields[FIELD_N])); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + } + /* pcode: m = if dp_operation then UInt(M:Vm) else UInt(Vm:M) */ + if(res->fields[FIELD_dp_operation]) { + res->fields[FIELD_m] = ((res->fields[FIELD_M]<<Vm_width)|(res->fields[FIELD_Vm])); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + } + else { + res->fields[FIELD_m] = ((res->fields[FIELD_Vm]<<M_width)|(res->fields[FIELD_M])); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + } + /* pcode: fmt_idx = (op == '1') */ + res->fields[FIELD_fmt_idx] = ((res->fields[FIELD_op]) == (0x1)); + res->fields_mask[FIELD_fmt_idx >> 6] |= 1LL << (FIELD_fmt_idx & 63); + /* pcode: fmt_idx = fmt_idx + fmt_idx */ + res->fields[FIELD_fmt_idx] = (res->fields[FIELD_fmt_idx]) + (res->fields[FIELD_fmt_idx]); + res->fields_mask[FIELD_fmt_idx >> 6] |= 1LL << (FIELD_fmt_idx & 63); + /* pcode: fmt_idx = fmt_idx + (sz == '1') */ + res->fields[FIELD_fmt_idx] = (res->fields[FIELD_fmt_idx]) + (((res->fields[FIELD_sz]) == (0x1))); + res->fields_mask[FIELD_fmt_idx >> 6] |= 1LL << (FIELD_fmt_idx & 63); + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* Encoding T1 */ + /* pattern="111x,xx1x0,D.1,op.1,sz.1,Vn.4,Vd.4,1100,N.1,Q.1,M.1,1,Vm.4" width=32 stringency=16 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xE2800F10)==0xE2000C10)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ADVSIMD)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_D] = (instr & 0x400000)>>22; + res->fields_mask[FIELD_D >> 6] |= 1LL << (FIELD_D & 63); + char D_width = 1; + res->fields[FIELD_op] = (instr & 0x200000)>>21; + res->fields_mask[FIELD_op >> 6] |= 1LL << (FIELD_op & 63); + char op_width = 1; + res->fields[FIELD_sz] = (instr & 0x100000)>>20; + res->fields_mask[FIELD_sz >> 6] |= 1LL << (FIELD_sz & 63); + char sz_width = 1; + res->fields[FIELD_Vn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Vn >> 6] |= 1LL << (FIELD_Vn & 63); + char Vn_width = 4; + res->fields[FIELD_Vd] = (instr & 0xF000)>>12; + res->fields_mask[FIELD_Vd >> 6] |= 1LL << (FIELD_Vd & 63); + char Vd_width = 4; + res->fields[FIELD_N] = (instr & 0x80)>>7; + res->fields_mask[FIELD_N >> 6] |= 1LL << (FIELD_N & 63); + char N_width = 1; + res->fields[FIELD_Q] = (instr & 0x40)>>6; + res->fields_mask[FIELD_Q >> 6] |= 1LL << (FIELD_Q & 63); + char Q_width = 1; + res->fields[FIELD_M] = (instr & 0x20)>>5; + res->fields_mask[FIELD_M >> 6] |= 1LL << (FIELD_M & 63); + char M_width = 1; + res->fields[FIELD_Vm] = instr & 0xF; + res->fields_mask[FIELD_Vm >> 6] |= 1LL << (FIELD_Vm & 63); + char Vm_width = 4; + + static const instruction_format instr_formats[] = + { + { /* VFMA<c>.F32 <Dd>,<Dn>,<Dm> */ + "vfma.f32", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_F32, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_n,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_m,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + { /* VFMA<c>.F32 <Qd>,<Qn>,<Qm> */ + "vfma.f32", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_F32, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"q","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_n,FIELD_UNINIT,"q","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_m,FIELD_UNINIT,"q","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + { /* VFMS<c>.F32 <Dd>,<Dn>,<Dm> */ + "vfms.f32", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_F32, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_n,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_m,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + { /* VFMS<c>.F32 <Qd>,<Qn>,<Qm> */ + "vfms.f32", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_F32, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"q","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_n,FIELD_UNINIT,"q","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_m,FIELD_UNINIT,"q","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 4; + res->mnem = armv7::ARMV7_VFMA; + + /* pcode: if (Q == '1' && (Vd<0> == '1' || Vn<0> == '1' || Vm<0> == '1')) then UNDEFINED */ + if((((res->fields[FIELD_Q]) == (0x1)) && ((((((res->fields[FIELD_Vd] & 1)) == (0x1)) || (((res->fields[FIELD_Vn] & 1)) == (0x1))) || (((res->fields[FIELD_Vm] & 1)) == (0x1)))))) { + res->status |= STATUS_UNDEFINED; + } + /* pcode: if sz == '1' then UNDEFINED */ + if((res->fields[FIELD_sz]) == (0x1)) { + res->status |= STATUS_UNDEFINED; + } + /* pcode: advsimd = TRUE */ + res->fields[FIELD_advsimd] = 1; + res->fields_mask[FIELD_advsimd >> 6] |= 1LL << (FIELD_advsimd & 63); + /* pcode: op1_neg = (op == '1') */ + res->fields[FIELD_op1_neg] = ((res->fields[FIELD_op]) == (0x1)); + res->fields_mask[FIELD_op1_neg >> 6] |= 1LL << (FIELD_op1_neg & 63); + /* pcode: esize = 32 */ + res->fields[FIELD_esize] = 32; + res->fields_mask[FIELD_esize >> 6] |= 1LL << (FIELD_esize & 63); + /* pcode: elements = 2 */ + res->fields[FIELD_elements] = 2; + res->fields_mask[FIELD_elements >> 6] |= 1LL << (FIELD_elements & 63); + /* pcode: d = UInt(D:Vd) */ + res->fields[FIELD_d] = ((res->fields[FIELD_D]<<Vd_width)|(res->fields[FIELD_Vd])); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: n = UInt(N:Vn) */ + res->fields[FIELD_n] = ((res->fields[FIELD_N]<<Vn_width)|(res->fields[FIELD_Vn])); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: m = UInt(M:Vm) */ + res->fields[FIELD_m] = ((res->fields[FIELD_M]<<Vm_width)|(res->fields[FIELD_Vm])); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + /* pcode: regs = if Q == '0' then 1 else 2 */ + if((res->fields[FIELD_Q]) == (0x0)) { + res->fields[FIELD_regs] = 1; + res->fields_mask[FIELD_regs >> 6] |= 1LL << (FIELD_regs & 63); + } + else { + res->fields[FIELD_regs] = 2; + res->fields_mask[FIELD_regs >> 6] |= 1LL << (FIELD_regs & 63); + } + /* pcode: fmt_idx = (op == '1') */ + res->fields[FIELD_fmt_idx] = ((res->fields[FIELD_op]) == (0x1)); + res->fields_mask[FIELD_fmt_idx >> 6] |= 1LL << (FIELD_fmt_idx & 63); + /* pcode: fmt_idx = fmt_idx + fmt_idx */ + res->fields[FIELD_fmt_idx] = (res->fields[FIELD_fmt_idx]) + (res->fields[FIELD_fmt_idx]); + res->fields_mask[FIELD_fmt_idx >> 6] |= 1LL << (FIELD_fmt_idx & 63); + /* pcode: fmt_idx = fmt_idx + (Q == '1') */ + res->fields[FIELD_fmt_idx] = (res->fields[FIELD_fmt_idx]) + (((res->fields[FIELD_Q]) == (0x1))); + res->fields_mask[FIELD_fmt_idx >> 6] |= 1LL << (FIELD_fmt_idx & 63); + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: 31D08218 +int vfnma(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + res->group = INSN_GROUP_NEON; + /* Encoding T1 */ + /* pattern="1110,11101,D.1,01,Vn.4,Vd.4,101,sz.1,N.1,op.1,M.1,0,Vm.4" width=32 stringency=20 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFFB00E10)==0xEE900A00)) { + res->instrSize = 32; + if(!(req->arch & ARCH_VFPv2)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_D] = (instr & 0x400000)>>22; + res->fields_mask[FIELD_D >> 6] |= 1LL << (FIELD_D & 63); + char D_width = 1; + res->fields[FIELD_Vn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Vn >> 6] |= 1LL << (FIELD_Vn & 63); + char Vn_width = 4; + res->fields[FIELD_Vd] = (instr & 0xF000)>>12; + res->fields_mask[FIELD_Vd >> 6] |= 1LL << (FIELD_Vd & 63); + char Vd_width = 4; + res->fields[FIELD_sz] = (instr & 0x100)>>8; + res->fields_mask[FIELD_sz >> 6] |= 1LL << (FIELD_sz & 63); + char sz_width = 1; + res->fields[FIELD_N] = (instr & 0x80)>>7; + res->fields_mask[FIELD_N >> 6] |= 1LL << (FIELD_N & 63); + char N_width = 1; + res->fields[FIELD_op] = (instr & 0x40)>>6; + res->fields_mask[FIELD_op >> 6] |= 1LL << (FIELD_op & 63); + char op_width = 1; + res->fields[FIELD_M] = (instr & 0x20)>>5; + res->fields_mask[FIELD_M >> 6] |= 1LL << (FIELD_M & 63); + char M_width = 1; + res->fields[FIELD_Vm] = instr & 0xF; + res->fields_mask[FIELD_Vm >> 6] |= 1LL << (FIELD_Vm & 63); + char Vm_width = 4; + + static const instruction_format instr_formats[] = + { + { /* VFNMS<c>.F32 <Sd>,<Sn>,<Sm> */ + "vfnms.f32", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_F32, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"s","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_n,FIELD_UNINIT,"s","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_m,FIELD_UNINIT,"s","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + { /* VFNMS<c>.F64 <Dd>,<Dn>,<Dm> */ + "vfnms.f64", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_F64, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_n,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_m,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + { /* VFNMA<c>.F32 <Sd>,<Sn>,<Sm> */ + "vfnma.f32", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_F32, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"s","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_n,FIELD_UNINIT,"s","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_m,FIELD_UNINIT,"s","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + { /* VFNMA<c>.F64 <Dd>,<Dn>,<Dm> */ + "vfnma.f64", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_F64, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_n,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_m,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 4; + res->mnem = armv7::ARMV7_VFNMS; + + /* pcode: op1_neg = (op == '1') */ + res->fields[FIELD_op1_neg] = ((res->fields[FIELD_op]) == (0x1)); + res->fields_mask[FIELD_op1_neg >> 6] |= 1LL << (FIELD_op1_neg & 63); + /* pcode: dp_operation = (sz == '1') */ + res->fields[FIELD_dp_operation] = ((res->fields[FIELD_sz]) == (0x1)); + res->fields_mask[FIELD_dp_operation >> 6] |= 1LL << (FIELD_dp_operation & 63); + /* pcode: d = if dp_operation then UInt(D:Vd) else UInt(Vd:D) */ + if(res->fields[FIELD_dp_operation]) { + res->fields[FIELD_d] = ((res->fields[FIELD_D]<<Vd_width)|(res->fields[FIELD_Vd])); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + } + else { + res->fields[FIELD_d] = ((res->fields[FIELD_Vd]<<D_width)|(res->fields[FIELD_D])); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + } + /* pcode: n = if dp_operation then UInt(N:Vn) else UInt(Vn:N) */ + if(res->fields[FIELD_dp_operation]) { + res->fields[FIELD_n] = ((res->fields[FIELD_N]<<Vn_width)|(res->fields[FIELD_Vn])); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + } + else { + res->fields[FIELD_n] = ((res->fields[FIELD_Vn]<<N_width)|(res->fields[FIELD_N])); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + } + /* pcode: m = if dp_operation then UInt(M:Vm) else UInt(Vm:M) */ + if(res->fields[FIELD_dp_operation]) { + res->fields[FIELD_m] = ((res->fields[FIELD_M]<<Vm_width)|(res->fields[FIELD_Vm])); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + } + else { + res->fields[FIELD_m] = ((res->fields[FIELD_Vm]<<M_width)|(res->fields[FIELD_M])); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + } + /* pcode: fmt_idx = op * 2 */ + res->fields[FIELD_fmt_idx] = (res->fields[FIELD_op]) * (2); + res->fields_mask[FIELD_fmt_idx >> 6] |= 1LL << (FIELD_fmt_idx & 63); + /* pcode: fmt_idx = fmt_idx + (sz == '1') */ + res->fields[FIELD_fmt_idx] = (res->fields[FIELD_fmt_idx]) + (((res->fields[FIELD_sz]) == (0x1))); + res->fields_mask[FIELD_fmt_idx >> 6] |= 1LL << (FIELD_fmt_idx & 63); + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: BEA7EA15 +int vfp_data_proc(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + uint32_t instr = req->instr_word32; + uint32_t T = (instr & 0x10000000)>>28; + uint32_t opc1 = (instr & 0xF00000)>>20; + uint32_t opc2 = (instr & 0xF0000)>>16; + uint32_t opc3 = (instr & 0xC0)>>6; + uint32_t opc4 = instr & 0xF; + if(((T & 0x1)==0x0) && ((opc1 & 0xB)==0x3) && ((opc3 & 0x1)==0x0) && 1) return vadd_float(req, res); + if(((T & 0x1)==0x0) && ((opc1 & 0xB)==0x3) && ((opc3 & 0x1)==0x1) && 1) return vsub_float(req, res); + if(((T & 0x1)==0x0) && ((opc1 & 0xB)==0x2) && ((opc3 & 0x1)==0x0) && 1) return vmul_float(req, res); + if(((T & 0x1)==0x0) && ((opc1 & 0xB)==0x8) && ((opc3 & 0x1)==0x0) && 1) return vdiv(req, res); + if(((T & 0x1)==0x1) && ((opc1 & 0xB)==0x8) && 1) return vmaxnm(req, res); + if(((T & 0x1)==0x0) && ((opc1 & 0xB)==0x0) && 1) return vmla_float(req, res); + if(((T & 0x1)==0x0) && ((opc1 & 0xB)==0x1) && 1) return vnmla(req, res); + if(((T & 0x1)==0x0) && ((opc1 & 0xB)==0x2) && 1) return vnmla(req, res); + if(((opc1 & 0xB)==0xA) && 1) return vfma(req, res); + if(((opc1 & 0xB)==0x9) && 1) return vfnma(req, res); + if(((opc1 & 0xB)==0xB) && 1) return vfp_data_proc_ext(req, res); + if(((T & 0x1)==0x1) && ((opc1 & 0x8)==0x0) && 1) return vsel(req, res); + if(1) return undefined(req, res); + return undefined(req, res); +} + +// gen_crc: 01226BDE +int vfp_data_proc_ext(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + uint32_t instr = req->instr_word32; + uint32_t T = (instr & 0x10000000)>>28; + uint32_t opc1 = (instr & 0xF00000)>>20; + uint32_t opc2 = (instr & 0xF0000)>>16; + uint32_t opc3 = (instr & 0xC0)>>6; + uint32_t opc4 = instr & 0xF; + if(((T & 0x1)==0x0) && ((opc2 & 0xF)==0x1) && ((opc3 & 0x3)==0x3)) return vsqrt(req, res); + if(((T & 0x1)==0x0) && ((opc2 & 0xF)==0x7) && ((opc3 & 0x3)==0x1)) return vrintx(req, res); + if(((T & 0x1)==0x0) && ((opc2 & 0xF)==0x1) && ((opc3 & 0x3)==0x1)) return vneg(req, res); + if(((T & 0x1)==0x1) && ((opc2 & 0xF)==0xC) && ((opc3 & 0x1)==0x1)) return vcvta(req, res); + if(((T & 0x1)==0x1) && ((opc2 & 0xF)==0xD) && ((opc3 & 0x1)==0x1)) return vcvtn(req, res); + if(((T & 0x1)==0x1) && ((opc2 & 0xF)==0xE) && ((opc3 & 0x1)==0x1)) return vcvtp(req, res); + if(((T & 0x1)==0x1) && ((opc2 & 0xF)==0xF) && ((opc3 & 0x1)==0x1)) return vcvtm(req, res); + if(((opc2 & 0xF)==0x7) && ((opc3 & 0x3)==0x3) && 1) return vcvt_double_single(req, res); + if(((opc2 & 0xF)==0x0) && ((opc3 & 0x3)==0x1) && 1) return vmov_register(req, res); + if(((opc2 & 0xF)==0x0) && ((opc3 & 0x3)==0x3) && 1) return vabs(req, res); + if(((T & 0x1)==0x0) && ((opc2 & 0xF)==0x8) && ((opc3 & 0x1)==0x1)) return vcvt_float_int(req, res); + if(((T & 0x1)==0x1) && ((opc2 & 0xC)==0x8) && ((opc3 & 0x3)==0x1)) return vrinta(req, res); + if(((T & 0x1)==0x0) && ((opc2 & 0xE)==0x6) && ((opc3 & 0x1)==0x1)) return vrintz(req, res); + if(((T & 0x1)==0x0) && ((opc2 & 0xE)==0xA) && ((opc3 & 0x1)==0x1)) return vcvt_float_fixed(req, res); + if(((T & 0x1)==0x0) && ((opc2 & 0xE)==0xC) && ((opc3 & 0x1)==0x1)) return vcvt_float_int(req, res); + if(((T & 0x1)==0x0) && ((opc2 & 0xE)==0xE) && ((opc3 & 0x1)==0x1)) return vcvt_float_fixed(req, res); + if(((opc2 & 0xE)==0x2) && ((opc3 & 0x1)==0x1) && 1) return vcvtb(req, res); + if(((opc2 & 0xE)==0x4) && ((opc3 & 0x1)==0x1) && 1) return vcmp(req, res); + if(((T & 0x1)==0x0) && ((opc3 & 0x1)==0x0) && 1) return vmov_immediate(req, res); + if(1) return undefined(req, res); + return undefined(req, res); +} + +// gen_crc: C8AD63C6 +int vhadd(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + res->group = INSN_GROUP_NEON; + /* Encoding T1 */ + /* pattern="111,U.1,1111,0,D.1,size.2,Vn.4,Vd.4,00,op.1,0,N.1,Q.1,M.1,0,Vm.4" width=32 stringency=18 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xEF800D10)==0xEF000000)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ADVSIMD)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_U] = (instr & 0x10000000)>>28; + res->fields_mask[FIELD_U >> 6] |= 1LL << (FIELD_U & 63); + char U_width = 1; + res->fields[FIELD_D] = (instr & 0x400000)>>22; + res->fields_mask[FIELD_D >> 6] |= 1LL << (FIELD_D & 63); + char D_width = 1; + res->fields[FIELD_size] = (instr & 0x300000)>>20; + res->fields_mask[FIELD_size >> 6] |= 1LL << (FIELD_size & 63); + char size_width = 2; + res->fields[FIELD_Vn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Vn >> 6] |= 1LL << (FIELD_Vn & 63); + char Vn_width = 4; + res->fields[FIELD_Vd] = (instr & 0xF000)>>12; + res->fields_mask[FIELD_Vd >> 6] |= 1LL << (FIELD_Vd & 63); + char Vd_width = 4; + res->fields[FIELD_op] = (instr & 0x200)>>9; + res->fields_mask[FIELD_op >> 6] |= 1LL << (FIELD_op & 63); + char op_width = 1; + res->fields[FIELD_N] = (instr & 0x80)>>7; + res->fields_mask[FIELD_N >> 6] |= 1LL << (FIELD_N & 63); + char N_width = 1; + res->fields[FIELD_Q] = (instr & 0x40)>>6; + res->fields_mask[FIELD_Q >> 6] |= 1LL << (FIELD_Q & 63); + char Q_width = 1; + res->fields[FIELD_M] = (instr & 0x20)>>5; + res->fields_mask[FIELD_M >> 6] |= 1LL << (FIELD_M & 63); + char M_width = 1; + res->fields[FIELD_Vm] = instr & 0xF; + res->fields_mask[FIELD_Vm >> 6] |= 1LL << (FIELD_Vm & 63); + char Vm_width = 4; + + static const instruction_format instr_formats[] = + { + { /* VHADD<c>.<dt> <Dd>,<Dn>,<Dm> */ + "vhadd", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_VFP_DATA_SIZE, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_n,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_m,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + { /* VHADD<c>.<dt> <Qd>,<Qn>,<Qm> */ + "vhadd", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_VFP_DATA_SIZE, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"q","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_n,FIELD_UNINIT,"q","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_m,FIELD_UNINIT,"q","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 2; + res->mnem = armv7::ARMV7_VHADD; + + /* pcode: if Q == '1' && (Vd<0> == '1' || Vn<0> == '1' || Vm<0> == '1') then UNDEFINED */ + if(((res->fields[FIELD_Q]) == (0x1)) && ((((((res->fields[FIELD_Vd] & 1)) == (0x1)) || (((res->fields[FIELD_Vn] & 1)) == (0x1))) || (((res->fields[FIELD_Vm] & 1)) == (0x1))))) { + res->status |= STATUS_UNDEFINED; + } + /* pcode: if size == '11' then UNDEFINED */ + if((res->fields[FIELD_size]) == (0x3)) { + res->status |= STATUS_UNDEFINED; + } + /* pcode: unsigned = (U == '1') */ + res->fields[FIELD_unsigned] = ((res->fields[FIELD_U]) == (0x1)); + res->fields_mask[FIELD_unsigned >> 6] |= 1LL << (FIELD_unsigned & 63); + /* pcode: esize = 8 << UInt(size) */ + res->fields[FIELD_esize] = (8) << ((res->fields[FIELD_size])); + res->fields_mask[FIELD_esize >> 6] |= 1LL << (FIELD_esize & 63); + /* pcode: elements = 64 DIV esize */ + res->fields[FIELD_elements] = ((res->fields[FIELD_esize]) ? ((64) / (res->fields[FIELD_esize])) : 0); + res->fields_mask[FIELD_elements >> 6] |= 1LL << (FIELD_elements & 63); + /* pcode: d = UInt(D:Vd) */ + res->fields[FIELD_d] = ((res->fields[FIELD_D]<<Vd_width)|(res->fields[FIELD_Vd])); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: n = UInt(N:Vn) */ + res->fields[FIELD_n] = ((res->fields[FIELD_N]<<Vn_width)|(res->fields[FIELD_Vn])); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: m = UInt(M:Vm) */ + res->fields[FIELD_m] = ((res->fields[FIELD_M]<<Vm_width)|(res->fields[FIELD_Vm])); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + /* pcode: fmt_idx = (Q == '1') */ + res->fields[FIELD_fmt_idx] = ((res->fields[FIELD_Q]) == (0x1)); + res->fields_mask[FIELD_fmt_idx >> 6] |= 1LL << (FIELD_fmt_idx & 63); + /* pcode: regs = if Q == '0' then 1 else 2 */ + if((res->fields[FIELD_Q]) == (0x0)) { + res->fields[FIELD_regs] = 1; + res->fields_mask[FIELD_regs >> 6] |= 1LL << (FIELD_regs & 63); + } + else { + res->fields[FIELD_regs] = 2; + res->fields_mask[FIELD_regs >> 6] |= 1LL << (FIELD_regs & 63); + } + /* pcode: dt = UInt(U:size) */ + res->fields[FIELD_dt] = ((res->fields[FIELD_U]<<size_width)|(res->fields[FIELD_size])); + res->fields_mask[FIELD_dt >> 6] |= 1LL << (FIELD_dt & 63); + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: ABF87CFB +int vhsub(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + res->group = INSN_GROUP_NEON; + /* Encoding T1 */ + /* pattern="111,U.1,1111,0,D.1,size.2,Vn.4,Vd.4,00,op.1,0,N.1,Q.1,M.1,0,Vm.4" width=32 stringency=18 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xEF800D10)==0xEF000000)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ADVSIMD)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_U] = (instr & 0x10000000)>>28; + res->fields_mask[FIELD_U >> 6] |= 1LL << (FIELD_U & 63); + char U_width = 1; + res->fields[FIELD_D] = (instr & 0x400000)>>22; + res->fields_mask[FIELD_D >> 6] |= 1LL << (FIELD_D & 63); + char D_width = 1; + res->fields[FIELD_size] = (instr & 0x300000)>>20; + res->fields_mask[FIELD_size >> 6] |= 1LL << (FIELD_size & 63); + char size_width = 2; + res->fields[FIELD_Vn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Vn >> 6] |= 1LL << (FIELD_Vn & 63); + char Vn_width = 4; + res->fields[FIELD_Vd] = (instr & 0xF000)>>12; + res->fields_mask[FIELD_Vd >> 6] |= 1LL << (FIELD_Vd & 63); + char Vd_width = 4; + res->fields[FIELD_op] = (instr & 0x200)>>9; + res->fields_mask[FIELD_op >> 6] |= 1LL << (FIELD_op & 63); + char op_width = 1; + res->fields[FIELD_N] = (instr & 0x80)>>7; + res->fields_mask[FIELD_N >> 6] |= 1LL << (FIELD_N & 63); + char N_width = 1; + res->fields[FIELD_Q] = (instr & 0x40)>>6; + res->fields_mask[FIELD_Q >> 6] |= 1LL << (FIELD_Q & 63); + char Q_width = 1; + res->fields[FIELD_M] = (instr & 0x20)>>5; + res->fields_mask[FIELD_M >> 6] |= 1LL << (FIELD_M & 63); + char M_width = 1; + res->fields[FIELD_Vm] = instr & 0xF; + res->fields_mask[FIELD_Vm >> 6] |= 1LL << (FIELD_Vm & 63); + char Vm_width = 4; + + static const instruction_format instr_formats[] = + { + { /* VHSUB<c>.<dt> <Dd>,<Dn>,<Dm> */ + "vhsub", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_VFP_DATA_SIZE, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_n,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_m,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + { /* VHSUB<c>.<dt> <Qd>,<Qn>,<Qm> */ + "vhsub", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_VFP_DATA_SIZE, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"q","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_n,FIELD_UNINIT,"q","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_m,FIELD_UNINIT,"q","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 2; + res->mnem = armv7::ARMV7_VHSUB; + + /* pcode: if Q == '1' && (Vd<0> == '1' || Vn<0> == '1' || Vm<0> == '1') then UNDEFINED */ + if(((res->fields[FIELD_Q]) == (0x1)) && ((((((res->fields[FIELD_Vd] & 1)) == (0x1)) || (((res->fields[FIELD_Vn] & 1)) == (0x1))) || (((res->fields[FIELD_Vm] & 1)) == (0x1))))) { + res->status |= STATUS_UNDEFINED; + } + /* pcode: if size == '11' then UNDEFINED */ + if((res->fields[FIELD_size]) == (0x3)) { + res->status |= STATUS_UNDEFINED; + } + /* pcode: unsigned = (U == '1') */ + res->fields[FIELD_unsigned] = ((res->fields[FIELD_U]) == (0x1)); + res->fields_mask[FIELD_unsigned >> 6] |= 1LL << (FIELD_unsigned & 63); + /* pcode: esize = 8 << UInt(size) */ + res->fields[FIELD_esize] = (8) << ((res->fields[FIELD_size])); + res->fields_mask[FIELD_esize >> 6] |= 1LL << (FIELD_esize & 63); + /* pcode: elements = 64 DIV esize */ + res->fields[FIELD_elements] = ((res->fields[FIELD_esize]) ? ((64) / (res->fields[FIELD_esize])) : 0); + res->fields_mask[FIELD_elements >> 6] |= 1LL << (FIELD_elements & 63); + /* pcode: d = UInt(D:Vd) */ + res->fields[FIELD_d] = ((res->fields[FIELD_D]<<Vd_width)|(res->fields[FIELD_Vd])); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: n = UInt(N:Vn) */ + res->fields[FIELD_n] = ((res->fields[FIELD_N]<<Vn_width)|(res->fields[FIELD_Vn])); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: m = UInt(M:Vm) */ + res->fields[FIELD_m] = ((res->fields[FIELD_M]<<Vm_width)|(res->fields[FIELD_Vm])); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + /* pcode: fmt_idx = (Q == '1') */ + res->fields[FIELD_fmt_idx] = ((res->fields[FIELD_Q]) == (0x1)); + res->fields_mask[FIELD_fmt_idx >> 6] |= 1LL << (FIELD_fmt_idx & 63); + /* pcode: regs = if Q == '0' then 1 else 2 */ + if((res->fields[FIELD_Q]) == (0x0)) { + res->fields[FIELD_regs] = 1; + res->fields_mask[FIELD_regs >> 6] |= 1LL << (FIELD_regs & 63); + } + else { + res->fields[FIELD_regs] = 2; + res->fields_mask[FIELD_regs >> 6] |= 1LL << (FIELD_regs & 63); + } + /* pcode: dt = UInt(U:size) */ + res->fields[FIELD_dt] = ((res->fields[FIELD_U]<<size_width)|(res->fields[FIELD_size])); + res->fields_mask[FIELD_dt >> 6] |= 1LL << (FIELD_dt & 63); + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: 4C47A282 +int vld1_mult_1elem(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + res->group = INSN_GROUP_NEON; + /* Encoding T1 */ + /* pattern="1111,1001,0,D.1,10,Rn.4,Vd.4,type.4,size.2,align.2,Rm.4" width=32 stringency=12 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFFB00000)==0xF9200000)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ADVSIMD)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_D] = (instr & 0x400000)>>22; + res->fields_mask[FIELD_D >> 6] |= 1LL << (FIELD_D & 63); + char D_width = 1; + res->fields[FIELD_Rn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Rn >> 6] |= 1LL << (FIELD_Rn & 63); + char Rn_width = 4; + res->fields[FIELD_Vd] = (instr & 0xF000)>>12; + res->fields_mask[FIELD_Vd >> 6] |= 1LL << (FIELD_Vd & 63); + char Vd_width = 4; + res->fields[FIELD_type] = (instr & 0xF00)>>8; + res->fields_mask[FIELD_type >> 6] |= 1LL << (FIELD_type & 63); + char type_width = 4; + res->fields[FIELD_size] = (instr & 0xC0)>>6; + res->fields_mask[FIELD_size >> 6] |= 1LL << (FIELD_size & 63); + char size_width = 2; + res->fields[FIELD_align] = (instr & 0x30)>>4; + res->fields_mask[FIELD_align >> 6] |= 1LL << (FIELD_align & 63); + char align_width = 2; + res->fields[FIELD_Rm] = instr & 0xF; + res->fields_mask[FIELD_Rm >> 6] |= 1LL << (FIELD_Rm & 63); + char Rm_width = 4; + + static const instruction_format instr_formats[] = + { + { /* VLD1<c>.<size> <registers>,[<Rn>,#<align>] */ + "vld1", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_NEON_SIZE, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REGISTERS,FIELD_registers,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_MEMORY_ONE_REG_ALIGNED,FIELD_Rn,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + { /* VLD1<c>.<size> <registers>,[<Rn>,#<align>]! */ + "vld1", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_NEON_SIZE, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REGISTERS,FIELD_registers,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_MEMORY_ONE_REG_ALIGNED,FIELD_Rn,FIELD_UNINIT,"","",WRITEBACK_YES}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + { /* VLD1<c>.<size> <registers>,[<Rn>,#<align>],<Rm> */ + "vld1", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_NEON_SIZE, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REGISTERS,FIELD_registers,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_MEMORY_ONE_REG_ALIGNED,FIELD_Rn,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rm,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 3; + res->mnem = armv7::ARMV7_VLD1; + + /* pcode: regs_n = 0 */ + res->fields[FIELD_regs_n] = 0; + res->fields_mask[FIELD_regs_n >> 6] |= 1LL << (FIELD_regs_n & 63); + /* pcode: if type == '0111' then regs_n = 1 */ + if((res->fields[FIELD_type]) == (0x7)) { + res->fields[FIELD_regs_n] = 1; + res->fields_mask[FIELD_regs_n >> 6] |= 1LL << (FIELD_regs_n & 63); + } + /* pcode: if type == '0111' && (align==2 || align==3) then UNDEFINED */ + if(((res->fields[FIELD_type]) == (0x7)) && ((((res->fields[FIELD_align]) == (2)) || ((res->fields[FIELD_align]) == (3))))) { + res->status |= STATUS_UNDEFINED; + } + /* pcode: if type == '1010' then regs_n = 2 */ + if((res->fields[FIELD_type]) == (0xA)) { + res->fields[FIELD_regs_n] = 2; + res->fields_mask[FIELD_regs_n >> 6] |= 1LL << (FIELD_regs_n & 63); + } + /* pcode: if type == '1010' && (align==3) then UNDEFINED */ + if(((res->fields[FIELD_type]) == (0xA)) && (((res->fields[FIELD_align]) == (3)))) { + res->status |= STATUS_UNDEFINED; + } + /* pcode: if type == '0110' then regs_n = 3 */ + if((res->fields[FIELD_type]) == (0x6)) { + res->fields[FIELD_regs_n] = 3; + res->fields_mask[FIELD_regs_n >> 6] |= 1LL << (FIELD_regs_n & 63); + } + /* pcode: if type == '0110' && (align==2 || align==3) then UNDEFINED */ + if(((res->fields[FIELD_type]) == (0x6)) && ((((res->fields[FIELD_align]) == (2)) || ((res->fields[FIELD_align]) == (3))))) { + res->status |= STATUS_UNDEFINED; + } + /* pcode: if type == '0010' then regs_n = 4 */ + if((res->fields[FIELD_type]) == (0x2)) { + res->fields[FIELD_regs_n] = 4; + res->fields_mask[FIELD_regs_n >> 6] |= 1LL << (FIELD_regs_n & 63); + } + /* pcode: if align == 0 then alignment = 1 */ + if((res->fields[FIELD_align]) == (0)) { + res->fields[FIELD_alignment] = 1; + res->fields_mask[FIELD_alignment >> 6] |= 1LL << (FIELD_alignment & 63); + } + /* pcode: if align == 1 then alignment = 64 */ + if((res->fields[FIELD_align]) == (1)) { + res->fields[FIELD_alignment] = 64; + res->fields_mask[FIELD_alignment >> 6] |= 1LL << (FIELD_alignment & 63); + } + /* pcode: if align == 2 then alignment = 128 */ + if((res->fields[FIELD_align]) == (2)) { + res->fields[FIELD_alignment] = 128; + res->fields_mask[FIELD_alignment >> 6] |= 1LL << (FIELD_alignment & 63); + } + /* pcode: if align == 3 then alignment = 256 */ + if((res->fields[FIELD_align]) == (3)) { + res->fields[FIELD_alignment] = 256; + res->fields_mask[FIELD_alignment >> 6] |= 1LL << (FIELD_alignment & 63); + } + /* pcode: d = D:Vd */ + res->fields[FIELD_d] = (res->fields[FIELD_D]<<Vd_width)|(res->fields[FIELD_Vd]); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: if regs_n > 1 then d2 = d+1 */ + if((res->fields[FIELD_regs_n]) > (1)) { + res->fields[FIELD_d2] = (res->fields[FIELD_d]) + (1); + res->fields_mask[FIELD_d2 >> 6] |= 1LL << (FIELD_d2 & 63); + } + /* pcode: if regs_n > 2 then d3 = d2+1 */ + if((res->fields[FIELD_regs_n]) > (2)) { + res->fields[FIELD_d3] = (res->fields[FIELD_d2]) + (1); + res->fields_mask[FIELD_d3 >> 6] |= 1LL << (FIELD_d3 & 63); + } + /* pcode: if regs_n > 3 then d4 = d3+1 */ + if((res->fields[FIELD_regs_n]) > (3)) { + res->fields[FIELD_d4] = (res->fields[FIELD_d3]) + (1); + res->fields_mask[FIELD_d4 >> 6] |= 1LL << (FIELD_d4 & 63); + } + /* pcode: wback = 0 */ + res->fields[FIELD_wback] = 0; + res->fields_mask[FIELD_wback >> 6] |= 1LL << (FIELD_wback & 63); + /* pcode: if Rm != 0 then wback = 1 */ + if((res->fields[FIELD_Rm]) != (0)) { + res->fields[FIELD_wback] = 1; + res->fields_mask[FIELD_wback >> 6] |= 1LL << (FIELD_wback & 63); + } + /* pcode: register_index = 0 */ + res->fields[FIELD_register_index] = 0; + res->fields_mask[FIELD_register_index >> 6] |= 1LL << (FIELD_register_index & 63); + /* pcode: if (m != 15 && m != 13) then wback = 1 */ + if((((res->fields[FIELD_m]) != (15)) && ((res->fields[FIELD_m]) != (13)))) { + res->fields[FIELD_wback] = 1; + res->fields_mask[FIELD_wback >> 6] |= 1LL << (FIELD_wback & 63); + } + /* pcode: if d+regs_n > 32 then UNPREDICTABLE */ + if((res->fields[FIELD_d]) + ((res->fields[FIELD_regs_n]) > (32))) { + res->flags |= FLAG_UNPREDICTABLE; + } + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: EC9F2C06 +int vld1_single_1elem_1lane(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + res->group = INSN_GROUP_NEON; + /* Encoding T1 */ + /* pattern="1111,1001,1,D.1,10,Rn.4,Vd.4,size.2,00,index_align.4,Rm.4" width=32 stringency=14 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFFB00300)==0xF9A00000)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ADVSIMD)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_D] = (instr & 0x400000)>>22; + res->fields_mask[FIELD_D >> 6] |= 1LL << (FIELD_D & 63); + char D_width = 1; + res->fields[FIELD_Rn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Rn >> 6] |= 1LL << (FIELD_Rn & 63); + char Rn_width = 4; + res->fields[FIELD_Vd] = (instr & 0xF000)>>12; + res->fields_mask[FIELD_Vd >> 6] |= 1LL << (FIELD_Vd & 63); + char Vd_width = 4; + res->fields[FIELD_size] = (instr & 0xC00)>>10; + res->fields_mask[FIELD_size >> 6] |= 1LL << (FIELD_size & 63); + char size_width = 2; + res->fields[FIELD_index_align] = (instr & 0xF0)>>4; + res->fields_mask[FIELD_index_align >> 6] |= 1LL << (FIELD_index_align & 63); + char index_align_width = 4; + res->fields[FIELD_Rm] = instr & 0xF; + res->fields_mask[FIELD_Rm >> 6] |= 1LL << (FIELD_Rm & 63); + char Rm_width = 4; + + static const instruction_format instr_formats[] = + { + { /* VLD1<c>.<size> <registers_indexed>,[<Rn>,#<align>] */ + "vld1", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_NEON_SIZE, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REGISTERS_INDEXED,FIELD_registers_indexed,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_MEMORY_ONE_REG_ALIGNED,FIELD_Rn,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + { /* VLD1<c>.<size> <registers_indexed>,[<Rn>,#<align>]! */ + "vld1", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_NEON_SIZE, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REGISTERS_INDEXED,FIELD_registers_indexed,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_MEMORY_ONE_REG_ALIGNED,FIELD_Rn,FIELD_UNINIT,"","",WRITEBACK_YES}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + { /* VLD1<c>.<size> <registers_indexed>,[<Rn>,#<align>],<Rm> */ + "vld1", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_NEON_SIZE, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REGISTERS_INDEXED,FIELD_registers_indexed,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_MEMORY_ONE_REG_ALIGNED,FIELD_Rn,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rm,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 3; + res->mnem = armv7::ARMV7_VLD1; + + /* pcode: if size == '11' then UNDEFINED */ + if((res->fields[FIELD_size]) == (0x3)) { + res->status |= STATUS_UNDEFINED; + } + /* pcode: case size of */ + /* pcode: when '00' */ + if(res->fields[FIELD_size] == 0x0) { + /* pcode: if index_align<0> != '0' then UNDEFINED */ + if(((res->fields[FIELD_index_align] & 1)) != (0x0)) { + res->status |= STATUS_UNDEFINED; + } + /* pcode: ebytes = 1 */ + res->fields[FIELD_ebytes] = 1; + res->fields_mask[FIELD_ebytes >> 6] |= 1LL << (FIELD_ebytes & 63); + /* pcode: esize = 8 */ + res->fields[FIELD_esize] = 8; + res->fields_mask[FIELD_esize >> 6] |= 1LL << (FIELD_esize & 63); + /* pcode: index = UInt(index_align<3:1>) */ + res->fields[FIELD_index] = (((res->fields[FIELD_index_align] >> 1) & 0x7)); + res->fields_mask[FIELD_index >> 6] |= 1LL << (FIELD_index & 63); + /* pcode: alignment = 1 */ + res->fields[FIELD_alignment] = 1; + res->fields_mask[FIELD_alignment >> 6] |= 1LL << (FIELD_alignment & 63); + } + /* pcode: when '01' */ + else + if(res->fields[FIELD_size] == 0x1) { + /* pcode: if index_align<1> != '0' then UNDEFINED */ + if((((res->fields[FIELD_index_align] >> 1) & 1)) != (0x0)) { + res->status |= STATUS_UNDEFINED; + } + /* pcode: ebytes = 2 */ + res->fields[FIELD_ebytes] = 2; + res->fields_mask[FIELD_ebytes >> 6] |= 1LL << (FIELD_ebytes & 63); + /* pcode: esize = 16 */ + res->fields[FIELD_esize] = 16; + res->fields_mask[FIELD_esize >> 6] |= 1LL << (FIELD_esize & 63); + /* pcode: index = UInt(index_align<3:2>) */ + res->fields[FIELD_index] = (((res->fields[FIELD_index_align] >> 2) & 0x3)); + res->fields_mask[FIELD_index >> 6] |= 1LL << (FIELD_index & 63); + /* pcode: alignment = if index_align<0> == '0' then 1 else 16 */ + if(((res->fields[FIELD_index_align] & 1)) == (0x0)) { + res->fields[FIELD_alignment] = 1; + res->fields_mask[FIELD_alignment >> 6] |= 1LL << (FIELD_alignment & 63); + } + else { + res->fields[FIELD_alignment] = 16; + res->fields_mask[FIELD_alignment >> 6] |= 1LL << (FIELD_alignment & 63); + } + } + /* pcode: when '10' */ + else + if(res->fields[FIELD_size] == 0x2) { + /* pcode: if index_align<2> != '0' then UNDEFINED */ + if((((res->fields[FIELD_index_align] >> 2) & 1)) != (0x0)) { + res->status |= STATUS_UNDEFINED; + } + /* pcode: if index_align<1:0> != '00' && index_align<1:0> != '11' then UNDEFINED */ + if((((res->fields[FIELD_index_align] & 0x3)) != (0x0)) && (((res->fields[FIELD_index_align] & 0x3)) != (0x3))) { + res->status |= STATUS_UNDEFINED; + } + /* pcode: ebytes = 4 */ + res->fields[FIELD_ebytes] = 4; + res->fields_mask[FIELD_ebytes >> 6] |= 1LL << (FIELD_ebytes & 63); + /* pcode: esize = 32 */ + res->fields[FIELD_esize] = 32; + res->fields_mask[FIELD_esize >> 6] |= 1LL << (FIELD_esize & 63); + /* pcode: index = UInt(index_align<3>) */ + res->fields[FIELD_index] = (((res->fields[FIELD_index_align] >> 3) & 1)); + res->fields_mask[FIELD_index >> 6] |= 1LL << (FIELD_index & 63); + /* pcode: alignment = if index_align<1:0> == '00' then 1 else 32 */ + if(((res->fields[FIELD_index_align] & 0x3)) == (0x0)) { + res->fields[FIELD_alignment] = 1; + res->fields_mask[FIELD_alignment >> 6] |= 1LL << (FIELD_alignment & 63); + } + else { + res->fields[FIELD_alignment] = 32; + res->fields_mask[FIELD_alignment >> 6] |= 1LL << (FIELD_alignment & 63); + } + } + /* pcode: d = UInt(D:Vd) */ + res->fields[FIELD_d] = ((res->fields[FIELD_D]<<Vd_width)|(res->fields[FIELD_Vd])); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: n = UInt(Rn) */ + res->fields[FIELD_n] = (res->fields[FIELD_Rn]); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: m = UInt(Rm) */ + res->fields[FIELD_m] = (res->fields[FIELD_Rm]); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + /* pcode: wback = (m != 15) */ + res->fields[FIELD_wback] = ((res->fields[FIELD_m]) != (15)); + res->fields_mask[FIELD_wback >> 6] |= 1LL << (FIELD_wback & 63); + /* pcode: register_index = (m != 15 && m != 13) */ + res->fields[FIELD_register_index] = (((res->fields[FIELD_m]) != (15)) && ((res->fields[FIELD_m]) != (13))); + res->fields_mask[FIELD_register_index >> 6] |= 1LL << (FIELD_register_index & 63); + /* pcode: length = 1 */ + res->fields[FIELD_length] = 1; + res->fields_mask[FIELD_length >> 6] |= 1LL << (FIELD_length & 63); + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: 506494F8 +int vld1_single_1elem_nlanes(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + res->group = INSN_GROUP_NEON; + /* Encoding T1 */ + /* pattern="1111,1001,1,D.1,10,Rn.4,Vd.4,11,00,size.2,T.1,a.1,Rm.4" width=32 stringency=18 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFFB00F00)==0xF9A00C00)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ADVSIMD)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_D] = (instr & 0x400000)>>22; + res->fields_mask[FIELD_D >> 6] |= 1LL << (FIELD_D & 63); + char D_width = 1; + res->fields[FIELD_Rn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Rn >> 6] |= 1LL << (FIELD_Rn & 63); + char Rn_width = 4; + res->fields[FIELD_Vd] = (instr & 0xF000)>>12; + res->fields_mask[FIELD_Vd >> 6] |= 1LL << (FIELD_Vd & 63); + char Vd_width = 4; + res->fields[FIELD_size] = (instr & 0xC0)>>6; + res->fields_mask[FIELD_size >> 6] |= 1LL << (FIELD_size & 63); + char size_width = 2; + res->fields[FIELD_T] = (instr & 0x20)>>5; + res->fields_mask[FIELD_T >> 6] |= 1LL << (FIELD_T & 63); + char T_width = 1; + res->fields[FIELD_a] = (instr & 0x10)>>4; + res->fields_mask[FIELD_a >> 6] |= 1LL << (FIELD_a & 63); + char a_width = 1; + res->fields[FIELD_Rm] = instr & 0xF; + res->fields_mask[FIELD_Rm >> 6] |= 1LL << (FIELD_Rm & 63); + char Rm_width = 4; + + static const instruction_format instr_formats[] = + { + { /* VLD1<c>.<size> <registers[]>,[<Rn>,#<align>] */ + "vld1", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_NEON_SIZE, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REGISTERS,FIELD_registers,FIELD_UNINIT,"","[]",WRITEBACK_NO}, + {OPERAND_FORMAT_MEMORY_ONE_REG_ALIGNED,FIELD_Rn,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + { /* VLD1<c>.<size> <registers[]>,[<Rn>,#<align>]! */ + "vld1", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_NEON_SIZE, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REGISTERS,FIELD_registers,FIELD_UNINIT,"","[]",WRITEBACK_NO}, + {OPERAND_FORMAT_MEMORY_ONE_REG_ALIGNED,FIELD_Rn,FIELD_UNINIT,"","",WRITEBACK_YES}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + { /* VLD1<c>.<size> <registers[]>,[<Rn>,#<align>],<Rm> */ + "vld1", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_NEON_SIZE, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REGISTERS,FIELD_registers,FIELD_UNINIT,"","[]",WRITEBACK_NO}, + {OPERAND_FORMAT_MEMORY_ONE_REG_ALIGNED,FIELD_Rn,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rm,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 3; + res->mnem = armv7::ARMV7_VLD1; + + /* pcode: if size == '11' || (size == '00' && a == '1') then UNDEFINED */ + if(((res->fields[FIELD_size]) == (0x3)) || ((((res->fields[FIELD_size]) == (0x0)) && ((res->fields[FIELD_a]) == (0x1))))) { + res->status |= STATUS_UNDEFINED; + } + /* pcode: ebytes = 1 << UInt(size) */ + res->fields[FIELD_ebytes] = (1) << ((res->fields[FIELD_size])); + res->fields_mask[FIELD_ebytes >> 6] |= 1LL << (FIELD_ebytes & 63); + /* pcode: elements = 8 / ebytes */ + res->fields[FIELD_elements] = ((res->fields[FIELD_ebytes]) ? ((8) / (res->fields[FIELD_ebytes])) : 0); + res->fields_mask[FIELD_elements >> 6] |= 1LL << (FIELD_elements & 63); + /* pcode: regs = if T == '0' then 1 else 2 */ + if((res->fields[FIELD_T]) == (0x0)) { + res->fields[FIELD_regs] = 1; + res->fields_mask[FIELD_regs >> 6] |= 1LL << (FIELD_regs & 63); + } + else { + res->fields[FIELD_regs] = 2; + res->fields_mask[FIELD_regs >> 6] |= 1LL << (FIELD_regs & 63); + } + /* pcode: if a == '0' then alignment = 1 */ + if((res->fields[FIELD_a]) == (0x0)) { + res->fields[FIELD_alignment] = 1; + res->fields_mask[FIELD_alignment >> 6] |= 1LL << (FIELD_alignment & 63); + } + /* pcode: alignment = if a == '0' then 1 else 16*size */ + if((res->fields[FIELD_a]) == (0x0)) { + res->fields[FIELD_alignment] = 1; + res->fields_mask[FIELD_alignment >> 6] |= 1LL << (FIELD_alignment & 63); + } + else { + res->fields[FIELD_alignment] = (16) * (res->fields[FIELD_size]); + res->fields_mask[FIELD_alignment >> 6] |= 1LL << (FIELD_alignment & 63); + } + /* pcode: d = UInt(D:Vd) */ + res->fields[FIELD_d] = ((res->fields[FIELD_D]<<Vd_width)|(res->fields[FIELD_Vd])); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: n = UInt(Rn) */ + res->fields[FIELD_n] = (res->fields[FIELD_Rn]); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: m = UInt(Rm) */ + res->fields[FIELD_m] = (res->fields[FIELD_Rm]); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + /* pcode: wback = (m != 15) */ + res->fields[FIELD_wback] = ((res->fields[FIELD_m]) != (15)); + res->fields_mask[FIELD_wback >> 6] |= 1LL << (FIELD_wback & 63); + /* pcode: register_index = (m != 15 && m != 13) */ + res->fields[FIELD_register_index] = (((res->fields[FIELD_m]) != (15)) && ((res->fields[FIELD_m]) != (13))); + res->fields_mask[FIELD_register_index >> 6] |= 1LL << (FIELD_register_index & 63); + /* pcode: if d+regs > 32 then UNPREDICTABLE */ + if((res->fields[FIELD_d]) + ((res->fields[FIELD_regs]) > (32))) { + res->flags |= FLAG_UNPREDICTABLE; + } + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: 9D91C940 +int vld2_mult_2elem(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + res->group = INSN_GROUP_NEON; + /* Encoding T1 */ + /* pattern="1111,1001,0,D.1,10,Rn.4,Vd.4,type.4,size.2,align.2,Rm.4" width=32 stringency=12 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFFB00000)==0xF9200000)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ADVSIMD)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_D] = (instr & 0x400000)>>22; + res->fields_mask[FIELD_D >> 6] |= 1LL << (FIELD_D & 63); + char D_width = 1; + res->fields[FIELD_Rn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Rn >> 6] |= 1LL << (FIELD_Rn & 63); + char Rn_width = 4; + res->fields[FIELD_Vd] = (instr & 0xF000)>>12; + res->fields_mask[FIELD_Vd >> 6] |= 1LL << (FIELD_Vd & 63); + char Vd_width = 4; + res->fields[FIELD_type] = (instr & 0xF00)>>8; + res->fields_mask[FIELD_type >> 6] |= 1LL << (FIELD_type & 63); + char type_width = 4; + res->fields[FIELD_size] = (instr & 0xC0)>>6; + res->fields_mask[FIELD_size >> 6] |= 1LL << (FIELD_size & 63); + char size_width = 2; + res->fields[FIELD_align] = (instr & 0x30)>>4; + res->fields_mask[FIELD_align >> 6] |= 1LL << (FIELD_align & 63); + char align_width = 2; + res->fields[FIELD_Rm] = instr & 0xF; + res->fields_mask[FIELD_Rm >> 6] |= 1LL << (FIELD_Rm & 63); + char Rm_width = 4; + + static const instruction_format instr_formats[] = + { + { /* VLD2<c>.<size> <registers>,[<Rn>,#<align>] */ + "vld2", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_NEON_SIZE, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REGISTERS,FIELD_registers,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_MEMORY_ONE_REG_ALIGNED,FIELD_Rn,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + { /* VLD2<c>.<size> <registers>,[<Rn>,#<align>]! */ + "vld2", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_NEON_SIZE, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REGISTERS,FIELD_registers,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_MEMORY_ONE_REG_ALIGNED,FIELD_Rn,FIELD_UNINIT,"","",WRITEBACK_YES}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + { /* VLD2<c>.<size> <registers>,[<Rn>,#<align>],<Rm> */ + "vld2", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_NEON_SIZE, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REGISTERS,FIELD_registers,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_MEMORY_ONE_REG_ALIGNED,FIELD_Rn,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rm,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 3; + res->mnem = armv7::ARMV7_VLD2; + + /* pcode: if size == '11' then UNDEFINED */ + if((res->fields[FIELD_size]) == (0x3)) { + res->status |= STATUS_UNDEFINED; + } + /* pcode: case type of */ + /* pcode: when '1000' */ + if(res->fields[FIELD_type] == 0x8) { + /* pcode: regs = 2 */ + res->fields[FIELD_regs] = 2; + res->fields_mask[FIELD_regs >> 6] |= 1LL << (FIELD_regs & 63); + /* pcode: inc = 1 */ + res->fields[FIELD_inc] = 1; + res->fields_mask[FIELD_inc >> 6] |= 1LL << (FIELD_inc & 63); + /* pcode: if align == '11' then UNDEFINED */ + if((res->fields[FIELD_align]) == (0x3)) { + res->status |= STATUS_UNDEFINED; + } + } + /* pcode: when '1001' */ + else + if(res->fields[FIELD_type] == 0x9) { + /* pcode: regs = 2 */ + res->fields[FIELD_regs] = 2; + res->fields_mask[FIELD_regs >> 6] |= 1LL << (FIELD_regs & 63); + /* pcode: inc = 2 */ + res->fields[FIELD_inc] = 2; + res->fields_mask[FIELD_inc >> 6] |= 1LL << (FIELD_inc & 63); + /* pcode: if align == '11' then UNDEFINED */ + if((res->fields[FIELD_align]) == (0x3)) { + res->status |= STATUS_UNDEFINED; + } + } + /* pcode: when '0011' */ + else + if(res->fields[FIELD_type] == 0x3) { + /* pcode: regs = 4 */ + res->fields[FIELD_regs] = 4; + res->fields_mask[FIELD_regs >> 6] |= 1LL << (FIELD_regs & 63); + /* pcode: inc = 1 */ + res->fields[FIELD_inc] = 1; + res->fields_mask[FIELD_inc >> 6] |= 1LL << (FIELD_inc & 63); + } + /* pcode: alignment = if align == '00' then 1 else 64 << (align-1) */ + if((res->fields[FIELD_align]) == (0x0)) { + res->fields[FIELD_alignment] = 1; + res->fields_mask[FIELD_alignment >> 6] |= 1LL << (FIELD_alignment & 63); + } + else { + res->fields[FIELD_alignment] = (64) << (((res->fields[FIELD_align]) - (1))); + res->fields_mask[FIELD_alignment >> 6] |= 1LL << (FIELD_alignment & 63); + } + /* pcode: ebytes = 1 << UInt(size) */ + res->fields[FIELD_ebytes] = (1) << ((res->fields[FIELD_size])); + res->fields_mask[FIELD_ebytes >> 6] |= 1LL << (FIELD_ebytes & 63); + /* pcode: esize = 8 * ebytes */ + res->fields[FIELD_esize] = (8) * (res->fields[FIELD_ebytes]); + res->fields_mask[FIELD_esize >> 6] |= 1LL << (FIELD_esize & 63); + /* pcode: elements = 8 / ebytes */ + res->fields[FIELD_elements] = ((res->fields[FIELD_ebytes]) ? ((8) / (res->fields[FIELD_ebytes])) : 0); + res->fields_mask[FIELD_elements >> 6] |= 1LL << (FIELD_elements & 63); + /* pcode: d = UInt(D:Vd) */ + res->fields[FIELD_d] = ((res->fields[FIELD_D]<<Vd_width)|(res->fields[FIELD_Vd])); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: d2 = d + inc */ + res->fields[FIELD_d2] = (res->fields[FIELD_d]) + (res->fields[FIELD_inc]); + res->fields_mask[FIELD_d2 >> 6] |= 1LL << (FIELD_d2 & 63); + /* pcode: n = UInt(Rn) */ + res->fields[FIELD_n] = (res->fields[FIELD_Rn]); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: m = UInt(Rm) */ + res->fields[FIELD_m] = (res->fields[FIELD_Rm]); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + /* pcode: wback = (m != 15) */ + res->fields[FIELD_wback] = ((res->fields[FIELD_m]) != (15)); + res->fields_mask[FIELD_wback >> 6] |= 1LL << (FIELD_wback & 63); + /* pcode: register_index = (m != 15 && m != 13) */ + res->fields[FIELD_register_index] = (((res->fields[FIELD_m]) != (15)) && ((res->fields[FIELD_m]) != (13))); + res->fields_mask[FIELD_register_index >> 6] |= 1LL << (FIELD_register_index & 63); + /* pcode: if d2 + regs > 32 then UNPREDICTABLE */ + if((res->fields[FIELD_d2]) + ((res->fields[FIELD_regs]) > (32))) { + res->flags |= FLAG_UNPREDICTABLE; + } + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: D6E58D13 +int vld2_single_2elem_1lane(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + res->group = INSN_GROUP_NEON; + /* Encoding T1 */ + /* pattern="1111,1001,1,D.1,10,Rn.4,Vd.4,size.2,01,index_align.4,Rm.4" width=32 stringency=14 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFFB00300)==0xF9A00100)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ADVSIMD)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_D] = (instr & 0x400000)>>22; + res->fields_mask[FIELD_D >> 6] |= 1LL << (FIELD_D & 63); + char D_width = 1; + res->fields[FIELD_Rn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Rn >> 6] |= 1LL << (FIELD_Rn & 63); + char Rn_width = 4; + res->fields[FIELD_Vd] = (instr & 0xF000)>>12; + res->fields_mask[FIELD_Vd >> 6] |= 1LL << (FIELD_Vd & 63); + char Vd_width = 4; + res->fields[FIELD_size] = (instr & 0xC00)>>10; + res->fields_mask[FIELD_size >> 6] |= 1LL << (FIELD_size & 63); + char size_width = 2; + res->fields[FIELD_index_align] = (instr & 0xF0)>>4; + res->fields_mask[FIELD_index_align >> 6] |= 1LL << (FIELD_index_align & 63); + char index_align_width = 4; + res->fields[FIELD_Rm] = instr & 0xF; + res->fields_mask[FIELD_Rm >> 6] |= 1LL << (FIELD_Rm & 63); + char Rm_width = 4; + + static const instruction_format instr_formats[] = + { + { /* VLD2<c>.<size> <registers_indexed>,[<Rn>,#<align>] */ + "vld2", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_NEON_SIZE, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REGISTERS_INDEXED,FIELD_registers_indexed,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_MEMORY_ONE_REG_ALIGNED,FIELD_Rn,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + { /* VLD2<c>.<size> <registers_indexed>,[<Rn>,#<align>]! */ + "vld2", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_NEON_SIZE, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REGISTERS_INDEXED,FIELD_registers_indexed,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_MEMORY_ONE_REG_ALIGNED,FIELD_Rn,FIELD_UNINIT,"","",WRITEBACK_YES}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + { /* VLD2<c>.<size> <registers_indexed>,[<Rn>,#<align>],<Rm> */ + "vld2", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_NEON_SIZE, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REGISTERS_INDEXED,FIELD_registers_indexed,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_MEMORY_ONE_REG_ALIGNED,FIELD_Rn,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rm,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 3; + res->mnem = armv7::ARMV7_VLD2; + + /* pcode: if size == '11' then UNDEFINED */ + if((res->fields[FIELD_size]) == (0x3)) { + res->status |= STATUS_UNDEFINED; + } + /* pcode: case size of */ + /* pcode: when '00' */ + if(res->fields[FIELD_size] == 0x0) { + /* pcode: ebytes = 1 */ + res->fields[FIELD_ebytes] = 1; + res->fields_mask[FIELD_ebytes >> 6] |= 1LL << (FIELD_ebytes & 63); + /* pcode: esize = 8 */ + res->fields[FIELD_esize] = 8; + res->fields_mask[FIELD_esize >> 6] |= 1LL << (FIELD_esize & 63); + /* pcode: index = UInt(index_align<3:1>) */ + res->fields[FIELD_index] = (((res->fields[FIELD_index_align] >> 1) & 0x7)); + res->fields_mask[FIELD_index >> 6] |= 1LL << (FIELD_index & 63); + /* pcode: inc = 1 */ + res->fields[FIELD_inc] = 1; + res->fields_mask[FIELD_inc >> 6] |= 1LL << (FIELD_inc & 63); + /* pcode: alignment = if index_align<0> == '0' then 1 else 16 */ + if(((res->fields[FIELD_index_align] & 1)) == (0x0)) { + res->fields[FIELD_alignment] = 1; + res->fields_mask[FIELD_alignment >> 6] |= 1LL << (FIELD_alignment & 63); + } + else { + res->fields[FIELD_alignment] = 16; + res->fields_mask[FIELD_alignment >> 6] |= 1LL << (FIELD_alignment & 63); + } + } + /* pcode: when '01' */ + else + if(res->fields[FIELD_size] == 0x1) { + /* pcode: ebytes = 2 */ + res->fields[FIELD_ebytes] = 2; + res->fields_mask[FIELD_ebytes >> 6] |= 1LL << (FIELD_ebytes & 63); + /* pcode: esize = 16 */ + res->fields[FIELD_esize] = 16; + res->fields_mask[FIELD_esize >> 6] |= 1LL << (FIELD_esize & 63); + /* pcode: index = UInt(index_align<3:2>) */ + res->fields[FIELD_index] = (((res->fields[FIELD_index_align] >> 2) & 0x3)); + res->fields_mask[FIELD_index >> 6] |= 1LL << (FIELD_index & 63); + /* pcode: inc = if index_align<1> == '0' then 1 else 2 */ + if((((res->fields[FIELD_index_align] >> 1) & 1)) == (0x0)) { + res->fields[FIELD_inc] = 1; + res->fields_mask[FIELD_inc >> 6] |= 1LL << (FIELD_inc & 63); + } + else { + res->fields[FIELD_inc] = 2; + res->fields_mask[FIELD_inc >> 6] |= 1LL << (FIELD_inc & 63); + } + /* pcode: alignment = if index_align<0> == '0' then 1 else 32 */ + if(((res->fields[FIELD_index_align] & 1)) == (0x0)) { + res->fields[FIELD_alignment] = 1; + res->fields_mask[FIELD_alignment >> 6] |= 1LL << (FIELD_alignment & 63); + } + else { + res->fields[FIELD_alignment] = 32; + res->fields_mask[FIELD_alignment >> 6] |= 1LL << (FIELD_alignment & 63); + } + } + /* pcode: when '10' */ + else + if(res->fields[FIELD_size] == 0x2) { + /* pcode: if index_align<1> != '0' then UNDEFINED */ + if((((res->fields[FIELD_index_align] >> 1) & 1)) != (0x0)) { + res->status |= STATUS_UNDEFINED; + } + /* pcode: ebytes = 4 */ + res->fields[FIELD_ebytes] = 4; + res->fields_mask[FIELD_ebytes >> 6] |= 1LL << (FIELD_ebytes & 63); + /* pcode: esize = 32 */ + res->fields[FIELD_esize] = 32; + res->fields_mask[FIELD_esize >> 6] |= 1LL << (FIELD_esize & 63); + /* pcode: index = UInt(index_align<3>) */ + res->fields[FIELD_index] = (((res->fields[FIELD_index_align] >> 3) & 1)); + res->fields_mask[FIELD_index >> 6] |= 1LL << (FIELD_index & 63); + /* pcode: inc = if index_align<2> == '0' then 1 else 2 */ + if((((res->fields[FIELD_index_align] >> 2) & 1)) == (0x0)) { + res->fields[FIELD_inc] = 1; + res->fields_mask[FIELD_inc >> 6] |= 1LL << (FIELD_inc & 63); + } + else { + res->fields[FIELD_inc] = 2; + res->fields_mask[FIELD_inc >> 6] |= 1LL << (FIELD_inc & 63); + } + /* pcode: alignment = if index_align<0> == '0' then 1 else 64 */ + if(((res->fields[FIELD_index_align] & 1)) == (0x0)) { + res->fields[FIELD_alignment] = 1; + res->fields_mask[FIELD_alignment >> 6] |= 1LL << (FIELD_alignment & 63); + } + else { + res->fields[FIELD_alignment] = 64; + res->fields_mask[FIELD_alignment >> 6] |= 1LL << (FIELD_alignment & 63); + } + } + /* pcode: d = UInt(D:Vd) */ + res->fields[FIELD_d] = ((res->fields[FIELD_D]<<Vd_width)|(res->fields[FIELD_Vd])); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: d2 = d + inc */ + res->fields[FIELD_d2] = (res->fields[FIELD_d]) + (res->fields[FIELD_inc]); + res->fields_mask[FIELD_d2 >> 6] |= 1LL << (FIELD_d2 & 63); + /* pcode: n = UInt(Rn) */ + res->fields[FIELD_n] = (res->fields[FIELD_Rn]); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: m = UInt(Rm) */ + res->fields[FIELD_m] = (res->fields[FIELD_Rm]); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + /* pcode: wback = (m != 15) */ + res->fields[FIELD_wback] = ((res->fields[FIELD_m]) != (15)); + res->fields_mask[FIELD_wback >> 6] |= 1LL << (FIELD_wback & 63); + /* pcode: register_index = (m != 15 && m != 13) */ + res->fields[FIELD_register_index] = (((res->fields[FIELD_m]) != (15)) && ((res->fields[FIELD_m]) != (13))); + res->fields_mask[FIELD_register_index >> 6] |= 1LL << (FIELD_register_index & 63); + /* pcode: if d2 > 31 then UNPREDICTABLE */ + if((res->fields[FIELD_d2]) > (31)) { + res->flags |= FLAG_UNPREDICTABLE; + } + /* pcode: length = 2 */ + res->fields[FIELD_length] = 2; + res->fields_mask[FIELD_length >> 6] |= 1LL << (FIELD_length & 63); + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: 4D342447 +int vld2_single_2elem_nlanes(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + res->group = INSN_GROUP_NEON; + /* Encoding T1 */ + /* pattern="1111,1001,1,D.1,10,Rn.4,Vd.4,11,01,size.2,T.1,a.1,Rm.4" width=32 stringency=18 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFFB00F00)==0xF9A00D00)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ADVSIMD)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_D] = (instr & 0x400000)>>22; + res->fields_mask[FIELD_D >> 6] |= 1LL << (FIELD_D & 63); + char D_width = 1; + res->fields[FIELD_Rn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Rn >> 6] |= 1LL << (FIELD_Rn & 63); + char Rn_width = 4; + res->fields[FIELD_Vd] = (instr & 0xF000)>>12; + res->fields_mask[FIELD_Vd >> 6] |= 1LL << (FIELD_Vd & 63); + char Vd_width = 4; + res->fields[FIELD_size] = (instr & 0xC0)>>6; + res->fields_mask[FIELD_size >> 6] |= 1LL << (FIELD_size & 63); + char size_width = 2; + res->fields[FIELD_T] = (instr & 0x20)>>5; + res->fields_mask[FIELD_T >> 6] |= 1LL << (FIELD_T & 63); + char T_width = 1; + res->fields[FIELD_a] = (instr & 0x10)>>4; + res->fields_mask[FIELD_a >> 6] |= 1LL << (FIELD_a & 63); + char a_width = 1; + res->fields[FIELD_Rm] = instr & 0xF; + res->fields_mask[FIELD_Rm >> 6] |= 1LL << (FIELD_Rm & 63); + char Rm_width = 4; + + static const instruction_format instr_formats[] = + { + { /* VLD2<c>.<size> <registers[]>,[<Rn>,#<align>] */ + "vld2", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_NEON_SIZE, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REGISTERS,FIELD_registers,FIELD_UNINIT,"","[]",WRITEBACK_NO}, + {OPERAND_FORMAT_MEMORY_ONE_REG_ALIGNED,FIELD_Rn,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + { /* VLD2<c>.<size> <registers[]>,[<Rn>,#<align>]! */ + "vld2", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_NEON_SIZE, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REGISTERS,FIELD_registers,FIELD_UNINIT,"","[]",WRITEBACK_NO}, + {OPERAND_FORMAT_MEMORY_ONE_REG_ALIGNED,FIELD_Rn,FIELD_UNINIT,"","",WRITEBACK_YES}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + { /* VLD2<c>.<size> <registers[]>,[<Rn>,#<align>],<Rm> */ + "vld2", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_NEON_SIZE, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REGISTERS,FIELD_registers,FIELD_UNINIT,"","[]",WRITEBACK_NO}, + {OPERAND_FORMAT_MEMORY_ONE_REG_ALIGNED,FIELD_Rn,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rm,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 3; + res->mnem = armv7::ARMV7_VLD2; + + /* pcode: if size == '11' then UNDEFINED */ + if((res->fields[FIELD_size]) == (0x3)) { + res->status |= STATUS_UNDEFINED; + } + /* pcode: ebytes = 1 << UInt(size) */ + res->fields[FIELD_ebytes] = (1) << ((res->fields[FIELD_size])); + res->fields_mask[FIELD_ebytes >> 6] |= 1LL << (FIELD_ebytes & 63); + /* pcode: elements = 8 / ebytes */ + res->fields[FIELD_elements] = ((res->fields[FIELD_ebytes]) ? ((8) / (res->fields[FIELD_ebytes])) : 0); + res->fields_mask[FIELD_elements >> 6] |= 1LL << (FIELD_elements & 63); + /* pcode: alignment = if a == '0' then 1 else 16<<size */ + if((res->fields[FIELD_a]) == (0x0)) { + res->fields[FIELD_alignment] = 1; + res->fields_mask[FIELD_alignment >> 6] |= 1LL << (FIELD_alignment & 63); + } + else { + res->fields[FIELD_alignment] = (16) << (res->fields[FIELD_size]); + res->fields_mask[FIELD_alignment >> 6] |= 1LL << (FIELD_alignment & 63); + } + /* pcode: inc = if T == '0' then 1 else 2 */ + if((res->fields[FIELD_T]) == (0x0)) { + res->fields[FIELD_inc] = 1; + res->fields_mask[FIELD_inc >> 6] |= 1LL << (FIELD_inc & 63); + } + else { + res->fields[FIELD_inc] = 2; + res->fields_mask[FIELD_inc >> 6] |= 1LL << (FIELD_inc & 63); + } + /* pcode: d = UInt(D:Vd) */ + res->fields[FIELD_d] = ((res->fields[FIELD_D]<<Vd_width)|(res->fields[FIELD_Vd])); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: d2 = d + inc */ + res->fields[FIELD_d2] = (res->fields[FIELD_d]) + (res->fields[FIELD_inc]); + res->fields_mask[FIELD_d2 >> 6] |= 1LL << (FIELD_d2 & 63); + /* pcode: n = UInt(Rn) */ + res->fields[FIELD_n] = (res->fields[FIELD_Rn]); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: m = UInt(Rm) */ + res->fields[FIELD_m] = (res->fields[FIELD_Rm]); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + /* pcode: wback = (m != 15) */ + res->fields[FIELD_wback] = ((res->fields[FIELD_m]) != (15)); + res->fields_mask[FIELD_wback >> 6] |= 1LL << (FIELD_wback & 63); + /* pcode: register_index = (m != 15 && m != 13) */ + res->fields[FIELD_register_index] = (((res->fields[FIELD_m]) != (15)) && ((res->fields[FIELD_m]) != (13))); + res->fields_mask[FIELD_register_index >> 6] |= 1LL << (FIELD_register_index & 63); + /* pcode: if d2 > 31 then UNPREDICTABLE */ + if((res->fields[FIELD_d2]) > (31)) { + res->flags |= FLAG_UNPREDICTABLE; + } + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: 92E2DFBB +int vld3_mult_3elem(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + res->group = INSN_GROUP_NEON; + /* Encoding T1 */ + /* pattern="1111,1001,0,D.1,10,Rn.4,Vd.4,type.4,size.2,align.2,Rm.4" width=32 stringency=12 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFFB00000)==0xF9200000)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ADVSIMD)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_D] = (instr & 0x400000)>>22; + res->fields_mask[FIELD_D >> 6] |= 1LL << (FIELD_D & 63); + char D_width = 1; + res->fields[FIELD_Rn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Rn >> 6] |= 1LL << (FIELD_Rn & 63); + char Rn_width = 4; + res->fields[FIELD_Vd] = (instr & 0xF000)>>12; + res->fields_mask[FIELD_Vd >> 6] |= 1LL << (FIELD_Vd & 63); + char Vd_width = 4; + res->fields[FIELD_type] = (instr & 0xF00)>>8; + res->fields_mask[FIELD_type >> 6] |= 1LL << (FIELD_type & 63); + char type_width = 4; + res->fields[FIELD_size] = (instr & 0xC0)>>6; + res->fields_mask[FIELD_size >> 6] |= 1LL << (FIELD_size & 63); + char size_width = 2; + res->fields[FIELD_align] = (instr & 0x30)>>4; + res->fields_mask[FIELD_align >> 6] |= 1LL << (FIELD_align & 63); + char align_width = 2; + res->fields[FIELD_Rm] = instr & 0xF; + res->fields_mask[FIELD_Rm >> 6] |= 1LL << (FIELD_Rm & 63); + char Rm_width = 4; + + static const instruction_format instr_formats[] = + { + { /* VLD3<c>.<size> <registers>,[<Rn>,#<align>] */ + "vld3", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_NEON_SIZE, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REGISTERS,FIELD_registers,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_MEMORY_ONE_REG_ALIGNED,FIELD_Rn,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + { /* VLD3<c>.<size> <registers>,[<Rn>,#<align>]! */ + "vld3", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_NEON_SIZE, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REGISTERS,FIELD_registers,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_MEMORY_ONE_REG_ALIGNED,FIELD_Rn,FIELD_UNINIT,"","",WRITEBACK_YES}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + { /* VLD3<c>.<size> <registers>,[<Rn>,#<align>],<Rm> */ + "vld3", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_NEON_SIZE, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REGISTERS,FIELD_registers,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_MEMORY_ONE_REG_ALIGNED,FIELD_Rn,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rm,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 3; + res->mnem = armv7::ARMV7_VLD3; + + /* pcode: if size=='11' || align==2 || align==3 then UNDEFINED */ + if((((res->fields[FIELD_size]) == (0x3)) || ((res->fields[FIELD_align]) == (2))) || ((res->fields[FIELD_align]) == (3))) { + res->status |= STATUS_UNDEFINED; + } + /* pcode: regs_n = 3 */ + res->fields[FIELD_regs_n] = 3; + res->fields_mask[FIELD_regs_n >> 6] |= 1LL << (FIELD_regs_n & 63); + /* pcode: if type=='0100' then inc=1 */ + if((res->fields[FIELD_type]) == (0x4)) { + res->fields[FIELD_inc] = 1; + res->fields_mask[FIELD_inc >> 6] |= 1LL << (FIELD_inc & 63); + } + /* pcode: if type=='0101' then inc=2 */ + if((res->fields[FIELD_type]) == (0x5)) { + res->fields[FIELD_inc] = 2; + res->fields_mask[FIELD_inc >> 6] |= 1LL << (FIELD_inc & 63); + } + /* pcode: alignment=64 */ + res->fields[FIELD_alignment] = 64; + res->fields_mask[FIELD_alignment >> 6] |= 1LL << (FIELD_alignment & 63); + /* pcode: if align==0 || align==2 then alignment=1 */ + if(((res->fields[FIELD_align]) == (0)) || ((res->fields[FIELD_align]) == (2))) { + res->fields[FIELD_alignment] = 1; + res->fields_mask[FIELD_alignment >> 6] |= 1LL << (FIELD_alignment & 63); + } + /* pcode: d = D:Vd */ + res->fields[FIELD_d] = (res->fields[FIELD_D]<<Vd_width)|(res->fields[FIELD_Vd]); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: d2 = d + inc */ + res->fields[FIELD_d2] = (res->fields[FIELD_d]) + (res->fields[FIELD_inc]); + res->fields_mask[FIELD_d2 >> 6] |= 1LL << (FIELD_d2 & 63); + /* pcode: d3 = d2 + inc */ + res->fields[FIELD_d3] = (res->fields[FIELD_d2]) + (res->fields[FIELD_inc]); + res->fields_mask[FIELD_d3 >> 6] |= 1LL << (FIELD_d3 & 63); + /* pcode: wback = (Rm != 15) */ + res->fields[FIELD_wback] = ((res->fields[FIELD_Rm]) != (15)); + res->fields_mask[FIELD_wback >> 6] |= 1LL << (FIELD_wback & 63); + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: CA96450F +int vld3_single_3elem_1lane(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + res->group = INSN_GROUP_NEON; + /* Encoding T1 */ + /* pattern="1111,1001,1,D.1,10,Rn.4,Vd.4,size.2,10,index_align.4,Rm.4" width=32 stringency=14 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFFB00300)==0xF9A00200)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ADVSIMD)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_D] = (instr & 0x400000)>>22; + res->fields_mask[FIELD_D >> 6] |= 1LL << (FIELD_D & 63); + char D_width = 1; + res->fields[FIELD_Rn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Rn >> 6] |= 1LL << (FIELD_Rn & 63); + char Rn_width = 4; + res->fields[FIELD_Vd] = (instr & 0xF000)>>12; + res->fields_mask[FIELD_Vd >> 6] |= 1LL << (FIELD_Vd & 63); + char Vd_width = 4; + res->fields[FIELD_size] = (instr & 0xC00)>>10; + res->fields_mask[FIELD_size >> 6] |= 1LL << (FIELD_size & 63); + char size_width = 2; + res->fields[FIELD_index_align] = (instr & 0xF0)>>4; + res->fields_mask[FIELD_index_align >> 6] |= 1LL << (FIELD_index_align & 63); + char index_align_width = 4; + res->fields[FIELD_Rm] = instr & 0xF; + res->fields_mask[FIELD_Rm >> 6] |= 1LL << (FIELD_Rm & 63); + char Rm_width = 4; + + static const instruction_format instr_formats[] = + { + { /* VLD3<c>.<size> <registers_indexed>,[<Rn>,#<align>] */ + "vld3", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_NEON_SIZE, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REGISTERS_INDEXED,FIELD_registers_indexed,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_MEMORY_ONE_REG_ALIGNED,FIELD_Rn,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + { /* VLD3<c>.<size> <registers_indexed>,[<Rn>,#<align>]! */ + "vld3", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_NEON_SIZE, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REGISTERS_INDEXED,FIELD_registers_indexed,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_MEMORY_ONE_REG_ALIGNED,FIELD_Rn,FIELD_UNINIT,"","",WRITEBACK_YES}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + { /* VLD3<c>.<size> <registers_indexed>,[<Rn>,#<align>],<Rm> */ + "vld3", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_NEON_SIZE, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REGISTERS_INDEXED,FIELD_registers_indexed,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_MEMORY_ONE_REG_ALIGNED,FIELD_Rn,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rm,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 3; + res->mnem = armv7::ARMV7_VLD3; + + /* pcode: if size == '11' then UNDEFINED */ + if((res->fields[FIELD_size]) == (0x3)) { + res->status |= STATUS_UNDEFINED; + } + /* pcode: case size of */ + /* pcode: when '00' */ + if(res->fields[FIELD_size] == 0x0) { + /* pcode: if index_align<0> != '0' then UNDEFINED */ + if(((res->fields[FIELD_index_align] & 1)) != (0x0)) { + res->status |= STATUS_UNDEFINED; + } + /* pcode: ebytes = 1 */ + res->fields[FIELD_ebytes] = 1; + res->fields_mask[FIELD_ebytes >> 6] |= 1LL << (FIELD_ebytes & 63); + /* pcode: esize = 8 */ + res->fields[FIELD_esize] = 8; + res->fields_mask[FIELD_esize >> 6] |= 1LL << (FIELD_esize & 63); + /* pcode: index = UInt(index_align<3:1>) */ + res->fields[FIELD_index] = (((res->fields[FIELD_index_align] >> 1) & 0x7)); + res->fields_mask[FIELD_index >> 6] |= 1LL << (FIELD_index & 63); + /* pcode: inc = 1 */ + res->fields[FIELD_inc] = 1; + res->fields_mask[FIELD_inc >> 6] |= 1LL << (FIELD_inc & 63); + } + /* pcode: when '01' */ + else + if(res->fields[FIELD_size] == 0x1) { + /* pcode: if index_align<0> != '0' then UNDEFINED */ + if(((res->fields[FIELD_index_align] & 1)) != (0x0)) { + res->status |= STATUS_UNDEFINED; + } + /* pcode: ebytes = 2 */ + res->fields[FIELD_ebytes] = 2; + res->fields_mask[FIELD_ebytes >> 6] |= 1LL << (FIELD_ebytes & 63); + /* pcode: esize = 16 */ + res->fields[FIELD_esize] = 16; + res->fields_mask[FIELD_esize >> 6] |= 1LL << (FIELD_esize & 63); + /* pcode: index = UInt(index_align<3:2>) */ + res->fields[FIELD_index] = (((res->fields[FIELD_index_align] >> 2) & 0x3)); + res->fields_mask[FIELD_index >> 6] |= 1LL << (FIELD_index & 63); + /* pcode: inc = if index_align<1> == '0' then 1 else 2 */ + if((((res->fields[FIELD_index_align] >> 1) & 1)) == (0x0)) { + res->fields[FIELD_inc] = 1; + res->fields_mask[FIELD_inc >> 6] |= 1LL << (FIELD_inc & 63); + } + else { + res->fields[FIELD_inc] = 2; + res->fields_mask[FIELD_inc >> 6] |= 1LL << (FIELD_inc & 63); + } + } + /* pcode: when '10' */ + else + if(res->fields[FIELD_size] == 0x2) { + /* pcode: if index_align<1:0> != '00' then UNDEFINED */ + if(((res->fields[FIELD_index_align] & 0x3)) != (0x0)) { + res->status |= STATUS_UNDEFINED; + } + /* pcode: ebytes = 4 */ + res->fields[FIELD_ebytes] = 4; + res->fields_mask[FIELD_ebytes >> 6] |= 1LL << (FIELD_ebytes & 63); + /* pcode: esize = 32 */ + res->fields[FIELD_esize] = 32; + res->fields_mask[FIELD_esize >> 6] |= 1LL << (FIELD_esize & 63); + /* pcode: index = UInt(index_align<3>) */ + res->fields[FIELD_index] = (((res->fields[FIELD_index_align] >> 3) & 1)); + res->fields_mask[FIELD_index >> 6] |= 1LL << (FIELD_index & 63); + /* pcode: inc = if index_align<2> == '0' then 1 else 2 */ + if((((res->fields[FIELD_index_align] >> 2) & 1)) == (0x0)) { + res->fields[FIELD_inc] = 1; + res->fields_mask[FIELD_inc >> 6] |= 1LL << (FIELD_inc & 63); + } + else { + res->fields[FIELD_inc] = 2; + res->fields_mask[FIELD_inc >> 6] |= 1LL << (FIELD_inc & 63); + } + } + /* pcode: d = UInt(D:Vd) */ + res->fields[FIELD_d] = ((res->fields[FIELD_D]<<Vd_width)|(res->fields[FIELD_Vd])); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: d2 = d + inc */ + res->fields[FIELD_d2] = (res->fields[FIELD_d]) + (res->fields[FIELD_inc]); + res->fields_mask[FIELD_d2 >> 6] |= 1LL << (FIELD_d2 & 63); + /* pcode: d3 = d2 + inc */ + res->fields[FIELD_d3] = (res->fields[FIELD_d2]) + (res->fields[FIELD_inc]); + res->fields_mask[FIELD_d3 >> 6] |= 1LL << (FIELD_d3 & 63); + /* pcode: n = UInt(Rn) */ + res->fields[FIELD_n] = (res->fields[FIELD_Rn]); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: m = UInt(Rm) */ + res->fields[FIELD_m] = (res->fields[FIELD_Rm]); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + /* pcode: wback = (m != 15) */ + res->fields[FIELD_wback] = ((res->fields[FIELD_m]) != (15)); + res->fields_mask[FIELD_wback >> 6] |= 1LL << (FIELD_wback & 63); + /* pcode: register_index = (m != 15 && m != 13) */ + res->fields[FIELD_register_index] = (((res->fields[FIELD_m]) != (15)) && ((res->fields[FIELD_m]) != (13))); + res->fields_mask[FIELD_register_index >> 6] |= 1LL << (FIELD_register_index & 63); + /* pcode: if d3 > 31 then UNPREDICTABLE */ + if((res->fields[FIELD_d3]) > (31)) { + res->flags |= FLAG_UNPREDICTABLE; + } + /* pcode: alignment = 1 */ + res->fields[FIELD_alignment] = 1; + res->fields_mask[FIELD_alignment >> 6] |= 1LL << (FIELD_alignment & 63); + /* pcode: length = 3 */ + res->fields[FIELD_length] = 3; + res->fields_mask[FIELD_length >> 6] |= 1LL << (FIELD_length & 63); + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: B29A1E02 +int vld3_single_3elem_nlanes(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + res->group = INSN_GROUP_NEON; + /* Encoding T1 */ + /* pattern="1111,1001,1,D.1,10,Rn.4,Vd.4,11,10,size.2,T.1,a.1,Rm.4" width=32 stringency=18 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFFB00F00)==0xF9A00E00)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ADVSIMD)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_D] = (instr & 0x400000)>>22; + res->fields_mask[FIELD_D >> 6] |= 1LL << (FIELD_D & 63); + char D_width = 1; + res->fields[FIELD_Rn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Rn >> 6] |= 1LL << (FIELD_Rn & 63); + char Rn_width = 4; + res->fields[FIELD_Vd] = (instr & 0xF000)>>12; + res->fields_mask[FIELD_Vd >> 6] |= 1LL << (FIELD_Vd & 63); + char Vd_width = 4; + res->fields[FIELD_size] = (instr & 0xC0)>>6; + res->fields_mask[FIELD_size >> 6] |= 1LL << (FIELD_size & 63); + char size_width = 2; + res->fields[FIELD_T] = (instr & 0x20)>>5; + res->fields_mask[FIELD_T >> 6] |= 1LL << (FIELD_T & 63); + char T_width = 1; + res->fields[FIELD_a] = (instr & 0x10)>>4; + res->fields_mask[FIELD_a >> 6] |= 1LL << (FIELD_a & 63); + char a_width = 1; + res->fields[FIELD_Rm] = instr & 0xF; + res->fields_mask[FIELD_Rm >> 6] |= 1LL << (FIELD_Rm & 63); + char Rm_width = 4; + + static const instruction_format instr_formats[] = + { + { /* VLD3<c>.<size> <registers[]>,[<Rn>,#<align>] */ + "vld3", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_NEON_SIZE, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REGISTERS,FIELD_registers,FIELD_UNINIT,"","[]",WRITEBACK_NO}, + {OPERAND_FORMAT_MEMORY_ONE_REG_ALIGNED,FIELD_Rn,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + { /* VLD3<c>.<size> <registers[]>,[<Rn>,#<align>]! */ + "vld3", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_NEON_SIZE, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REGISTERS,FIELD_registers,FIELD_UNINIT,"","[]",WRITEBACK_NO}, + {OPERAND_FORMAT_MEMORY_ONE_REG_ALIGNED,FIELD_Rn,FIELD_UNINIT,"","",WRITEBACK_YES}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + { /* VLD3<c>.<size> <registers[]>,[<Rn>,#<align>],<Rm> */ + "vld3", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_NEON_SIZE, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REGISTERS,FIELD_registers,FIELD_UNINIT,"","[]",WRITEBACK_NO}, + {OPERAND_FORMAT_MEMORY_ONE_REG_ALIGNED,FIELD_Rn,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rm,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 3; + res->mnem = armv7::ARMV7_VLD3; + + /* pcode: if size == '11' || a == '1' then UNDEFINED */ + if(((res->fields[FIELD_size]) == (0x3)) || ((res->fields[FIELD_a]) == (0x1))) { + res->status |= STATUS_UNDEFINED; + } + /* pcode: ebytes = 1 << UInt(size) */ + res->fields[FIELD_ebytes] = (1) << ((res->fields[FIELD_size])); + res->fields_mask[FIELD_ebytes >> 6] |= 1LL << (FIELD_ebytes & 63); + /* pcode: elements = 8 / ebytes */ + res->fields[FIELD_elements] = ((res->fields[FIELD_ebytes]) ? ((8) / (res->fields[FIELD_ebytes])) : 0); + res->fields_mask[FIELD_elements >> 6] |= 1LL << (FIELD_elements & 63); + /* pcode: inc = if T == '0' then 1 else 2 */ + if((res->fields[FIELD_T]) == (0x0)) { + res->fields[FIELD_inc] = 1; + res->fields_mask[FIELD_inc >> 6] |= 1LL << (FIELD_inc & 63); + } + else { + res->fields[FIELD_inc] = 2; + res->fields_mask[FIELD_inc >> 6] |= 1LL << (FIELD_inc & 63); + } + /* pcode: d = UInt(D:Vd) */ + res->fields[FIELD_d] = ((res->fields[FIELD_D]<<Vd_width)|(res->fields[FIELD_Vd])); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: d2 = d + inc */ + res->fields[FIELD_d2] = (res->fields[FIELD_d]) + (res->fields[FIELD_inc]); + res->fields_mask[FIELD_d2 >> 6] |= 1LL << (FIELD_d2 & 63); + /* pcode: d3 = d2 + inc */ + res->fields[FIELD_d3] = (res->fields[FIELD_d2]) + (res->fields[FIELD_inc]); + res->fields_mask[FIELD_d3 >> 6] |= 1LL << (FIELD_d3 & 63); + /* pcode: n = UInt(Rn) */ + res->fields[FIELD_n] = (res->fields[FIELD_Rn]); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: wback = (m != 15) */ + res->fields[FIELD_wback] = ((res->fields[FIELD_m]) != (15)); + res->fields_mask[FIELD_wback >> 6] |= 1LL << (FIELD_wback & 63); + /* pcode: register_index = (m != 15 && m != 13) */ + res->fields[FIELD_register_index] = (((res->fields[FIELD_m]) != (15)) && ((res->fields[FIELD_m]) != (13))); + res->fields_mask[FIELD_register_index >> 6] |= 1LL << (FIELD_register_index & 63); + /* pcode: if d3 > 31 then UNPREDICTABLE */ + if((res->fields[FIELD_d3]) > (31)) { + res->flags |= FLAG_UNPREDICTABLE; + } + /* pcode: alignment = 1 */ + res->fields[FIELD_alignment] = 1; + res->fields_mask[FIELD_alignment >> 6] |= 1LL << (FIELD_alignment & 63); + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: D46709C7 +int vld4_mult_4elem(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + res->group = INSN_GROUP_NEON; + /* Encoding T1 */ + /* pattern="1111,1001,0,D.1,10,Rn.4,Vd.4,type.4,size.2,align.2,Rm.4" width=32 stringency=12 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFFB00000)==0xF9200000)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ADVSIMD)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_D] = (instr & 0x400000)>>22; + res->fields_mask[FIELD_D >> 6] |= 1LL << (FIELD_D & 63); + char D_width = 1; + res->fields[FIELD_Rn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Rn >> 6] |= 1LL << (FIELD_Rn & 63); + char Rn_width = 4; + res->fields[FIELD_Vd] = (instr & 0xF000)>>12; + res->fields_mask[FIELD_Vd >> 6] |= 1LL << (FIELD_Vd & 63); + char Vd_width = 4; + res->fields[FIELD_type] = (instr & 0xF00)>>8; + res->fields_mask[FIELD_type >> 6] |= 1LL << (FIELD_type & 63); + char type_width = 4; + res->fields[FIELD_size] = (instr & 0xC0)>>6; + res->fields_mask[FIELD_size >> 6] |= 1LL << (FIELD_size & 63); + char size_width = 2; + res->fields[FIELD_align] = (instr & 0x30)>>4; + res->fields_mask[FIELD_align >> 6] |= 1LL << (FIELD_align & 63); + char align_width = 2; + res->fields[FIELD_Rm] = instr & 0xF; + res->fields_mask[FIELD_Rm >> 6] |= 1LL << (FIELD_Rm & 63); + char Rm_width = 4; + + static const instruction_format instr_formats[] = + { + { /* VLD4<c>.<size> <registers>,[<Rn>,#<align>] */ + "vld4", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_NEON_SIZE, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REGISTERS,FIELD_registers,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_MEMORY_ONE_REG_ALIGNED,FIELD_Rn,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + { /* VLD4<c>.<size> <registers>,[<Rn>,#<align>]! */ + "vld4", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_NEON_SIZE, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REGISTERS,FIELD_registers,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_MEMORY_ONE_REG_ALIGNED,FIELD_Rn,FIELD_UNINIT,"","",WRITEBACK_YES}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + { /* VLD4<c>.<size> <registers>,[<Rn>,#<align>],<Rm> */ + "vld4", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_NEON_SIZE, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REGISTERS,FIELD_registers,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_MEMORY_ONE_REG_ALIGNED,FIELD_Rn,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rm,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 3; + res->mnem = armv7::ARMV7_VLD4; + + /* pcode: regs_n = 4 */ + res->fields[FIELD_regs_n] = 4; + res->fields_mask[FIELD_regs_n >> 6] |= 1LL << (FIELD_regs_n & 63); + /* pcode: if size == '11' then UNDEFINED */ + if((res->fields[FIELD_size]) == (0x3)) { + res->status |= STATUS_UNDEFINED; + } + /* pcode: inc = 0 */ + res->fields[FIELD_inc] = 0; + res->fields_mask[FIELD_inc >> 6] |= 1LL << (FIELD_inc & 63); + /* pcode: if type == '0000' then inc = 1 */ + if((res->fields[FIELD_type]) == (0x0)) { + res->fields[FIELD_inc] = 1; + res->fields_mask[FIELD_inc >> 6] |= 1LL << (FIELD_inc & 63); + } + /* pcode: if type == '0001' then inc = 2 */ + if((res->fields[FIELD_type]) == (0x1)) { + res->fields[FIELD_inc] = 2; + res->fields_mask[FIELD_inc >> 6] |= 1LL << (FIELD_inc & 63); + } + /* pcode: if align == 0 then alignment = 1 */ + if((res->fields[FIELD_align]) == (0)) { + res->fields[FIELD_alignment] = 1; + res->fields_mask[FIELD_alignment >> 6] |= 1LL << (FIELD_alignment & 63); + } + /* pcode: if align == 1 then alignment = 64 */ + if((res->fields[FIELD_align]) == (1)) { + res->fields[FIELD_alignment] = 64; + res->fields_mask[FIELD_alignment >> 6] |= 1LL << (FIELD_alignment & 63); + } + /* pcode: if align == 2 then alignment = 128 */ + if((res->fields[FIELD_align]) == (2)) { + res->fields[FIELD_alignment] = 128; + res->fields_mask[FIELD_alignment >> 6] |= 1LL << (FIELD_alignment & 63); + } + /* pcode: if align == 3 then alignment = 256 */ + if((res->fields[FIELD_align]) == (3)) { + res->fields[FIELD_alignment] = 256; + res->fields_mask[FIELD_alignment >> 6] |= 1LL << (FIELD_alignment & 63); + } + /* pcode: d = D:Vd */ + res->fields[FIELD_d] = (res->fields[FIELD_D]<<Vd_width)|(res->fields[FIELD_Vd]); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: d2 = d + inc */ + res->fields[FIELD_d2] = (res->fields[FIELD_d]) + (res->fields[FIELD_inc]); + res->fields_mask[FIELD_d2 >> 6] |= 1LL << (FIELD_d2 & 63); + /* pcode: d3 = d2 + inc */ + res->fields[FIELD_d3] = (res->fields[FIELD_d2]) + (res->fields[FIELD_inc]); + res->fields_mask[FIELD_d3 >> 6] |= 1LL << (FIELD_d3 & 63); + /* pcode: d4 = d3 + inc */ + res->fields[FIELD_d4] = (res->fields[FIELD_d3]) + (res->fields[FIELD_inc]); + res->fields_mask[FIELD_d4 >> 6] |= 1LL << (FIELD_d4 & 63); + /* pcode: wback = (Rm != 15) */ + res->fields[FIELD_wback] = ((res->fields[FIELD_Rm]) != (15)); + res->fields_mask[FIELD_wback >> 6] |= 1LL << (FIELD_wback & 63); + /* pcode: fmt_idx = 2 */ + res->fields[FIELD_fmt_idx] = 2; + res->fields_mask[FIELD_fmt_idx >> 6] |= 1LL << (FIELD_fmt_idx & 63); + /* pcode: if Rm == '1111' then fmt_idx = 0 */ + if((res->fields[FIELD_Rm]) == (0xF)) { + res->fields[FIELD_fmt_idx] = 0; + res->fields_mask[FIELD_fmt_idx >> 6] |= 1LL << (FIELD_fmt_idx & 63); + } + /* pcode: if Rm == '1101' then fmt_idx = 1 */ + if((res->fields[FIELD_Rm]) == (0xD)) { + res->fields[FIELD_fmt_idx] = 1; + res->fields_mask[FIELD_fmt_idx >> 6] |= 1LL << (FIELD_fmt_idx & 63); + } + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: B4BC345B +int vld4_single_4elem_1lane(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + res->group = INSN_GROUP_NEON; + /* Encoding T1 */ + /* pattern="1111,1001,1,D.1,10,Rn.4,Vd.4,size.2,11,index_align.4,Rm.4" width=32 stringency=14 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFFB00300)==0xF9A00300)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ADVSIMD)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_D] = (instr & 0x400000)>>22; + res->fields_mask[FIELD_D >> 6] |= 1LL << (FIELD_D & 63); + char D_width = 1; + res->fields[FIELD_Rn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Rn >> 6] |= 1LL << (FIELD_Rn & 63); + char Rn_width = 4; + res->fields[FIELD_Vd] = (instr & 0xF000)>>12; + res->fields_mask[FIELD_Vd >> 6] |= 1LL << (FIELD_Vd & 63); + char Vd_width = 4; + res->fields[FIELD_size] = (instr & 0xC00)>>10; + res->fields_mask[FIELD_size >> 6] |= 1LL << (FIELD_size & 63); + char size_width = 2; + res->fields[FIELD_index_align] = (instr & 0xF0)>>4; + res->fields_mask[FIELD_index_align >> 6] |= 1LL << (FIELD_index_align & 63); + char index_align_width = 4; + res->fields[FIELD_Rm] = instr & 0xF; + res->fields_mask[FIELD_Rm >> 6] |= 1LL << (FIELD_Rm & 63); + char Rm_width = 4; + + static const instruction_format instr_formats[] = + { + { /* VLD4<c>.<size> <registers_indexed>,[<Rn>,#<align>] */ + "vld4", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_NEON_SIZE, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REGISTERS_INDEXED,FIELD_registers_indexed,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_MEMORY_ONE_REG_ALIGNED,FIELD_Rn,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + { /* VLD4<c>.<size> <registers_indexed>,[<Rn>,#<align>]! */ + "vld4", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_NEON_SIZE, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REGISTERS_INDEXED,FIELD_registers_indexed,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_MEMORY_ONE_REG_ALIGNED,FIELD_Rn,FIELD_UNINIT,"","",WRITEBACK_YES}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + { /* VLD4<c>.<size> <registers_indexed>,[<Rn>,#<align>],<Rm> */ + "vld4", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_NEON_SIZE, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REGISTERS_INDEXED,FIELD_registers_indexed,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_MEMORY_ONE_REG_ALIGNED,FIELD_Rn,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rm,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 3; + res->mnem = armv7::ARMV7_VLD4; + + /* pcode: if size == '11' then UNDEFINED */ + if((res->fields[FIELD_size]) == (0x3)) { + res->status |= STATUS_UNDEFINED; + } + /* pcode: case size of */ + /* pcode: when '00' */ + if(res->fields[FIELD_size] == 0x0) { + /* pcode: ebytes = 1 */ + res->fields[FIELD_ebytes] = 1; + res->fields_mask[FIELD_ebytes >> 6] |= 1LL << (FIELD_ebytes & 63); + /* pcode: esize = 8 */ + res->fields[FIELD_esize] = 8; + res->fields_mask[FIELD_esize >> 6] |= 1LL << (FIELD_esize & 63); + /* pcode: index = UInt(index_align<3:1>) */ + res->fields[FIELD_index] = (((res->fields[FIELD_index_align] >> 1) & 0x7)); + res->fields_mask[FIELD_index >> 6] |= 1LL << (FIELD_index & 63); + /* pcode: inc = 1 */ + res->fields[FIELD_inc] = 1; + res->fields_mask[FIELD_inc >> 6] |= 1LL << (FIELD_inc & 63); + /* pcode: alignment = if index_align<0> == '0' then 1 else 32 */ + if(((res->fields[FIELD_index_align] & 1)) == (0x0)) { + res->fields[FIELD_alignment] = 1; + res->fields_mask[FIELD_alignment >> 6] |= 1LL << (FIELD_alignment & 63); + } + else { + res->fields[FIELD_alignment] = 32; + res->fields_mask[FIELD_alignment >> 6] |= 1LL << (FIELD_alignment & 63); + } + } + /* pcode: when '01' */ + else + if(res->fields[FIELD_size] == 0x1) { + /* pcode: ebytes = 2 */ + res->fields[FIELD_ebytes] = 2; + res->fields_mask[FIELD_ebytes >> 6] |= 1LL << (FIELD_ebytes & 63); + /* pcode: esize = 16 */ + res->fields[FIELD_esize] = 16; + res->fields_mask[FIELD_esize >> 6] |= 1LL << (FIELD_esize & 63); + /* pcode: index = UInt(index_align<3:2>) */ + res->fields[FIELD_index] = (((res->fields[FIELD_index_align] >> 2) & 0x3)); + res->fields_mask[FIELD_index >> 6] |= 1LL << (FIELD_index & 63); + /* pcode: inc = if index_align<1> == '0' then 1 else 2 */ + if((((res->fields[FIELD_index_align] >> 1) & 1)) == (0x0)) { + res->fields[FIELD_inc] = 1; + res->fields_mask[FIELD_inc >> 6] |= 1LL << (FIELD_inc & 63); + } + else { + res->fields[FIELD_inc] = 2; + res->fields_mask[FIELD_inc >> 6] |= 1LL << (FIELD_inc & 63); + } + /* pcode: alignment = if index_align<0> == '0' then 1 else 64 */ + if(((res->fields[FIELD_index_align] & 1)) == (0x0)) { + res->fields[FIELD_alignment] = 1; + res->fields_mask[FIELD_alignment >> 6] |= 1LL << (FIELD_alignment & 63); + } + else { + res->fields[FIELD_alignment] = 64; + res->fields_mask[FIELD_alignment >> 6] |= 1LL << (FIELD_alignment & 63); + } + } + /* pcode: when '10' */ + else + if(res->fields[FIELD_size] == 0x2) { + /* pcode: if index_align<1:0> == '11' then UNDEFINED */ + if(((res->fields[FIELD_index_align] & 0x3)) == (0x3)) { + res->status |= STATUS_UNDEFINED; + } + /* pcode: ebytes = 4 */ + res->fields[FIELD_ebytes] = 4; + res->fields_mask[FIELD_ebytes >> 6] |= 1LL << (FIELD_ebytes & 63); + /* pcode: esize = 32 */ + res->fields[FIELD_esize] = 32; + res->fields_mask[FIELD_esize >> 6] |= 1LL << (FIELD_esize & 63); + /* pcode: index = UInt(index_align<3>) */ + res->fields[FIELD_index] = (((res->fields[FIELD_index_align] >> 3) & 1)); + res->fields_mask[FIELD_index >> 6] |= 1LL << (FIELD_index & 63); + /* pcode: inc = if index_align<2> == '0' then 1 else 2 */ + if((((res->fields[FIELD_index_align] >> 2) & 1)) == (0x0)) { + res->fields[FIELD_inc] = 1; + res->fields_mask[FIELD_inc >> 6] |= 1LL << (FIELD_inc & 63); + } + else { + res->fields[FIELD_inc] = 2; + res->fields_mask[FIELD_inc >> 6] |= 1LL << (FIELD_inc & 63); + } + /* pcode: alignment = if index_align<1:0> == '00' then 1 else 64 << UInt(index_align<1:0> - 1) */ + if(((res->fields[FIELD_index_align] & 0x3)) == (0x0)) { + res->fields[FIELD_alignment] = 1; + res->fields_mask[FIELD_alignment >> 6] |= 1LL << (FIELD_alignment & 63); + } + else { + res->fields[FIELD_alignment] = (64) << ((((res->fields[FIELD_index_align] & 0x3)) - (1))); + res->fields_mask[FIELD_alignment >> 6] |= 1LL << (FIELD_alignment & 63); + } + } + /* pcode: d = UInt(D:Vd) */ + res->fields[FIELD_d] = ((res->fields[FIELD_D]<<Vd_width)|(res->fields[FIELD_Vd])); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: d2 = d + inc */ + res->fields[FIELD_d2] = (res->fields[FIELD_d]) + (res->fields[FIELD_inc]); + res->fields_mask[FIELD_d2 >> 6] |= 1LL << (FIELD_d2 & 63); + /* pcode: d3 = d2 + inc */ + res->fields[FIELD_d3] = (res->fields[FIELD_d2]) + (res->fields[FIELD_inc]); + res->fields_mask[FIELD_d3 >> 6] |= 1LL << (FIELD_d3 & 63); + /* pcode: d4 = d3 + inc */ + res->fields[FIELD_d4] = (res->fields[FIELD_d3]) + (res->fields[FIELD_inc]); + res->fields_mask[FIELD_d4 >> 6] |= 1LL << (FIELD_d4 & 63); + /* pcode: n = UInt(Rn) */ + res->fields[FIELD_n] = (res->fields[FIELD_Rn]); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: m = UInt(Rm) */ + res->fields[FIELD_m] = (res->fields[FIELD_Rm]); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + /* pcode: wback = (m != 15) */ + res->fields[FIELD_wback] = ((res->fields[FIELD_m]) != (15)); + res->fields_mask[FIELD_wback >> 6] |= 1LL << (FIELD_wback & 63); + /* pcode: register_index = (m != 15 && m != 13) */ + res->fields[FIELD_register_index] = (((res->fields[FIELD_m]) != (15)) && ((res->fields[FIELD_m]) != (13))); + res->fields_mask[FIELD_register_index >> 6] |= 1LL << (FIELD_register_index & 63); + /* pcode: if d4 > 31 then UNPREDICTABLE */ + if((res->fields[FIELD_d4]) > (31)) { + res->flags |= FLAG_UNPREDICTABLE; + } + /* pcode: length = 4 */ + res->fields[FIELD_length] = 4; + res->fields_mask[FIELD_length >> 6] |= 1LL << (FIELD_length & 63); + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: 371FD984 +int vld4_single_4elem_nlanes(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + res->group = INSN_GROUP_NEON; + /* Encoding T1 */ + /* pattern="1111,1001,1,D.1,10,Rn.4,Vd.4,11,11,size.2,T.1,a.1,Rm.4" width=32 stringency=18 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFFB00F00)==0xF9A00F00)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ADVSIMD)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_D] = (instr & 0x400000)>>22; + res->fields_mask[FIELD_D >> 6] |= 1LL << (FIELD_D & 63); + char D_width = 1; + res->fields[FIELD_Rn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Rn >> 6] |= 1LL << (FIELD_Rn & 63); + char Rn_width = 4; + res->fields[FIELD_Vd] = (instr & 0xF000)>>12; + res->fields_mask[FIELD_Vd >> 6] |= 1LL << (FIELD_Vd & 63); + char Vd_width = 4; + res->fields[FIELD_size] = (instr & 0xC0)>>6; + res->fields_mask[FIELD_size >> 6] |= 1LL << (FIELD_size & 63); + char size_width = 2; + res->fields[FIELD_T] = (instr & 0x20)>>5; + res->fields_mask[FIELD_T >> 6] |= 1LL << (FIELD_T & 63); + char T_width = 1; + res->fields[FIELD_a] = (instr & 0x10)>>4; + res->fields_mask[FIELD_a >> 6] |= 1LL << (FIELD_a & 63); + char a_width = 1; + res->fields[FIELD_Rm] = instr & 0xF; + res->fields_mask[FIELD_Rm >> 6] |= 1LL << (FIELD_Rm & 63); + char Rm_width = 4; + + static const instruction_format instr_formats[] = + { + { /* VLD4<c>.<size> <registers[]>,[<Rn>,#<align>] */ + "vld4", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_NEON_SIZE, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REGISTERS,FIELD_registers,FIELD_UNINIT,"","[]",WRITEBACK_NO}, + {OPERAND_FORMAT_MEMORY_ONE_REG_ALIGNED,FIELD_Rn,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + { /* VLD4<c>.<size> <registers[]>,[<Rn>,#<align>]! */ + "vld4", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_NEON_SIZE, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REGISTERS,FIELD_registers,FIELD_UNINIT,"","[]",WRITEBACK_NO}, + {OPERAND_FORMAT_MEMORY_ONE_REG_ALIGNED,FIELD_Rn,FIELD_UNINIT,"","",WRITEBACK_YES}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + { /* VLD4<c>.<size> <registers[]>,[<Rn>,#<align>],<Rm> */ + "vld4", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_NEON_SIZE, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REGISTERS,FIELD_registers,FIELD_UNINIT,"","[]",WRITEBACK_NO}, + {OPERAND_FORMAT_MEMORY_ONE_REG_ALIGNED,FIELD_Rn,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rm,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 3; + res->mnem = armv7::ARMV7_VLD4; + + /* pcode: if size == '11' && a == '0' then UNDEFINED */ + if(((res->fields[FIELD_size]) == (0x3)) && ((res->fields[FIELD_a]) == (0x0))) { + res->status |= STATUS_UNDEFINED; + } + /* pcode: ebytes = if size == '11' then 4 else 1 << UInt(size) */ + if((res->fields[FIELD_size]) == (0x3)) { + res->fields[FIELD_ebytes] = 4; + res->fields_mask[FIELD_ebytes >> 6] |= 1LL << (FIELD_ebytes & 63); + } + else { + res->fields[FIELD_ebytes] = (1) << ((res->fields[FIELD_size])); + res->fields_mask[FIELD_ebytes >> 6] |= 1LL << (FIELD_ebytes & 63); + } + /* pcode: elements = if size == '11' then 2 else 8 / ebytes */ + if((res->fields[FIELD_size]) == (0x3)) { + res->fields[FIELD_elements] = 2; + res->fields_mask[FIELD_elements >> 6] |= 1LL << (FIELD_elements & 63); + } + else { + res->fields[FIELD_elements] = ((res->fields[FIELD_ebytes]) ? ((8) / (res->fields[FIELD_ebytes])) : 0); + res->fields_mask[FIELD_elements >> 6] |= 1LL << (FIELD_elements & 63); + } + /* pcode: alignment = 1 */ + res->fields[FIELD_alignment] = 1; + res->fields_mask[FIELD_alignment >> 6] |= 1LL << (FIELD_alignment & 63); + /* pcode: if size == 3 then alignment = 128 */ + if((res->fields[FIELD_size]) == (3)) { + res->fields[FIELD_alignment] = 128; + res->fields_mask[FIELD_alignment >> 6] |= 1LL << (FIELD_alignment & 63); + } + /* pcode: if size == 2 && a == 1 then alignment = 64 */ + if(((res->fields[FIELD_size]) == (2)) && ((res->fields[FIELD_a]) == (1))) { + res->fields[FIELD_alignment] = 64; + res->fields_mask[FIELD_alignment >> 6] |= 1LL << (FIELD_alignment & 63); + } + /* pcode: if size < 2 && a == 1 then alignment = 32*ebytes */ + if(((res->fields[FIELD_size]) < (2)) && ((res->fields[FIELD_a]) == (1))) { + res->fields[FIELD_alignment] = (32) * (res->fields[FIELD_ebytes]); + res->fields_mask[FIELD_alignment >> 6] |= 1LL << (FIELD_alignment & 63); + } + /* pcode: inc = if T == '0' then 1 else 2 */ + if((res->fields[FIELD_T]) == (0x0)) { + res->fields[FIELD_inc] = 1; + res->fields_mask[FIELD_inc >> 6] |= 1LL << (FIELD_inc & 63); + } + else { + res->fields[FIELD_inc] = 2; + res->fields_mask[FIELD_inc >> 6] |= 1LL << (FIELD_inc & 63); + } + /* pcode: d = UInt(D:Vd) */ + res->fields[FIELD_d] = ((res->fields[FIELD_D]<<Vd_width)|(res->fields[FIELD_Vd])); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: d2 = d + inc */ + res->fields[FIELD_d2] = (res->fields[FIELD_d]) + (res->fields[FIELD_inc]); + res->fields_mask[FIELD_d2 >> 6] |= 1LL << (FIELD_d2 & 63); + /* pcode: d3 = d2 + inc */ + res->fields[FIELD_d3] = (res->fields[FIELD_d2]) + (res->fields[FIELD_inc]); + res->fields_mask[FIELD_d3 >> 6] |= 1LL << (FIELD_d3 & 63); + /* pcode: d4 = d3 + inc */ + res->fields[FIELD_d4] = (res->fields[FIELD_d3]) + (res->fields[FIELD_inc]); + res->fields_mask[FIELD_d4 >> 6] |= 1LL << (FIELD_d4 & 63); + /* pcode: n = UInt(Rn) */ + res->fields[FIELD_n] = (res->fields[FIELD_Rn]); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: m = UInt(Rm) */ + res->fields[FIELD_m] = (res->fields[FIELD_Rm]); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + /* pcode: wback = (m != 15) */ + res->fields[FIELD_wback] = ((res->fields[FIELD_m]) != (15)); + res->fields_mask[FIELD_wback >> 6] |= 1LL << (FIELD_wback & 63); + /* pcode: register_index = (m != 15 && m != 13) */ + res->fields[FIELD_register_index] = (((res->fields[FIELD_m]) != (15)) && ((res->fields[FIELD_m]) != (13))); + res->fields_mask[FIELD_register_index >> 6] |= 1LL << (FIELD_register_index & 63); + /* pcode: if size == 3 then size = 2 */ + if((res->fields[FIELD_size]) == (3)) { + res->fields[FIELD_size] = 2; + res->fields_mask[FIELD_size >> 6] |= 1LL << (FIELD_size & 63); + } + /* pcode: if d4 > 31 then UNPREDICTABLE */ + if((res->fields[FIELD_d4]) > (31)) { + res->flags |= FLAG_UNPREDICTABLE; + } + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: 9373B587 +int vldm(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + res->group = INSN_GROUP_NEON; + /* Encoding T2 */ + /* pattern="1110,110,P.1,U.1,D.1,W.1,1,Rn.4,Vd.4,1010,imm8.8" width=32 stringency=16 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFE100F00)==0xEC100A00)) { + res->instrSize = 32; + if(!(req->arch & ARCH_VFPv2) && !(req->arch & ARCH_VFPv3)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_P] = (instr & 0x1000000)>>24; + res->fields_mask[FIELD_P >> 6] |= 1LL << (FIELD_P & 63); + char P_width = 1; + res->fields[FIELD_U] = (instr & 0x800000)>>23; + res->fields_mask[FIELD_U >> 6] |= 1LL << (FIELD_U & 63); + char U_width = 1; + res->fields[FIELD_D] = (instr & 0x400000)>>22; + res->fields_mask[FIELD_D >> 6] |= 1LL << (FIELD_D & 63); + char D_width = 1; + res->fields[FIELD_W] = (instr & 0x200000)>>21; + res->fields_mask[FIELD_W >> 6] |= 1LL << (FIELD_W & 63); + char W_width = 1; + res->fields[FIELD_Rn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Rn >> 6] |= 1LL << (FIELD_Rn & 63); + char Rn_width = 4; + res->fields[FIELD_Vd] = (instr & 0xF000)>>12; + res->fields_mask[FIELD_Vd >> 6] |= 1LL << (FIELD_Vd & 63); + char Vd_width = 4; + res->fields[FIELD_imm8] = instr & 0xFF; + res->fields_mask[FIELD_imm8 >> 6] |= 1LL << (FIELD_imm8 & 63); + char imm8_width = 8; + + static const instruction_format instr_formats[] = + { + { /* VLDMDB<c> <Rn>{!},<registers> */ + "vldmdb", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rn,FIELD_UNINIT,"","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REGISTERS,FIELD_registers,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + { /* VLDMIA<c> <Rn>{!},<registers> */ + "vldmia", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rn,FIELD_UNINIT,"","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REGISTERS,FIELD_registers,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 2; + res->mnem = armv7::ARMV7_VLDMDB; + + /* pcode: if (P == '0' && U == '0' && W == '0') then SEE xfer_64_core_ext_regs */ + if(((((res->fields[FIELD_P]) == (0x0)) && ((res->fields[FIELD_U]) == (0x0))) && ((res->fields[FIELD_W]) == (0x0)))) { + + return xfer_64_core_ext_regs(req, res); + } + /* pcode: if (P == '0' && U == '1' && W == '1' && Rn == '1101') then SEE vpop */ + if((((((res->fields[FIELD_P]) == (0x0)) && ((res->fields[FIELD_U]) == (0x1))) && ((res->fields[FIELD_W]) == (0x1))) && ((res->fields[FIELD_Rn]) == (0xD)))) { + + return vpop(req, res); + } + /* pcode: if (P == '1' && W == '0') then SEE vldr */ + if((((res->fields[FIELD_P]) == (0x1)) && ((res->fields[FIELD_W]) == (0x0)))) { + + return vldr(req, res); + } + /* pcode: if (P == U && W == '1') then UNDEFINED */ + if((((res->fields[FIELD_P]) == (res->fields[FIELD_U])) && ((res->fields[FIELD_W]) == (0x1)))) { + res->status |= STATUS_UNDEFINED; + } + /* pcode: single_regs = TRUE */ + res->fields[FIELD_single_regs] = 1; + res->fields_mask[FIELD_single_regs >> 6] |= 1LL << (FIELD_single_regs & 63); + /* pcode: add = (U == '1') */ + res->fields[FIELD_add] = ((res->fields[FIELD_U]) == (0x1)); + res->fields_mask[FIELD_add >> 6] |= 1LL << (FIELD_add & 63); + /* pcode: wback = (W == '1') */ + res->fields[FIELD_wback] = ((res->fields[FIELD_W]) == (0x1)); + res->fields_mask[FIELD_wback >> 6] |= 1LL << (FIELD_wback & 63); + /* pcode: d = UInt(Vd:D) */ + res->fields[FIELD_d] = ((res->fields[FIELD_Vd]<<D_width)|(res->fields[FIELD_D])); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: n = UInt(Rn) */ + res->fields[FIELD_n] = (res->fields[FIELD_Rn]); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: imm32 = ZeroExtend(imm8:'00', 32) */ + res->fields[FIELD_imm32] = (res->fields[FIELD_imm8]<<2)|(0x0); + res->fields_mask[FIELD_imm32 >> 6] |= 1LL << (FIELD_imm32 & 63); + /* pcode: regs = UInt(imm8) */ + res->fields[FIELD_regs] = (res->fields[FIELD_imm8]); + res->fields_mask[FIELD_regs >> 6] |= 1LL << (FIELD_regs & 63); + /* pcode: if (n == 15 && wback) then UNPREDICTABLE */ + if((((res->fields[FIELD_n]) == (15)) && (res->fields[FIELD_wback]))) { + res->flags |= FLAG_UNPREDICTABLE; + } + /* pcode: if (regs == 0 || (d+regs) > 32) then UNPREDICTABLE */ + if((((res->fields[FIELD_regs]) == (0)) || ((((res->fields[FIELD_d]) + (res->fields[FIELD_regs]))) > (32)))) { + res->flags |= FLAG_UNPREDICTABLE; + } + /* pcode: fmt_idx = U */ + res->fields[FIELD_fmt_idx] = res->fields[FIELD_U]; + res->fields_mask[FIELD_fmt_idx >> 6] |= 1LL << (FIELD_fmt_idx & 63); + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* Encoding T1 */ + /* pattern="1110,110,P.1,U.1,D.1,W.1,1,Rn.4,Vd.4,1011,imm8.8" width=32 stringency=16 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFE100F00)==0xEC100B00)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ADVSIMD)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_P] = (instr & 0x1000000)>>24; + res->fields_mask[FIELD_P >> 6] |= 1LL << (FIELD_P & 63); + char P_width = 1; + res->fields[FIELD_U] = (instr & 0x800000)>>23; + res->fields_mask[FIELD_U >> 6] |= 1LL << (FIELD_U & 63); + char U_width = 1; + res->fields[FIELD_D] = (instr & 0x400000)>>22; + res->fields_mask[FIELD_D >> 6] |= 1LL << (FIELD_D & 63); + char D_width = 1; + res->fields[FIELD_W] = (instr & 0x200000)>>21; + res->fields_mask[FIELD_W >> 6] |= 1LL << (FIELD_W & 63); + char W_width = 1; + res->fields[FIELD_Rn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Rn >> 6] |= 1LL << (FIELD_Rn & 63); + char Rn_width = 4; + res->fields[FIELD_Vd] = (instr & 0xF000)>>12; + res->fields_mask[FIELD_Vd >> 6] |= 1LL << (FIELD_Vd & 63); + char Vd_width = 4; + res->fields[FIELD_imm8] = instr & 0xFF; + res->fields_mask[FIELD_imm8 >> 6] |= 1LL << (FIELD_imm8 & 63); + char imm8_width = 8; + + static const instruction_format instr_formats[] = + { + { /* VLDMDB<c> <Rn>{!},<registers> */ + "vldmdb", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rn,FIELD_UNINIT,"","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REGISTERS,FIELD_registers,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + { /* VLDMIA<c> <Rn>{!},<registers> */ + "vldmia", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rn,FIELD_UNINIT,"","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REGISTERS,FIELD_registers,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 2; + res->mnem = armv7::ARMV7_VLDMDB; + + /* pcode: if (P == '0' && U == '0' && W == '0') then SEE xfer_64_core_ext_regs */ + if(((((res->fields[FIELD_P]) == (0x0)) && ((res->fields[FIELD_U]) == (0x0))) && ((res->fields[FIELD_W]) == (0x0)))) { + + return xfer_64_core_ext_regs(req, res); + } + /* pcode: if (P == '0' && U == '1' && W == '1' && Rn == '1101') then SEE vpop */ + if((((((res->fields[FIELD_P]) == (0x0)) && ((res->fields[FIELD_U]) == (0x1))) && ((res->fields[FIELD_W]) == (0x1))) && ((res->fields[FIELD_Rn]) == (0xD)))) { + + return vpop(req, res); + } + /* pcode: if (P == '1' && W == '0') then SEE vldr */ + if((((res->fields[FIELD_P]) == (0x1)) && ((res->fields[FIELD_W]) == (0x0)))) { + + return vldr(req, res); + } + /* pcode: if (imm8<0> == '1') then UNDEFINED */ + if((((res->fields[FIELD_imm8] & 1)) == (0x1))) { + res->status |= STATUS_UNDEFINED; + } + /* pcode: if (P == U && W == '1') then UNDEFINED */ + if((((res->fields[FIELD_P]) == (res->fields[FIELD_U])) && ((res->fields[FIELD_W]) == (0x1)))) { + res->status |= STATUS_UNDEFINED; + } + /* pcode: single_regs = FALSE */ + res->fields[FIELD_single_regs] = 0; + res->fields_mask[FIELD_single_regs >> 6] |= 1LL << (FIELD_single_regs & 63); + /* pcode: add = (U == '1') */ + res->fields[FIELD_add] = ((res->fields[FIELD_U]) == (0x1)); + res->fields_mask[FIELD_add >> 6] |= 1LL << (FIELD_add & 63); + /* pcode: wback = (W == '1') */ + res->fields[FIELD_wback] = ((res->fields[FIELD_W]) == (0x1)); + res->fields_mask[FIELD_wback >> 6] |= 1LL << (FIELD_wback & 63); + /* pcode: d = UInt(D:Vd) */ + res->fields[FIELD_d] = ((res->fields[FIELD_D]<<Vd_width)|(res->fields[FIELD_Vd])); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: n = UInt(Rn) */ + res->fields[FIELD_n] = (res->fields[FIELD_Rn]); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: imm32 = ZeroExtend(imm8:'00', 32) */ + res->fields[FIELD_imm32] = (res->fields[FIELD_imm8]<<2)|(0x0); + res->fields_mask[FIELD_imm32 >> 6] |= 1LL << (FIELD_imm32 & 63); + /* pcode: regs = UInt(imm8) DIV 2 */ + res->fields[FIELD_regs] = ((2) ? (((res->fields[FIELD_imm8])) / (2)) : 0); + res->fields_mask[FIELD_regs >> 6] |= 1LL << (FIELD_regs & 63); + /* pcode: if n == 15 then UNPREDICTABLE */ + if((res->fields[FIELD_n]) == (15)) { + res->flags |= FLAG_UNPREDICTABLE; + } + /* pcode: if (regs == 0 || regs > 16 || (d+regs) > 32) then UNPREDICTABLE */ + if(((((res->fields[FIELD_regs]) == (0)) || ((res->fields[FIELD_regs]) > (16))) || ((((res->fields[FIELD_d]) + (res->fields[FIELD_regs]))) > (32)))) { + res->flags |= FLAG_UNPREDICTABLE; + } + /* pcode: if (d+regs) > 16 then UNPREDICTABLE */ + if((((res->fields[FIELD_d]) + (res->fields[FIELD_regs]))) > (16)) { + res->flags |= FLAG_UNPREDICTABLE; + } + /* pcode: fmt_idx = U */ + res->fields[FIELD_fmt_idx] = res->fields[FIELD_U]; + res->fields_mask[FIELD_fmt_idx >> 6] |= 1LL << (FIELD_fmt_idx & 63); + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: 2C1446E0 +int vldr(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + res->group = INSN_GROUP_NEON; + /* Encoding T2 */ + /* pattern="1110,1101,U.1,D.1,0,1,Rn.4,Vd.4,1010,imm8.8" width=32 stringency=16 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFF300F00)==0xED100A00)) { + res->instrSize = 32; + if(!(req->arch & ARCH_VFPv2) && !(req->arch & ARCH_VFPv3)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_U] = (instr & 0x800000)>>23; + res->fields_mask[FIELD_U >> 6] |= 1LL << (FIELD_U & 63); + char U_width = 1; + res->fields[FIELD_D] = (instr & 0x400000)>>22; + res->fields_mask[FIELD_D >> 6] |= 1LL << (FIELD_D & 63); + char D_width = 1; + res->fields[FIELD_Rn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Rn >> 6] |= 1LL << (FIELD_Rn & 63); + char Rn_width = 4; + res->fields[FIELD_Vd] = (instr & 0xF000)>>12; + res->fields_mask[FIELD_Vd >> 6] |= 1LL << (FIELD_Vd & 63); + char Vd_width = 4; + res->fields[FIELD_imm8] = instr & 0xFF; + res->fields_mask[FIELD_imm8 >> 6] |= 1LL << (FIELD_imm8 & 63); + char imm8_width = 8; + + static const instruction_format instr_formats[] = + { + { /* VLDR<c> <Sd>,[<Rn>{,#<+/-><imm>}] */ + "vldr", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"s","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_MEMORY_ONE_REG_OPTIONAL_ADD_IMM,FIELD_Rn,FIELD_imm,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + { /* VLDR<c> <Sd>,<label> */ + "vldr", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"s","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_LABEL,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 2; + res->mnem = armv7::ARMV7_VLDR; + + /* pcode: add = (U == '1') */ + res->fields[FIELD_add] = ((res->fields[FIELD_U]) == (0x1)); + res->fields_mask[FIELD_add >> 6] |= 1LL << (FIELD_add & 63); + /* pcode: imm32 = ZeroExtend(imm8:'00', 32) */ + res->fields[FIELD_imm32] = (res->fields[FIELD_imm8]<<2)|(0x0); + res->fields_mask[FIELD_imm32 >> 6] |= 1LL << (FIELD_imm32 & 63); + /* pcode: d = UInt(Vd:D) */ + res->fields[FIELD_d] = ((res->fields[FIELD_Vd]<<D_width)|(res->fields[FIELD_D])); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: n = UInt(Rn) */ + res->fields[FIELD_n] = (res->fields[FIELD_Rn]); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: imm = imm32 */ + res->fields[FIELD_imm] = res->fields[FIELD_imm32]; + res->fields_mask[FIELD_imm >> 6] |= 1LL << (FIELD_imm & 63); + /* pcode: fmt_idx = 0 */ + res->fields[FIELD_fmt_idx] = 0; + res->fields_mask[FIELD_fmt_idx >> 6] |= 1LL << (FIELD_fmt_idx & 63); + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* Encoding T1 */ + /* pattern="1110,1101,U.1,D.1,0,1,Rn.4,Vd.4,1011,imm8.8" width=32 stringency=16 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFF300F00)==0xED100B00)) { + res->instrSize = 32; + if(!(req->arch & ARCH_VFPv2) && !(req->arch & ARCH_VFPv3)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_U] = (instr & 0x800000)>>23; + res->fields_mask[FIELD_U >> 6] |= 1LL << (FIELD_U & 63); + char U_width = 1; + res->fields[FIELD_D] = (instr & 0x400000)>>22; + res->fields_mask[FIELD_D >> 6] |= 1LL << (FIELD_D & 63); + char D_width = 1; + res->fields[FIELD_Rn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Rn >> 6] |= 1LL << (FIELD_Rn & 63); + char Rn_width = 4; + res->fields[FIELD_Vd] = (instr & 0xF000)>>12; + res->fields_mask[FIELD_Vd >> 6] |= 1LL << (FIELD_Vd & 63); + char Vd_width = 4; + res->fields[FIELD_imm8] = instr & 0xFF; + res->fields_mask[FIELD_imm8 >> 6] |= 1LL << (FIELD_imm8 & 63); + char imm8_width = 8; + + static const instruction_format instr_formats[] = + { + { /* VLDR<c> <Dd>,[<Rn>{,#<+/-><imm>}] */ + "vldr", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_MEMORY_ONE_REG_OPTIONAL_ADD_IMM,FIELD_Rn,FIELD_imm,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + { /* VLDR<c> <Dd>,<label> */ + "vldr", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_LABEL,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 2; + res->mnem = armv7::ARMV7_VLDR; + + /* pcode: add = (U == '1') */ + res->fields[FIELD_add] = ((res->fields[FIELD_U]) == (0x1)); + res->fields_mask[FIELD_add >> 6] |= 1LL << (FIELD_add & 63); + /* pcode: imm32 = ZeroExtend(imm8:'00', 32) */ + res->fields[FIELD_imm32] = (res->fields[FIELD_imm8]<<2)|(0x0); + res->fields_mask[FIELD_imm32 >> 6] |= 1LL << (FIELD_imm32 & 63); + /* pcode: d = UInt(D:Vd) */ + res->fields[FIELD_d] = ((res->fields[FIELD_D]<<Vd_width)|(res->fields[FIELD_Vd])); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: n = UInt(Rn) */ + res->fields[FIELD_n] = (res->fields[FIELD_Rn]); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: imm = imm32 */ + res->fields[FIELD_imm] = res->fields[FIELD_imm32]; + res->fields_mask[FIELD_imm >> 6] |= 1LL << (FIELD_imm & 63); + /* pcode: fmt_idx = 0 */ + res->fields[FIELD_fmt_idx] = 0; + res->fields_mask[FIELD_fmt_idx >> 6] |= 1LL << (FIELD_fmt_idx & 63); + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: 8B81DE62 +int vmax_vmin_float(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + res->group = INSN_GROUP_NEON; + /* Encoding T1 */ + /* pattern="111x,xx1x,0,D.1,0,sz.1,Vn.4,Vd.4,1111,N.1,Q.1,M.1,0,Vm.4" width=32 stringency=16 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xE2A00F10)==0xE2000F00)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ADVSIMD)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_D] = (instr & 0x400000)>>22; + res->fields_mask[FIELD_D >> 6] |= 1LL << (FIELD_D & 63); + char D_width = 1; + res->fields[FIELD_sz] = (instr & 0x100000)>>20; + res->fields_mask[FIELD_sz >> 6] |= 1LL << (FIELD_sz & 63); + char sz_width = 1; + res->fields[FIELD_Vn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Vn >> 6] |= 1LL << (FIELD_Vn & 63); + char Vn_width = 4; + res->fields[FIELD_Vd] = (instr & 0xF000)>>12; + res->fields_mask[FIELD_Vd >> 6] |= 1LL << (FIELD_Vd & 63); + char Vd_width = 4; + res->fields[FIELD_N] = (instr & 0x80)>>7; + res->fields_mask[FIELD_N >> 6] |= 1LL << (FIELD_N & 63); + char N_width = 1; + res->fields[FIELD_Q] = (instr & 0x40)>>6; + res->fields_mask[FIELD_Q >> 6] |= 1LL << (FIELD_Q & 63); + char Q_width = 1; + res->fields[FIELD_M] = (instr & 0x20)>>5; + res->fields_mask[FIELD_M >> 6] |= 1LL << (FIELD_M & 63); + char M_width = 1; + res->fields[FIELD_Vm] = instr & 0xF; + res->fields_mask[FIELD_Vm >> 6] |= 1LL << (FIELD_Vm & 63); + char Vm_width = 4; + + static const instruction_format instr_formats[] = + { + { /* VMAX<c>.F32 <Dd>,<Dn>,<Dm> */ + "vmax.f32", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_F32, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_n,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_m,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + { /* VMAX<c>.F32 <Qd>,<Qn>,<Qm> */ + "vmax.f32", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_F32, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"q","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_n,FIELD_UNINIT,"q","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_m,FIELD_UNINIT,"q","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 2; + res->mnem = armv7::ARMV7_VMAX; + + /* pcode: if Q == '1' && (Vd<0> == '1' || Vn<0> == '1' || Vm<0> == '1') then UNDEFINED */ + if(((res->fields[FIELD_Q]) == (0x1)) && ((((((res->fields[FIELD_Vd] & 1)) == (0x1)) || (((res->fields[FIELD_Vn] & 1)) == (0x1))) || (((res->fields[FIELD_Vm] & 1)) == (0x1))))) { + res->status |= STATUS_UNDEFINED; + } + /* pcode: if sz == '1' then UNDEFINED */ + if((res->fields[FIELD_sz]) == (0x1)) { + res->status |= STATUS_UNDEFINED; + } + /* pcode: esize = 32 */ + res->fields[FIELD_esize] = 32; + res->fields_mask[FIELD_esize >> 6] |= 1LL << (FIELD_esize & 63); + /* pcode: elements = 2 */ + res->fields[FIELD_elements] = 2; + res->fields_mask[FIELD_elements >> 6] |= 1LL << (FIELD_elements & 63); + /* pcode: d = UInt(D:Vd) */ + res->fields[FIELD_d] = ((res->fields[FIELD_D]<<Vd_width)|(res->fields[FIELD_Vd])); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: n = UInt(N:Vn) */ + res->fields[FIELD_n] = ((res->fields[FIELD_N]<<Vn_width)|(res->fields[FIELD_Vn])); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: m = UInt(M:Vm) */ + res->fields[FIELD_m] = ((res->fields[FIELD_M]<<Vm_width)|(res->fields[FIELD_Vm])); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + /* pcode: regs = if Q == '0' then 1 else 2 */ + if((res->fields[FIELD_Q]) == (0x0)) { + res->fields[FIELD_regs] = 1; + res->fields_mask[FIELD_regs >> 6] |= 1LL << (FIELD_regs & 63); + } + else { + res->fields[FIELD_regs] = 2; + res->fields_mask[FIELD_regs >> 6] |= 1LL << (FIELD_regs & 63); + } + /* pcode: fmt_idx = (Q == '1') */ + res->fields[FIELD_fmt_idx] = ((res->fields[FIELD_Q]) == (0x1)); + res->fields_mask[FIELD_fmt_idx >> 6] |= 1LL << (FIELD_fmt_idx & 63); + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* Encoding T1 */ + /* pattern="111x,xx1x,0,D.1,1,sz.1,Vn.4,Vd.4,1111,N.1,Q.1,M.1,0,Vm.4" width=32 stringency=16 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xE2A00F10)==0xE2200F00)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ADVSIMD)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_D] = (instr & 0x400000)>>22; + res->fields_mask[FIELD_D >> 6] |= 1LL << (FIELD_D & 63); + char D_width = 1; + res->fields[FIELD_sz] = (instr & 0x100000)>>20; + res->fields_mask[FIELD_sz >> 6] |= 1LL << (FIELD_sz & 63); + char sz_width = 1; + res->fields[FIELD_Vn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Vn >> 6] |= 1LL << (FIELD_Vn & 63); + char Vn_width = 4; + res->fields[FIELD_Vd] = (instr & 0xF000)>>12; + res->fields_mask[FIELD_Vd >> 6] |= 1LL << (FIELD_Vd & 63); + char Vd_width = 4; + res->fields[FIELD_N] = (instr & 0x80)>>7; + res->fields_mask[FIELD_N >> 6] |= 1LL << (FIELD_N & 63); + char N_width = 1; + res->fields[FIELD_Q] = (instr & 0x40)>>6; + res->fields_mask[FIELD_Q >> 6] |= 1LL << (FIELD_Q & 63); + char Q_width = 1; + res->fields[FIELD_M] = (instr & 0x20)>>5; + res->fields_mask[FIELD_M >> 6] |= 1LL << (FIELD_M & 63); + char M_width = 1; + res->fields[FIELD_Vm] = instr & 0xF; + res->fields_mask[FIELD_Vm >> 6] |= 1LL << (FIELD_Vm & 63); + char Vm_width = 4; + + static const instruction_format instr_formats[] = + { + { /* VMIN<c>.F32 <Dd>,<Dn>,<Dm> */ + "vmin.f32", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_F32, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_n,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_m,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + { /* VMIN<c>.F32 <Qd>,<Qn>,<Qm> */ + "vmin.f32", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_F32, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"q","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_n,FIELD_UNINIT,"q","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_m,FIELD_UNINIT,"q","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 2; + res->mnem = armv7::ARMV7_VMIN; + + /* pcode: if Q == '1' && (Vd<0> == '1' || Vn<0> == '1' || Vm<0> == '1') then UNDEFINED */ + if(((res->fields[FIELD_Q]) == (0x1)) && ((((((res->fields[FIELD_Vd] & 1)) == (0x1)) || (((res->fields[FIELD_Vn] & 1)) == (0x1))) || (((res->fields[FIELD_Vm] & 1)) == (0x1))))) { + res->status |= STATUS_UNDEFINED; + } + /* pcode: if sz == '1' then UNDEFINED */ + if((res->fields[FIELD_sz]) == (0x1)) { + res->status |= STATUS_UNDEFINED; + } + /* pcode: esize = 32 */ + res->fields[FIELD_esize] = 32; + res->fields_mask[FIELD_esize >> 6] |= 1LL << (FIELD_esize & 63); + /* pcode: elements = 2 */ + res->fields[FIELD_elements] = 2; + res->fields_mask[FIELD_elements >> 6] |= 1LL << (FIELD_elements & 63); + /* pcode: d = UInt(D:Vd) */ + res->fields[FIELD_d] = ((res->fields[FIELD_D]<<Vd_width)|(res->fields[FIELD_Vd])); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: n = UInt(N:Vn) */ + res->fields[FIELD_n] = ((res->fields[FIELD_N]<<Vn_width)|(res->fields[FIELD_Vn])); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: m = UInt(M:Vm) */ + res->fields[FIELD_m] = ((res->fields[FIELD_M]<<Vm_width)|(res->fields[FIELD_Vm])); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + /* pcode: regs = if Q == '0' then 1 else 2 */ + if((res->fields[FIELD_Q]) == (0x0)) { + res->fields[FIELD_regs] = 1; + res->fields_mask[FIELD_regs >> 6] |= 1LL << (FIELD_regs & 63); + } + else { + res->fields[FIELD_regs] = 2; + res->fields_mask[FIELD_regs >> 6] |= 1LL << (FIELD_regs & 63); + } + /* pcode: fmt_idx = (Q == '1') */ + res->fields[FIELD_fmt_idx] = ((res->fields[FIELD_Q]) == (0x1)); + res->fields_mask[FIELD_fmt_idx >> 6] |= 1LL << (FIELD_fmt_idx & 63); + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: E66B34F5 +int vmax_vmin_integer(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + res->group = INSN_GROUP_NEON; + /* Encoding T1 */ + /* pattern="111,U.1,1111,0,D.1,size.2,Vn.4,Vd.4,0110,N.1,Q.1,M.1,0,Vm.4" width=32 stringency=18 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xEF800F10)==0xEF000600)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ADVSIMD)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_U] = (instr & 0x10000000)>>28; + res->fields_mask[FIELD_U >> 6] |= 1LL << (FIELD_U & 63); + char U_width = 1; + res->fields[FIELD_D] = (instr & 0x400000)>>22; + res->fields_mask[FIELD_D >> 6] |= 1LL << (FIELD_D & 63); + char D_width = 1; + res->fields[FIELD_size] = (instr & 0x300000)>>20; + res->fields_mask[FIELD_size >> 6] |= 1LL << (FIELD_size & 63); + char size_width = 2; + res->fields[FIELD_Vn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Vn >> 6] |= 1LL << (FIELD_Vn & 63); + char Vn_width = 4; + res->fields[FIELD_Vd] = (instr & 0xF000)>>12; + res->fields_mask[FIELD_Vd >> 6] |= 1LL << (FIELD_Vd & 63); + char Vd_width = 4; + res->fields[FIELD_N] = (instr & 0x80)>>7; + res->fields_mask[FIELD_N >> 6] |= 1LL << (FIELD_N & 63); + char N_width = 1; + res->fields[FIELD_Q] = (instr & 0x40)>>6; + res->fields_mask[FIELD_Q >> 6] |= 1LL << (FIELD_Q & 63); + char Q_width = 1; + res->fields[FIELD_M] = (instr & 0x20)>>5; + res->fields_mask[FIELD_M >> 6] |= 1LL << (FIELD_M & 63); + char M_width = 1; + res->fields[FIELD_Vm] = instr & 0xF; + res->fields_mask[FIELD_Vm >> 6] |= 1LL << (FIELD_Vm & 63); + char Vm_width = 4; + + static const instruction_format instr_formats[] = + { + { /* VMAX<c>.<dt> <Dd>,<Dn>,<Dm> */ + "vmax", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_VFP_DATA_SIZE, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_n,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_m,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + { /* VMAX<c>.<dt> <Qd>,<Qn>,<Qm> */ + "vmax", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_VFP_DATA_SIZE, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"q","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_n,FIELD_UNINIT,"q","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_m,FIELD_UNINIT,"q","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 2; + res->mnem = armv7::ARMV7_VMAX; + + /* pcode: if Q == '1' && (Vd<0> == '1' || Vn<0> == '1' || Vm<0> == '1') then UNDEFINED */ + if(((res->fields[FIELD_Q]) == (0x1)) && ((((((res->fields[FIELD_Vd] & 1)) == (0x1)) || (((res->fields[FIELD_Vn] & 1)) == (0x1))) || (((res->fields[FIELD_Vm] & 1)) == (0x1))))) { + res->status |= STATUS_UNDEFINED; + } + /* pcode: if size == '11' then UNDEFINED */ + if((res->fields[FIELD_size]) == (0x3)) { + res->status |= STATUS_UNDEFINED; + } + /* pcode: unsigned = (U == '1') */ + res->fields[FIELD_unsigned] = ((res->fields[FIELD_U]) == (0x1)); + res->fields_mask[FIELD_unsigned >> 6] |= 1LL << (FIELD_unsigned & 63); + /* pcode: esize = 8 << UInt(size) */ + res->fields[FIELD_esize] = (8) << ((res->fields[FIELD_size])); + res->fields_mask[FIELD_esize >> 6] |= 1LL << (FIELD_esize & 63); + /* pcode: elements = 64 DIV esize */ + res->fields[FIELD_elements] = ((res->fields[FIELD_esize]) ? ((64) / (res->fields[FIELD_esize])) : 0); + res->fields_mask[FIELD_elements >> 6] |= 1LL << (FIELD_elements & 63); + /* pcode: d = UInt(D:Vd) */ + res->fields[FIELD_d] = ((res->fields[FIELD_D]<<Vd_width)|(res->fields[FIELD_Vd])); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: n = UInt(N:Vn) */ + res->fields[FIELD_n] = ((res->fields[FIELD_N]<<Vn_width)|(res->fields[FIELD_Vn])); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: m = UInt(M:Vm) */ + res->fields[FIELD_m] = ((res->fields[FIELD_M]<<Vm_width)|(res->fields[FIELD_Vm])); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + /* pcode: regs = if Q == '0' then 1 else 2 */ + if((res->fields[FIELD_Q]) == (0x0)) { + res->fields[FIELD_regs] = 1; + res->fields_mask[FIELD_regs >> 6] |= 1LL << (FIELD_regs & 63); + } + else { + res->fields[FIELD_regs] = 2; + res->fields_mask[FIELD_regs >> 6] |= 1LL << (FIELD_regs & 63); + } + /* pcode: fmt_idx = (Q == '1') */ + res->fields[FIELD_fmt_idx] = ((res->fields[FIELD_Q]) == (0x1)); + res->fields_mask[FIELD_fmt_idx >> 6] |= 1LL << (FIELD_fmt_idx & 63); + /* pcode: dt = UInt(U:size) */ + res->fields[FIELD_dt] = ((res->fields[FIELD_U]<<size_width)|(res->fields[FIELD_size])); + res->fields_mask[FIELD_dt >> 6] |= 1LL << (FIELD_dt & 63); + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* Encoding T2 */ + /* pattern="111,U.1,1111,0,D.1,size.2,Vn.4,Vd.4,0110,N.1,Q.1,M.1,1,Vm.4" width=32 stringency=18 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xEF800F10)==0xEF000610)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ADVSIMD)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_U] = (instr & 0x10000000)>>28; + res->fields_mask[FIELD_U >> 6] |= 1LL << (FIELD_U & 63); + char U_width = 1; + res->fields[FIELD_D] = (instr & 0x400000)>>22; + res->fields_mask[FIELD_D >> 6] |= 1LL << (FIELD_D & 63); + char D_width = 1; + res->fields[FIELD_size] = (instr & 0x300000)>>20; + res->fields_mask[FIELD_size >> 6] |= 1LL << (FIELD_size & 63); + char size_width = 2; + res->fields[FIELD_Vn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Vn >> 6] |= 1LL << (FIELD_Vn & 63); + char Vn_width = 4; + res->fields[FIELD_Vd] = (instr & 0xF000)>>12; + res->fields_mask[FIELD_Vd >> 6] |= 1LL << (FIELD_Vd & 63); + char Vd_width = 4; + res->fields[FIELD_N] = (instr & 0x80)>>7; + res->fields_mask[FIELD_N >> 6] |= 1LL << (FIELD_N & 63); + char N_width = 1; + res->fields[FIELD_Q] = (instr & 0x40)>>6; + res->fields_mask[FIELD_Q >> 6] |= 1LL << (FIELD_Q & 63); + char Q_width = 1; + res->fields[FIELD_M] = (instr & 0x20)>>5; + res->fields_mask[FIELD_M >> 6] |= 1LL << (FIELD_M & 63); + char M_width = 1; + res->fields[FIELD_Vm] = instr & 0xF; + res->fields_mask[FIELD_Vm >> 6] |= 1LL << (FIELD_Vm & 63); + char Vm_width = 4; + + static const instruction_format instr_formats[] = + { + { /* VMIN<c>.<dt> <Dd>,<Dn>,<Dm> */ + "vmin", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_VFP_DATA_SIZE, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_n,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_m,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + { /* VMIN<c>.<dt> <Qd>,<Qn>,<Qm> */ + "vmin", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_VFP_DATA_SIZE, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"q","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_n,FIELD_UNINIT,"q","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_m,FIELD_UNINIT,"q","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 2; + res->mnem = armv7::ARMV7_VMIN; + + /* pcode: if Q == '1' && (Vd<0> == '1' || Vn<0> == '1' || Vm<0> == '1') then UNDEFINED */ + if(((res->fields[FIELD_Q]) == (0x1)) && ((((((res->fields[FIELD_Vd] & 1)) == (0x1)) || (((res->fields[FIELD_Vn] & 1)) == (0x1))) || (((res->fields[FIELD_Vm] & 1)) == (0x1))))) { + res->status |= STATUS_UNDEFINED; + } + /* pcode: if size == '11' then UNDEFINED */ + if((res->fields[FIELD_size]) == (0x3)) { + res->status |= STATUS_UNDEFINED; + } + /* pcode: unsigned = (U == '1') */ + res->fields[FIELD_unsigned] = ((res->fields[FIELD_U]) == (0x1)); + res->fields_mask[FIELD_unsigned >> 6] |= 1LL << (FIELD_unsigned & 63); + /* pcode: esize = 8 << UInt(size) */ + res->fields[FIELD_esize] = (8) << ((res->fields[FIELD_size])); + res->fields_mask[FIELD_esize >> 6] |= 1LL << (FIELD_esize & 63); + /* pcode: elements = 64 DIV esize */ + res->fields[FIELD_elements] = ((res->fields[FIELD_esize]) ? ((64) / (res->fields[FIELD_esize])) : 0); + res->fields_mask[FIELD_elements >> 6] |= 1LL << (FIELD_elements & 63); + /* pcode: d = UInt(D:Vd) */ + res->fields[FIELD_d] = ((res->fields[FIELD_D]<<Vd_width)|(res->fields[FIELD_Vd])); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: n = UInt(N:Vn) */ + res->fields[FIELD_n] = ((res->fields[FIELD_N]<<Vn_width)|(res->fields[FIELD_Vn])); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: m = UInt(M:Vm) */ + res->fields[FIELD_m] = ((res->fields[FIELD_M]<<Vm_width)|(res->fields[FIELD_Vm])); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + /* pcode: regs = if Q == '0' then 1 else 2 */ + if((res->fields[FIELD_Q]) == (0x0)) { + res->fields[FIELD_regs] = 1; + res->fields_mask[FIELD_regs >> 6] |= 1LL << (FIELD_regs & 63); + } + else { + res->fields[FIELD_regs] = 2; + res->fields_mask[FIELD_regs >> 6] |= 1LL << (FIELD_regs & 63); + } + /* pcode: fmt_idx = (Q == '1') */ + res->fields[FIELD_fmt_idx] = ((res->fields[FIELD_Q]) == (0x1)); + res->fields_mask[FIELD_fmt_idx >> 6] |= 1LL << (FIELD_fmt_idx & 63); + /* pcode: dt = UInt(U:size) */ + res->fields[FIELD_dt] = ((res->fields[FIELD_U]<<size_width)|(res->fields[FIELD_size])); + res->fields_mask[FIELD_dt >> 6] |= 1LL << (FIELD_dt & 63); + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: 554E2ACB +int vmaxnm(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + res->group = INSN_GROUP_NEON; + /* Encoding T1 */ + /* pattern="1111,11101,D.1,00,Vn.4,Vd.4,101,sz.1,N.1,op.1,M.1,0,Vm.4" width=32 stringency=20 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFFB00E10)==0xFE800A00)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ADVSIMD)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_D] = (instr & 0x400000)>>22; + res->fields_mask[FIELD_D >> 6] |= 1LL << (FIELD_D & 63); + char D_width = 1; + res->fields[FIELD_Vn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Vn >> 6] |= 1LL << (FIELD_Vn & 63); + char Vn_width = 4; + res->fields[FIELD_Vd] = (instr & 0xF000)>>12; + res->fields_mask[FIELD_Vd >> 6] |= 1LL << (FIELD_Vd & 63); + char Vd_width = 4; + res->fields[FIELD_sz] = (instr & 0x100)>>8; + res->fields_mask[FIELD_sz >> 6] |= 1LL << (FIELD_sz & 63); + char sz_width = 1; + res->fields[FIELD_N] = (instr & 0x80)>>7; + res->fields_mask[FIELD_N >> 6] |= 1LL << (FIELD_N & 63); + char N_width = 1; + res->fields[FIELD_op] = (instr & 0x40)>>6; + res->fields_mask[FIELD_op >> 6] |= 1LL << (FIELD_op & 63); + char op_width = 1; + res->fields[FIELD_M] = (instr & 0x20)>>5; + res->fields_mask[FIELD_M >> 6] |= 1LL << (FIELD_M & 63); + char M_width = 1; + res->fields[FIELD_Vm] = instr & 0xF; + res->fields_mask[FIELD_Vm >> 6] |= 1LL << (FIELD_Vm & 63); + char Vm_width = 4; + + static const instruction_format instr_formats[] = + { + { /* VMAXNM.F32 <Sd>,<Sn>,<Sm> */ + "vmaxnm.f32", /* .operation (const char *) */ + 0, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"s","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_n,FIELD_UNINIT,"s","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_m,FIELD_UNINIT,"s","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + { /* VMAXNM.F64 <Dd>,<Dn>,<Dm> */ + "vmaxnm.f64", /* .operation (const char *) */ + 0, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_n,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_m,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + { /* VMINNM.F32 <Sd>,<Sn>,<Sm> */ + "vminnm.f32", /* .operation (const char *) */ + 0, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"s","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_n,FIELD_UNINIT,"s","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_m,FIELD_UNINIT,"s","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + { /* VMINNM.F64 <Dd>,<Dn>,<Dm> */ + "vminnm.f64", /* .operation (const char *) */ + 0, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_n,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_m,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 4; + res->mnem = armv7::ARMV7_VMAXNM; + + /* pcode: dp_operation = (sz == '1') */ + res->fields[FIELD_dp_operation] = ((res->fields[FIELD_sz]) == (0x1)); + res->fields_mask[FIELD_dp_operation >> 6] |= 1LL << (FIELD_dp_operation & 63); + /* pcode: d = if dp_operation then UInt(D:Vd) else UInt(Vd:D) */ + if(res->fields[FIELD_dp_operation]) { + res->fields[FIELD_d] = ((res->fields[FIELD_D]<<Vd_width)|(res->fields[FIELD_Vd])); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + } + else { + res->fields[FIELD_d] = ((res->fields[FIELD_Vd]<<D_width)|(res->fields[FIELD_D])); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + } + /* pcode: n = if dp_operation then UInt(N:Vn) else UInt(Vn:N) */ + if(res->fields[FIELD_dp_operation]) { + res->fields[FIELD_n] = ((res->fields[FIELD_N]<<Vn_width)|(res->fields[FIELD_Vn])); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + } + else { + res->fields[FIELD_n] = ((res->fields[FIELD_Vn]<<N_width)|(res->fields[FIELD_N])); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + } + /* pcode: m = if dp_operation then UInt(M:Vm) else UInt(Vm:M) */ + if(res->fields[FIELD_dp_operation]) { + res->fields[FIELD_m] = ((res->fields[FIELD_M]<<Vm_width)|(res->fields[FIELD_Vm])); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + } + else { + res->fields[FIELD_m] = ((res->fields[FIELD_Vm]<<M_width)|(res->fields[FIELD_M])); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + } + /* pcode: fmt_idx = ((op == '1') * 2) + dp_operation */ + res->fields[FIELD_fmt_idx] = (((((res->fields[FIELD_op]) == (0x1))) * (2))) + (res->fields[FIELD_dp_operation]); + res->fields_mask[FIELD_fmt_idx >> 6] |= 1LL << (FIELD_fmt_idx & 63); + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: B91C91F4 +int vmla_float(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + res->group = INSN_GROUP_NEON; + /* Encoding T2 */ + /* pattern="1110,11100,D.1,00,Vn.4,Vd.4,101,sz.1,N.1,op.1,M.1,0,Vm.4" width=32 stringency=20 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFFB00E10)==0xEE000A00)) { + res->instrSize = 32; + if(!(req->arch & ARCH_VFPv2) && !(req->arch & ARCH_VFPv3)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_D] = (instr & 0x400000)>>22; + res->fields_mask[FIELD_D >> 6] |= 1LL << (FIELD_D & 63); + char D_width = 1; + res->fields[FIELD_Vn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Vn >> 6] |= 1LL << (FIELD_Vn & 63); + char Vn_width = 4; + res->fields[FIELD_Vd] = (instr & 0xF000)>>12; + res->fields_mask[FIELD_Vd >> 6] |= 1LL << (FIELD_Vd & 63); + char Vd_width = 4; + res->fields[FIELD_sz] = (instr & 0x100)>>8; + res->fields_mask[FIELD_sz >> 6] |= 1LL << (FIELD_sz & 63); + char sz_width = 1; + res->fields[FIELD_N] = (instr & 0x80)>>7; + res->fields_mask[FIELD_N >> 6] |= 1LL << (FIELD_N & 63); + char N_width = 1; + res->fields[FIELD_op] = (instr & 0x40)>>6; + res->fields_mask[FIELD_op >> 6] |= 1LL << (FIELD_op & 63); + char op_width = 1; + res->fields[FIELD_M] = (instr & 0x20)>>5; + res->fields_mask[FIELD_M >> 6] |= 1LL << (FIELD_M & 63); + char M_width = 1; + res->fields[FIELD_Vm] = instr & 0xF; + res->fields_mask[FIELD_Vm >> 6] |= 1LL << (FIELD_Vm & 63); + char Vm_width = 4; + + static const instruction_format instr_formats[] = + { + { /* VMLA<c>.F32 <Sd>,<Sn>,<Sm> */ + "vmla.f32", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_F32, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"s","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_n,FIELD_UNINIT,"s","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_m,FIELD_UNINIT,"s","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + { /* VMLA<c>.F64 <Dd>,<Dn>,<Dm> */ + "vmla.f64", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_F64, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_n,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_m,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + { /* VMLS<c>.F32 <Sd>,<Sn>,<Sm> */ + "vmls.f32", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_F32, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"s","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_n,FIELD_UNINIT,"s","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_m,FIELD_UNINIT,"s","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + { /* VMLS<c>.F64 <Dd>,<Dn>,<Dm> */ + "vmls.f64", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_F64, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_n,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_m,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 4; + res->mnem = armv7::ARMV7_VMLA; + + /* pcode: advsimd = FALSE */ + res->fields[FIELD_advsimd] = 0; + res->fields_mask[FIELD_advsimd >> 6] |= 1LL << (FIELD_advsimd & 63); + /* pcode: dp_operation = (sz == '1') */ + res->fields[FIELD_dp_operation] = ((res->fields[FIELD_sz]) == (0x1)); + res->fields_mask[FIELD_dp_operation >> 6] |= 1LL << (FIELD_dp_operation & 63); + /* pcode: add = (op == '0') */ + res->fields[FIELD_add] = ((res->fields[FIELD_op]) == (0x0)); + res->fields_mask[FIELD_add >> 6] |= 1LL << (FIELD_add & 63); + /* pcode: d = if dp_operation then UInt(D:Vd) else UInt(Vd:D) */ + if(res->fields[FIELD_dp_operation]) { + res->fields[FIELD_d] = ((res->fields[FIELD_D]<<Vd_width)|(res->fields[FIELD_Vd])); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + } + else { + res->fields[FIELD_d] = ((res->fields[FIELD_Vd]<<D_width)|(res->fields[FIELD_D])); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + } + /* pcode: n = if dp_operation then UInt(N:Vn) else UInt(Vn:N) */ + if(res->fields[FIELD_dp_operation]) { + res->fields[FIELD_n] = ((res->fields[FIELD_N]<<Vn_width)|(res->fields[FIELD_Vn])); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + } + else { + res->fields[FIELD_n] = ((res->fields[FIELD_Vn]<<N_width)|(res->fields[FIELD_N])); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + } + /* pcode: m = if dp_operation then UInt(M:Vm) else UInt(Vm:M) */ + if(res->fields[FIELD_dp_operation]) { + res->fields[FIELD_m] = ((res->fields[FIELD_M]<<Vm_width)|(res->fields[FIELD_Vm])); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + } + else { + res->fields[FIELD_m] = ((res->fields[FIELD_Vm]<<M_width)|(res->fields[FIELD_M])); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + } + /* pcode: fmt_idx = (op * 2) + dp_operation */ + res->fields[FIELD_fmt_idx] = (((res->fields[FIELD_op]) * (2))) + (res->fields[FIELD_dp_operation]); + res->fields_mask[FIELD_fmt_idx >> 6] |= 1LL << (FIELD_fmt_idx & 63); + /* pcode: dt = size */ + res->fields[FIELD_dt] = res->fields[FIELD_size]; + res->fields_mask[FIELD_dt >> 6] |= 1LL << (FIELD_dt & 63); + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* Encoding T1 */ + /* pattern="1110,1111,0,D.1,op.1,sz.1,Vn.4,Vd.4,1101,N.1,Q.1,M.1,1,Vm.4" width=32 stringency=20 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFF800F10)==0xEF000D10)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ADVSIMD)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_D] = (instr & 0x400000)>>22; + res->fields_mask[FIELD_D >> 6] |= 1LL << (FIELD_D & 63); + char D_width = 1; + res->fields[FIELD_op] = (instr & 0x200000)>>21; + res->fields_mask[FIELD_op >> 6] |= 1LL << (FIELD_op & 63); + char op_width = 1; + res->fields[FIELD_sz] = (instr & 0x100000)>>20; + res->fields_mask[FIELD_sz >> 6] |= 1LL << (FIELD_sz & 63); + char sz_width = 1; + res->fields[FIELD_Vn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Vn >> 6] |= 1LL << (FIELD_Vn & 63); + char Vn_width = 4; + res->fields[FIELD_Vd] = (instr & 0xF000)>>12; + res->fields_mask[FIELD_Vd >> 6] |= 1LL << (FIELD_Vd & 63); + char Vd_width = 4; + res->fields[FIELD_N] = (instr & 0x80)>>7; + res->fields_mask[FIELD_N >> 6] |= 1LL << (FIELD_N & 63); + char N_width = 1; + res->fields[FIELD_Q] = (instr & 0x40)>>6; + res->fields_mask[FIELD_Q >> 6] |= 1LL << (FIELD_Q & 63); + char Q_width = 1; + res->fields[FIELD_M] = (instr & 0x20)>>5; + res->fields_mask[FIELD_M >> 6] |= 1LL << (FIELD_M & 63); + char M_width = 1; + res->fields[FIELD_Vm] = instr & 0xF; + res->fields_mask[FIELD_Vm >> 6] |= 1LL << (FIELD_Vm & 63); + char Vm_width = 4; + + static const instruction_format instr_formats[] = + { + { /* VMLA<c>.F32 <Dd>,<Dn>,<Dm> */ + "vmla.f32", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_F32, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_n,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_m,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + { /* VMLA<c>.F32 <Qd>,<Qn>,<Qm> */ + "vmla.f32", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_F32, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"q","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_n,FIELD_UNINIT,"q","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_m,FIELD_UNINIT,"q","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + { /* VMLS<c>.F32 <Dd>,<Dn>,<Dm> */ + "vmls.f32", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_F32, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_n,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_m,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + { /* VMLS<c>.F32 <Qd>,<Qn>,<Qm> */ + "vmls.f32", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_F32, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"q","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_n,FIELD_UNINIT,"q","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_m,FIELD_UNINIT,"q","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 4; + res->mnem = armv7::ARMV7_VMLA; + + /* pcode: if (Q == '1' && (Vd<0> == '1' || Vn<0> == '1' || Vm<0> == '1')) then UNDEFINED */ + if((((res->fields[FIELD_Q]) == (0x1)) && ((((((res->fields[FIELD_Vd] & 1)) == (0x1)) || (((res->fields[FIELD_Vn] & 1)) == (0x1))) || (((res->fields[FIELD_Vm] & 1)) == (0x1)))))) { + res->status |= STATUS_UNDEFINED; + } + /* pcode: if sz == '1' then UNDEFINED */ + if((res->fields[FIELD_sz]) == (0x1)) { + res->status |= STATUS_UNDEFINED; + } + /* pcode: advsimd = TRUE */ + res->fields[FIELD_advsimd] = 1; + res->fields_mask[FIELD_advsimd >> 6] |= 1LL << (FIELD_advsimd & 63); + /* pcode: esize = 32 */ + res->fields[FIELD_esize] = 32; + res->fields_mask[FIELD_esize >> 6] |= 1LL << (FIELD_esize & 63); + /* pcode: elements = 2 */ + res->fields[FIELD_elements] = 2; + res->fields_mask[FIELD_elements >> 6] |= 1LL << (FIELD_elements & 63); + /* pcode: d = UInt(D:Vd) */ + res->fields[FIELD_d] = ((res->fields[FIELD_D]<<Vd_width)|(res->fields[FIELD_Vd])); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: n = UInt(N:Vn) */ + res->fields[FIELD_n] = ((res->fields[FIELD_N]<<Vn_width)|(res->fields[FIELD_Vn])); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: m = UInt(M:Vm) */ + res->fields[FIELD_m] = ((res->fields[FIELD_M]<<Vm_width)|(res->fields[FIELD_Vm])); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + /* pcode: regs = if Q == '0' then 1 else 2 */ + if((res->fields[FIELD_Q]) == (0x0)) { + res->fields[FIELD_regs] = 1; + res->fields_mask[FIELD_regs >> 6] |= 1LL << (FIELD_regs & 63); + } + else { + res->fields[FIELD_regs] = 2; + res->fields_mask[FIELD_regs >> 6] |= 1LL << (FIELD_regs & 63); + } + /* pcode: fmt_idx = (op * 2) + (Q == '1') */ + res->fields[FIELD_fmt_idx] = (((res->fields[FIELD_op]) * (2))) + (((res->fields[FIELD_Q]) == (0x1))); + res->fields_mask[FIELD_fmt_idx >> 6] |= 1LL << (FIELD_fmt_idx & 63); + /* pcode: dt = size */ + res->fields[FIELD_dt] = res->fields[FIELD_size]; + res->fields_mask[FIELD_dt >> 6] |= 1LL << (FIELD_dt & 63); + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: 572D595B +int vmla_integer(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + res->group = INSN_GROUP_NEON; + /* Encoding T4 */ + /* pattern="111,U.1,1111,1,D.1,size.2,Vn.4,Vd.4,10,1,0,N.1,0,M.1,0,Vm.4" width=32 stringency=18 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xEF800F50)==0xEF800A00)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ADVSIMD)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_U] = (instr & 0x10000000)>>28; + res->fields_mask[FIELD_U >> 6] |= 1LL << (FIELD_U & 63); + char U_width = 1; + res->fields[FIELD_D] = (instr & 0x400000)>>22; + res->fields_mask[FIELD_D >> 6] |= 1LL << (FIELD_D & 63); + char D_width = 1; + res->fields[FIELD_size] = (instr & 0x300000)>>20; + res->fields_mask[FIELD_size >> 6] |= 1LL << (FIELD_size & 63); + char size_width = 2; + res->fields[FIELD_Vn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Vn >> 6] |= 1LL << (FIELD_Vn & 63); + char Vn_width = 4; + res->fields[FIELD_Vd] = (instr & 0xF000)>>12; + res->fields_mask[FIELD_Vd >> 6] |= 1LL << (FIELD_Vd & 63); + char Vd_width = 4; + res->fields[FIELD_N] = (instr & 0x80)>>7; + res->fields_mask[FIELD_N >> 6] |= 1LL << (FIELD_N & 63); + char N_width = 1; + res->fields[FIELD_M] = (instr & 0x20)>>5; + res->fields_mask[FIELD_M >> 6] |= 1LL << (FIELD_M & 63); + char M_width = 1; + res->fields[FIELD_Vm] = instr & 0xF; + res->fields_mask[FIELD_Vm >> 6] |= 1LL << (FIELD_Vm & 63); + char Vm_width = 4; + + static const instruction_format instr_formats[] = + { + { /* VMLSL<c>.S<size> <Qd>,<Dn>,<Dm> */ + "vmlsl.s", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_NEON_SINGLE_SIZE|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"q","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_n,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_m,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + { /* VMLSL<c>.U<size> <Qd>,<Dn>,<Dm> */ + "vmlsl.u", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_NEON_SINGLE_SIZE|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"q","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_n,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_m,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + { /* VMLSL<c>.I<size> <Qd>,<Dn>,<Dm> */ + "vmlsl.i", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_NEON_SINGLE_SIZE|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"q","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_n,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_m,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 3; + res->mnem = armv7::ARMV7_VMLSL; + + /* pcode: if size == '11' then SEE advanced_simd_data_proc */ + if((res->fields[FIELD_size]) == (0x3)) { + + return advanced_simd_data_proc(req, res); + } + /* pcode: if Vd<0> == '1' then UNDEFINED */ + if(((res->fields[FIELD_Vd] & 1)) == (0x1)) { + res->status |= STATUS_UNDEFINED; + } + /* pcode: long_destination = TRUE */ + res->fields[FIELD_long_destination] = 1; + res->fields_mask[FIELD_long_destination >> 6] |= 1LL << (FIELD_long_destination & 63); + /* pcode: unsigned = (U == '1') */ + res->fields[FIELD_unsigned] = ((res->fields[FIELD_U]) == (0x1)); + res->fields_mask[FIELD_unsigned >> 6] |= 1LL << (FIELD_unsigned & 63); + /* pcode: esize = 8 << UInt(size) */ + res->fields[FIELD_esize] = (8) << ((res->fields[FIELD_size])); + res->fields_mask[FIELD_esize >> 6] |= 1LL << (FIELD_esize & 63); + /* pcode: elements = 64 DIV esize */ + res->fields[FIELD_elements] = ((res->fields[FIELD_esize]) ? ((64) / (res->fields[FIELD_esize])) : 0); + res->fields_mask[FIELD_elements >> 6] |= 1LL << (FIELD_elements & 63); + /* pcode: d = UInt(D:Vd) */ + res->fields[FIELD_d] = ((res->fields[FIELD_D]<<Vd_width)|(res->fields[FIELD_Vd])); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: n = UInt(N:Vn) */ + res->fields[FIELD_n] = ((res->fields[FIELD_N]<<Vn_width)|(res->fields[FIELD_Vn])); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: m = UInt(M:Vm) */ + res->fields[FIELD_m] = ((res->fields[FIELD_M]<<Vm_width)|(res->fields[FIELD_Vm])); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + /* pcode: regs = 1 */ + res->fields[FIELD_regs] = 1; + res->fields_mask[FIELD_regs >> 6] |= 1LL << (FIELD_regs & 63); + /* pcode: fmt_idx = (U == '1') */ + res->fields[FIELD_fmt_idx] = ((res->fields[FIELD_U]) == (0x1)); + res->fields_mask[FIELD_fmt_idx >> 6] |= 1LL << (FIELD_fmt_idx & 63); + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* Encoding T3 */ + /* pattern="111,1,1111,0,D.1,size.2,Vn.4,Vd.4,1001,N.1,Q.1,M.1,0,Vm.4" width=32 stringency=18 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFF800F10)==0xFF000900)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ADVSIMD)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_D] = (instr & 0x400000)>>22; + res->fields_mask[FIELD_D >> 6] |= 1LL << (FIELD_D & 63); + char D_width = 1; + res->fields[FIELD_size] = (instr & 0x300000)>>20; + res->fields_mask[FIELD_size >> 6] |= 1LL << (FIELD_size & 63); + char size_width = 2; + res->fields[FIELD_Vn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Vn >> 6] |= 1LL << (FIELD_Vn & 63); + char Vn_width = 4; + res->fields[FIELD_Vd] = (instr & 0xF000)>>12; + res->fields_mask[FIELD_Vd >> 6] |= 1LL << (FIELD_Vd & 63); + char Vd_width = 4; + res->fields[FIELD_N] = (instr & 0x80)>>7; + res->fields_mask[FIELD_N >> 6] |= 1LL << (FIELD_N & 63); + char N_width = 1; + res->fields[FIELD_Q] = (instr & 0x40)>>6; + res->fields_mask[FIELD_Q >> 6] |= 1LL << (FIELD_Q & 63); + char Q_width = 1; + res->fields[FIELD_M] = (instr & 0x20)>>5; + res->fields_mask[FIELD_M >> 6] |= 1LL << (FIELD_M & 63); + char M_width = 1; + res->fields[FIELD_Vm] = instr & 0xF; + res->fields_mask[FIELD_Vm >> 6] |= 1LL << (FIELD_Vm & 63); + char Vm_width = 4; + + static const instruction_format instr_formats[] = + { + { /* VMLS<c>.<dt> <Dd>,<Dn>,<Dm> */ + "vmls", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_VFP_DATA_SIZE, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_n,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_m,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + { /* VMLS<c>.<dt> <Qd>,<Qn>,<Qm> */ + "vmls", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_VFP_DATA_SIZE, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"q","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_n,FIELD_UNINIT,"q","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_m,FIELD_UNINIT,"q","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 2; + res->mnem = armv7::ARMV7_VMLS; + + /* pcode: if size == '11' then UNDEFINED */ + if((res->fields[FIELD_size]) == (0x3)) { + res->status |= STATUS_UNDEFINED; + } + /* pcode: if (Q == '1' && (Vd<0> == '1' || Vn<0> == '1' || Vm<0> == '1')) then UNDEFINED */ + if((((res->fields[FIELD_Q]) == (0x1)) && ((((((res->fields[FIELD_Vd] & 1)) == (0x1)) || (((res->fields[FIELD_Vn] & 1)) == (0x1))) || (((res->fields[FIELD_Vm] & 1)) == (0x1)))))) { + res->status |= STATUS_UNDEFINED; + } + /* pcode: long_destination = FALSE */ + res->fields[FIELD_long_destination] = 0; + res->fields_mask[FIELD_long_destination >> 6] |= 1LL << (FIELD_long_destination & 63); + /* pcode: iword = TRUE */ + res->fields[FIELD_iword] = 1; + res->fields_mask[FIELD_iword >> 6] |= 1LL << (FIELD_iword & 63); + /* pcode: esize = 8 << UInt(size) */ + res->fields[FIELD_esize] = (8) << ((res->fields[FIELD_size])); + res->fields_mask[FIELD_esize >> 6] |= 1LL << (FIELD_esize & 63); + /* pcode: elements = 64 DIV esize */ + res->fields[FIELD_elements] = ((res->fields[FIELD_esize]) ? ((64) / (res->fields[FIELD_esize])) : 0); + res->fields_mask[FIELD_elements >> 6] |= 1LL << (FIELD_elements & 63); + /* pcode: d = UInt(D:Vd) */ + res->fields[FIELD_d] = ((res->fields[FIELD_D]<<Vd_width)|(res->fields[FIELD_Vd])); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: n = UInt(N:Vn) */ + res->fields[FIELD_n] = ((res->fields[FIELD_N]<<Vn_width)|(res->fields[FIELD_Vn])); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: m = UInt(M:Vm) */ + res->fields[FIELD_m] = ((res->fields[FIELD_M]<<Vm_width)|(res->fields[FIELD_Vm])); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + /* pcode: regs = if Q == '0' then 1 else 2 */ + if((res->fields[FIELD_Q]) == (0x0)) { + res->fields[FIELD_regs] = 1; + res->fields_mask[FIELD_regs >> 6] |= 1LL << (FIELD_regs & 63); + } + else { + res->fields[FIELD_regs] = 2; + res->fields_mask[FIELD_regs >> 6] |= 1LL << (FIELD_regs & 63); + } + /* pcode: fmt_idx = (Q == '1') */ + res->fields[FIELD_fmt_idx] = ((res->fields[FIELD_Q]) == (0x1)); + res->fields_mask[FIELD_fmt_idx >> 6] |= 1LL << (FIELD_fmt_idx & 63); + /* pcode: dt = size */ + res->fields[FIELD_dt] = res->fields[FIELD_size]; + res->fields_mask[FIELD_dt >> 6] |= 1LL << (FIELD_dt & 63); + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* Encoding T2 */ + /* pattern="111,U.1,1111,1,D.1,size.2,Vn.4,Vd.4,10,0,0,N.1,0,M.1,0,Vm.4" width=32 stringency=18 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xEF800F50)==0xEF800800)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ADVSIMD)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_U] = (instr & 0x10000000)>>28; + res->fields_mask[FIELD_U >> 6] |= 1LL << (FIELD_U & 63); + char U_width = 1; + res->fields[FIELD_D] = (instr & 0x400000)>>22; + res->fields_mask[FIELD_D >> 6] |= 1LL << (FIELD_D & 63); + char D_width = 1; + res->fields[FIELD_size] = (instr & 0x300000)>>20; + res->fields_mask[FIELD_size >> 6] |= 1LL << (FIELD_size & 63); + char size_width = 2; + res->fields[FIELD_Vn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Vn >> 6] |= 1LL << (FIELD_Vn & 63); + char Vn_width = 4; + res->fields[FIELD_Vd] = (instr & 0xF000)>>12; + res->fields_mask[FIELD_Vd >> 6] |= 1LL << (FIELD_Vd & 63); + char Vd_width = 4; + res->fields[FIELD_N] = (instr & 0x80)>>7; + res->fields_mask[FIELD_N >> 6] |= 1LL << (FIELD_N & 63); + char N_width = 1; + res->fields[FIELD_M] = (instr & 0x20)>>5; + res->fields_mask[FIELD_M >> 6] |= 1LL << (FIELD_M & 63); + char M_width = 1; + res->fields[FIELD_Vm] = instr & 0xF; + res->fields_mask[FIELD_Vm >> 6] |= 1LL << (FIELD_Vm & 63); + char Vm_width = 4; + + static const instruction_format instr_formats[] = + { + { /* VMLAL<c>.S<size> <Qd>,<Dn>,<Dm> */ + "vmlal.s", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_NEON_SINGLE_SIZE|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"q","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_n,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_m,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + { /* VMLAL<c>.U<size> <Qd>,<Dn>,<Dm> */ + "vmlal.u", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_NEON_SINGLE_SIZE|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"q","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_n,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_m,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + { /* VMLAL<c>.I<size> <Qd>,<Dn>,<Dm> */ + "vmlal.i", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_NEON_SINGLE_SIZE|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"q","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_n,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_m,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 3; + res->mnem = armv7::ARMV7_VMLAL; + + /* pcode: if size == '11' then SEE advanced_simd_data_proc */ + if((res->fields[FIELD_size]) == (0x3)) { + + return advanced_simd_data_proc(req, res); + } + /* pcode: if Vd<0> == '1' then UNDEFINED */ + if(((res->fields[FIELD_Vd] & 1)) == (0x1)) { + res->status |= STATUS_UNDEFINED; + } + /* pcode: long_destination = TRUE */ + res->fields[FIELD_long_destination] = 1; + res->fields_mask[FIELD_long_destination >> 6] |= 1LL << (FIELD_long_destination & 63); + /* pcode: unsigned = (U == '1') */ + res->fields[FIELD_unsigned] = ((res->fields[FIELD_U]) == (0x1)); + res->fields_mask[FIELD_unsigned >> 6] |= 1LL << (FIELD_unsigned & 63); + /* pcode: esize = 8 << UInt(size) */ + res->fields[FIELD_esize] = (8) << ((res->fields[FIELD_size])); + res->fields_mask[FIELD_esize >> 6] |= 1LL << (FIELD_esize & 63); + /* pcode: elements = 64 DIV esize */ + res->fields[FIELD_elements] = ((res->fields[FIELD_esize]) ? ((64) / (res->fields[FIELD_esize])) : 0); + res->fields_mask[FIELD_elements >> 6] |= 1LL << (FIELD_elements & 63); + /* pcode: d = UInt(D:Vd) */ + res->fields[FIELD_d] = ((res->fields[FIELD_D]<<Vd_width)|(res->fields[FIELD_Vd])); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: n = UInt(N:Vn) */ + res->fields[FIELD_n] = ((res->fields[FIELD_N]<<Vn_width)|(res->fields[FIELD_Vn])); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: m = UInt(M:Vm) */ + res->fields[FIELD_m] = ((res->fields[FIELD_M]<<Vm_width)|(res->fields[FIELD_Vm])); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + /* pcode: regs = 1 */ + res->fields[FIELD_regs] = 1; + res->fields_mask[FIELD_regs >> 6] |= 1LL << (FIELD_regs & 63); + /* pcode: fmt_idx = (U == '1') */ + res->fields[FIELD_fmt_idx] = ((res->fields[FIELD_U]) == (0x1)); + res->fields_mask[FIELD_fmt_idx >> 6] |= 1LL << (FIELD_fmt_idx & 63); + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* Encoding T1 */ + /* pattern="111,0,1111,0,D.1,size.2,Vn.4,Vd.4,1001,N.1,Q.1,M.1,0,Vm.4" width=32 stringency=18 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFF800F10)==0xEF000900)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ADVSIMD)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_D] = (instr & 0x400000)>>22; + res->fields_mask[FIELD_D >> 6] |= 1LL << (FIELD_D & 63); + char D_width = 1; + res->fields[FIELD_size] = (instr & 0x300000)>>20; + res->fields_mask[FIELD_size >> 6] |= 1LL << (FIELD_size & 63); + char size_width = 2; + res->fields[FIELD_Vn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Vn >> 6] |= 1LL << (FIELD_Vn & 63); + char Vn_width = 4; + res->fields[FIELD_Vd] = (instr & 0xF000)>>12; + res->fields_mask[FIELD_Vd >> 6] |= 1LL << (FIELD_Vd & 63); + char Vd_width = 4; + res->fields[FIELD_N] = (instr & 0x80)>>7; + res->fields_mask[FIELD_N >> 6] |= 1LL << (FIELD_N & 63); + char N_width = 1; + res->fields[FIELD_Q] = (instr & 0x40)>>6; + res->fields_mask[FIELD_Q >> 6] |= 1LL << (FIELD_Q & 63); + char Q_width = 1; + res->fields[FIELD_M] = (instr & 0x20)>>5; + res->fields_mask[FIELD_M >> 6] |= 1LL << (FIELD_M & 63); + char M_width = 1; + res->fields[FIELD_Vm] = instr & 0xF; + res->fields_mask[FIELD_Vm >> 6] |= 1LL << (FIELD_Vm & 63); + char Vm_width = 4; + + static const instruction_format instr_formats[] = + { + { /* VMLA<c>.<dt> <Dd>,<Dn>,<Dm> */ + "vmla", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_VFP_DATA_SIZE, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_n,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_m,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + { /* VMLA<c>.<dt> <Qd>,<Qn>,<Qm> */ + "vmla", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_VFP_DATA_SIZE, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"q","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_n,FIELD_UNINIT,"q","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_m,FIELD_UNINIT,"q","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 2; + res->mnem = armv7::ARMV7_VMLA; + + /* pcode: if size == '11' then UNDEFINED */ + if((res->fields[FIELD_size]) == (0x3)) { + res->status |= STATUS_UNDEFINED; + } + /* pcode: if (Q == '1' && (Vd<0> == '1' || Vn<0> == '1' || Vm<0> == '1')) then UNDEFINED */ + if((((res->fields[FIELD_Q]) == (0x1)) && ((((((res->fields[FIELD_Vd] & 1)) == (0x1)) || (((res->fields[FIELD_Vn] & 1)) == (0x1))) || (((res->fields[FIELD_Vm] & 1)) == (0x1)))))) { + res->status |= STATUS_UNDEFINED; + } + /* pcode: long_destination = FALSE */ + res->fields[FIELD_long_destination] = 0; + res->fields_mask[FIELD_long_destination >> 6] |= 1LL << (FIELD_long_destination & 63); + /* pcode: iword = TRUE */ + res->fields[FIELD_iword] = 1; + res->fields_mask[FIELD_iword >> 6] |= 1LL << (FIELD_iword & 63); + /* pcode: esize = 8 << UInt(size) */ + res->fields[FIELD_esize] = (8) << ((res->fields[FIELD_size])); + res->fields_mask[FIELD_esize >> 6] |= 1LL << (FIELD_esize & 63); + /* pcode: elements = 64 DIV esize */ + res->fields[FIELD_elements] = ((res->fields[FIELD_esize]) ? ((64) / (res->fields[FIELD_esize])) : 0); + res->fields_mask[FIELD_elements >> 6] |= 1LL << (FIELD_elements & 63); + /* pcode: d = UInt(D:Vd) */ + res->fields[FIELD_d] = ((res->fields[FIELD_D]<<Vd_width)|(res->fields[FIELD_Vd])); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: n = UInt(N:Vn) */ + res->fields[FIELD_n] = ((res->fields[FIELD_N]<<Vn_width)|(res->fields[FIELD_Vn])); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: m = UInt(M:Vm) */ + res->fields[FIELD_m] = ((res->fields[FIELD_M]<<Vm_width)|(res->fields[FIELD_Vm])); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + /* pcode: regs = if Q == '0' then 1 else 2 */ + if((res->fields[FIELD_Q]) == (0x0)) { + res->fields[FIELD_regs] = 1; + res->fields_mask[FIELD_regs >> 6] |= 1LL << (FIELD_regs & 63); + } + else { + res->fields[FIELD_regs] = 2; + res->fields_mask[FIELD_regs >> 6] |= 1LL << (FIELD_regs & 63); + } + /* pcode: fmt_idx = (Q == '1') */ + res->fields[FIELD_fmt_idx] = ((res->fields[FIELD_Q]) == (0x1)); + res->fields_mask[FIELD_fmt_idx >> 6] |= 1LL << (FIELD_fmt_idx & 63); + /* pcode: dt = size */ + res->fields[FIELD_dt] = res->fields[FIELD_size]; + res->fields_mask[FIELD_dt >> 6] |= 1LL << (FIELD_dt & 63); + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: 7A71D4D7 +int vmla_scalar(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + res->group = INSN_GROUP_NEON; + /* Encoding T2 */ + /* pattern="111,U.1,1111,1,D.1,size.2,Vn.4,Vd.4,0,op.1,10,N.1,1,M.1,0,Vm.4" width=32 stringency=18 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xEF800B50)==0xEF800240)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ADVSIMD)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_U] = (instr & 0x10000000)>>28; + res->fields_mask[FIELD_U >> 6] |= 1LL << (FIELD_U & 63); + char U_width = 1; + res->fields[FIELD_D] = (instr & 0x400000)>>22; + res->fields_mask[FIELD_D >> 6] |= 1LL << (FIELD_D & 63); + char D_width = 1; + res->fields[FIELD_size] = (instr & 0x300000)>>20; + res->fields_mask[FIELD_size >> 6] |= 1LL << (FIELD_size & 63); + char size_width = 2; + res->fields[FIELD_Vn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Vn >> 6] |= 1LL << (FIELD_Vn & 63); + char Vn_width = 4; + res->fields[FIELD_Vd] = (instr & 0xF000)>>12; + res->fields_mask[FIELD_Vd >> 6] |= 1LL << (FIELD_Vd & 63); + char Vd_width = 4; + res->fields[FIELD_op] = (instr & 0x400)>>10; + res->fields_mask[FIELD_op >> 6] |= 1LL << (FIELD_op & 63); + char op_width = 1; + res->fields[FIELD_N] = (instr & 0x80)>>7; + res->fields_mask[FIELD_N >> 6] |= 1LL << (FIELD_N & 63); + char N_width = 1; + res->fields[FIELD_M] = (instr & 0x20)>>5; + res->fields_mask[FIELD_M >> 6] |= 1LL << (FIELD_M & 63); + char M_width = 1; + res->fields[FIELD_Vm] = instr & 0xF; + res->fields_mask[FIELD_Vm >> 6] |= 1LL << (FIELD_Vm & 63); + char Vm_width = 4; + + static const instruction_format instr_formats[] = + { + { /* VMLAL<c>.<type><size> <Qd>,<Dn>,<Dm[x]> */ + "vmlal", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_NEON_TYPE_SIZE|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"q","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_n,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_INDEX,FIELD_m,FIELD_x,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + { /* VMLSL<c>.<type><size> <Qd>,<Dn>,<Dm[x]> */ + "vmlsl", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_NEON_TYPE_SIZE|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"q","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_n,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_INDEX,FIELD_m,FIELD_x,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 2; + res->mnem = armv7::ARMV7_VMLAL; + + /* pcode: if size == '11' then SEE advanced_simd_data_proc */ + if((res->fields[FIELD_size]) == (0x3)) { + + return advanced_simd_data_proc(req, res); + } + /* pcode: if (size == '00' || Vd<0> == '1') then UNDEFINED */ + if((((res->fields[FIELD_size]) == (0x0)) || (((res->fields[FIELD_Vd] & 1)) == (0x1)))) { + res->status |= STATUS_UNDEFINED; + } + /* pcode: unsigned = (U == '1') */ + res->fields[FIELD_unsigned] = ((res->fields[FIELD_U]) == (0x1)); + res->fields_mask[FIELD_unsigned >> 6] |= 1LL << (FIELD_unsigned & 63); + /* pcode: floating_point = FALSE */ + res->fields[FIELD_floating_point] = 0; + res->fields_mask[FIELD_floating_point >> 6] |= 1LL << (FIELD_floating_point & 63); + /* pcode: long_destination = TRUE */ + res->fields[FIELD_long_destination] = 1; + res->fields_mask[FIELD_long_destination >> 6] |= 1LL << (FIELD_long_destination & 63); + /* pcode: d = UInt(D:Vd) */ + res->fields[FIELD_d] = ((res->fields[FIELD_D]<<Vd_width)|(res->fields[FIELD_Vd])); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: n = UInt(N:Vn) */ + res->fields[FIELD_n] = ((res->fields[FIELD_N]<<Vn_width)|(res->fields[FIELD_Vn])); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: regs = 1 */ + res->fields[FIELD_regs] = 1; + res->fields_mask[FIELD_regs >> 6] |= 1LL << (FIELD_regs & 63); + /* pcode: if size == '01' then esize = 16 */ + if((res->fields[FIELD_size]) == (0x1)) { + res->fields[FIELD_esize] = 16; + res->fields_mask[FIELD_esize >> 6] |= 1LL << (FIELD_esize & 63); + } + /* pcode: if size == '10' then esize = 32 */ + if((res->fields[FIELD_size]) == (0x2)) { + res->fields[FIELD_esize] = 32; + res->fields_mask[FIELD_esize >> 6] |= 1LL << (FIELD_esize & 63); + } + /* pcode: elements = 64 DIV esize */ + res->fields[FIELD_elements] = ((res->fields[FIELD_esize]) ? ((64) / (res->fields[FIELD_esize])) : 0); + res->fields_mask[FIELD_elements >> 6] |= 1LL << (FIELD_elements & 63); + /* pcode: if esize == 16 then m = UInt(Vm) - ((UInt(Vm) >> 3) * 8) */ + if((res->fields[FIELD_esize]) == (16)) { + res->fields[FIELD_m] = ((res->fields[FIELD_Vm])) - ((((((res->fields[FIELD_Vm])) >> (3))) * (8))); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + } + /* pcode: if esize == 32 then m = UInt(Vm) */ + if((res->fields[FIELD_esize]) == (32)) { + res->fields[FIELD_m] = (res->fields[FIELD_Vm]); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + } + /* pcode: x = UInt(M:Vm) */ + res->fields[FIELD_x] = ((res->fields[FIELD_M]<<Vm_width)|(res->fields[FIELD_Vm])); + res->fields_mask[FIELD_x >> 6] |= 1LL << (FIELD_x & 63); + /* pcode: if esize == 16 then x = x >> 3 */ + if((res->fields[FIELD_esize]) == (16)) { + res->fields[FIELD_x] = (res->fields[FIELD_x]) >> (3); + res->fields_mask[FIELD_x >> 6] |= 1LL << (FIELD_x & 63); + } + /* pcode: if esize == 32 then x = UInt(M) */ + if((res->fields[FIELD_esize]) == (32)) { + res->fields[FIELD_x] = (res->fields[FIELD_M]); + res->fields_mask[FIELD_x >> 6] |= 1LL << (FIELD_x & 63); + } + /* pcode: fmt_idx = (op == '1') */ + res->fields[FIELD_fmt_idx] = ((res->fields[FIELD_op]) == (0x1)); + res->fields_mask[FIELD_fmt_idx >> 6] |= 1LL << (FIELD_fmt_idx & 63); + /* pcode: type = U + 2 */ + res->fields[FIELD_type] = (res->fields[FIELD_U]) + (2); + res->fields_mask[FIELD_type >> 6] |= 1LL << (FIELD_type & 63); + /* pcode: size = size - 1 */ + res->fields[FIELD_size] = (res->fields[FIELD_size]) - (1); + res->fields_mask[FIELD_size >> 6] |= 1LL << (FIELD_size & 63); + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* Encoding T1 */ + /* pattern="111,Q.1,1111,1,D.1,size.2,Vn.4,Vd.4,0,op.1,0,F.1,N.1,1,M.1,0,Vm.4" width=32 stringency=18 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xEF800A50)==0xEF800040)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ADVSIMD)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_Q] = (instr & 0x10000000)>>28; + res->fields_mask[FIELD_Q >> 6] |= 1LL << (FIELD_Q & 63); + char Q_width = 1; + res->fields[FIELD_D] = (instr & 0x400000)>>22; + res->fields_mask[FIELD_D >> 6] |= 1LL << (FIELD_D & 63); + char D_width = 1; + res->fields[FIELD_size] = (instr & 0x300000)>>20; + res->fields_mask[FIELD_size >> 6] |= 1LL << (FIELD_size & 63); + char size_width = 2; + res->fields[FIELD_Vn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Vn >> 6] |= 1LL << (FIELD_Vn & 63); + char Vn_width = 4; + res->fields[FIELD_Vd] = (instr & 0xF000)>>12; + res->fields_mask[FIELD_Vd >> 6] |= 1LL << (FIELD_Vd & 63); + char Vd_width = 4; + res->fields[FIELD_op] = (instr & 0x400)>>10; + res->fields_mask[FIELD_op >> 6] |= 1LL << (FIELD_op & 63); + char op_width = 1; + res->fields[FIELD_F] = (instr & 0x100)>>8; + res->fields_mask[FIELD_F >> 6] |= 1LL << (FIELD_F & 63); + char F_width = 1; + res->fields[FIELD_N] = (instr & 0x80)>>7; + res->fields_mask[FIELD_N >> 6] |= 1LL << (FIELD_N & 63); + char N_width = 1; + res->fields[FIELD_M] = (instr & 0x20)>>5; + res->fields_mask[FIELD_M >> 6] |= 1LL << (FIELD_M & 63); + char M_width = 1; + res->fields[FIELD_Vm] = instr & 0xF; + res->fields_mask[FIELD_Vm >> 6] |= 1LL << (FIELD_Vm & 63); + char Vm_width = 4; + + static const instruction_format instr_formats[] = + { + { /* VMLA<c>.I<size> <Dd>,<Dn>,<Dm[x]> */ + "vmla.i", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_NEON_SINGLE_SIZE|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_n,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_INDEX,FIELD_m,FIELD_x,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + { /* VMLA<c>.I<size> <Qd>,<Qn>,<Dm[x]> */ + "vmla.i", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_NEON_SINGLE_SIZE|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"q","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_n,FIELD_UNINIT,"q","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_INDEX,FIELD_m,FIELD_x,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + { /* VMLS<c>.I<size> <Dd>,<Dn>,<Dm[x]> */ + "vmls.i", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_NEON_SINGLE_SIZE|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_n,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_INDEX,FIELD_m,FIELD_x,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + { /* VMLS<c>.I<size> <Qd>,<Qn>,<Dm[x]> */ + "vmls.i", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_NEON_SINGLE_SIZE|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"q","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_n,FIELD_UNINIT,"q","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_INDEX,FIELD_m,FIELD_x,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + { /* VMLA<c>.F<size> <Dd>,<Dn>,<Dm[x]> */ + "vmla.f", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_NEON_SINGLE_SIZE|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_n,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_INDEX,FIELD_m,FIELD_x,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + { /* VMLA<c>.F<size> <Qd>,<Qn>,<Dm[x]> */ + "vmla.f", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_NEON_SINGLE_SIZE|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"q","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_n,FIELD_UNINIT,"q","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_INDEX,FIELD_m,FIELD_x,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + { /* VMLS<c>.F<size> <Dd>,<Dn>,<Dm[x]> */ + "vmls.f", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_NEON_SINGLE_SIZE|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_n,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_INDEX,FIELD_m,FIELD_x,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + { /* VMLS<c>.F<size> <Qd>,<Qn>,<Dm[x]> */ + "vmls.f", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_NEON_SINGLE_SIZE|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"q","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_n,FIELD_UNINIT,"q","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_INDEX,FIELD_m,FIELD_x,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 8; + res->mnem = armv7::ARMV7_VMLA; + + /* pcode: if size == '11' then SEE advanced_simd_data_proc */ + if((res->fields[FIELD_size]) == (0x3)) { + + return advanced_simd_data_proc(req, res); + } + /* pcode: if (size == '00' || (F == '1' && size == '01')) then UNDEFINED */ + if((((res->fields[FIELD_size]) == (0x0)) || ((((res->fields[FIELD_F]) == (0x1)) && ((res->fields[FIELD_size]) == (0x1)))))) { + res->status |= STATUS_UNDEFINED; + } + /* pcode: if (Q == '1' && (Vd<0> == '1' || Vn<0> == '1')) then UNDEFINED */ + if((((res->fields[FIELD_Q]) == (0x1)) && (((((res->fields[FIELD_Vd] & 1)) == (0x1)) || (((res->fields[FIELD_Vn] & 1)) == (0x1)))))) { + res->status |= STATUS_UNDEFINED; + } + /* pcode: unsigned = FALSE */ + res->fields[FIELD_unsigned] = 0; + res->fields_mask[FIELD_unsigned >> 6] |= 1LL << (FIELD_unsigned & 63); + /* pcode: floating_point = (F == '1') */ + res->fields[FIELD_floating_point] = ((res->fields[FIELD_F]) == (0x1)); + res->fields_mask[FIELD_floating_point >> 6] |= 1LL << (FIELD_floating_point & 63); + /* pcode: long_destination = FALSE */ + res->fields[FIELD_long_destination] = 0; + res->fields_mask[FIELD_long_destination >> 6] |= 1LL << (FIELD_long_destination & 63); + /* pcode: d = UInt(D:Vd) */ + res->fields[FIELD_d] = ((res->fields[FIELD_D]<<Vd_width)|(res->fields[FIELD_Vd])); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: n = UInt(N:Vn) */ + res->fields[FIELD_n] = ((res->fields[FIELD_N]<<Vn_width)|(res->fields[FIELD_Vn])); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: regs = if Q == '0' then 1 else 2 */ + if((res->fields[FIELD_Q]) == (0x0)) { + res->fields[FIELD_regs] = 1; + res->fields_mask[FIELD_regs >> 6] |= 1LL << (FIELD_regs & 63); + } + else { + res->fields[FIELD_regs] = 2; + res->fields_mask[FIELD_regs >> 6] |= 1LL << (FIELD_regs & 63); + } + /* pcode: if size == '01' then esize = 16 */ + if((res->fields[FIELD_size]) == (0x1)) { + res->fields[FIELD_esize] = 16; + res->fields_mask[FIELD_esize >> 6] |= 1LL << (FIELD_esize & 63); + } + /* pcode: if size == '10' then esize = 32 */ + if((res->fields[FIELD_size]) == (0x2)) { + res->fields[FIELD_esize] = 32; + res->fields_mask[FIELD_esize >> 6] |= 1LL << (FIELD_esize & 63); + } + /* pcode: elements = 64 DIV esize */ + res->fields[FIELD_elements] = ((res->fields[FIELD_esize]) ? ((64) / (res->fields[FIELD_esize])) : 0); + res->fields_mask[FIELD_elements >> 6] |= 1LL << (FIELD_elements & 63); + /* pcode: if esize == 16 then m = UInt(Vm) - ((UInt(Vm) >> 3) * 8) */ + if((res->fields[FIELD_esize]) == (16)) { + res->fields[FIELD_m] = ((res->fields[FIELD_Vm])) - ((((((res->fields[FIELD_Vm])) >> (3))) * (8))); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + } + /* pcode: if esize == 32 then m = UInt(Vm) */ + if((res->fields[FIELD_esize]) == (32)) { + res->fields[FIELD_m] = (res->fields[FIELD_Vm]); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + } + /* pcode: x = UInt(M:Vm) */ + res->fields[FIELD_x] = ((res->fields[FIELD_M]<<Vm_width)|(res->fields[FIELD_Vm])); + res->fields_mask[FIELD_x >> 6] |= 1LL << (FIELD_x & 63); + /* pcode: if esize == 16 then x = x >> 3 */ + if((res->fields[FIELD_esize]) == (16)) { + res->fields[FIELD_x] = (res->fields[FIELD_x]) >> (3); + res->fields_mask[FIELD_x >> 6] |= 1LL << (FIELD_x & 63); + } + /* pcode: if esize == 32 then x = UInt(M) */ + if((res->fields[FIELD_esize]) == (32)) { + res->fields[FIELD_x] = (res->fields[FIELD_M]); + res->fields_mask[FIELD_x >> 6] |= 1LL << (FIELD_x & 63); + } + /* pcode: fmt_idx = (F == '1') */ + res->fields[FIELD_fmt_idx] = ((res->fields[FIELD_F]) == (0x1)); + res->fields_mask[FIELD_fmt_idx >> 6] |= 1LL << (FIELD_fmt_idx & 63); + /* pcode: fmt_idx = fmt_idx * 4 */ + res->fields[FIELD_fmt_idx] = (res->fields[FIELD_fmt_idx]) * (4); + res->fields_mask[FIELD_fmt_idx >> 6] |= 1LL << (FIELD_fmt_idx & 63); + /* pcode: fmt_idx = fmt_idx + (op * 2) */ + res->fields[FIELD_fmt_idx] = (res->fields[FIELD_fmt_idx]) + (((res->fields[FIELD_op]) * (2))); + res->fields_mask[FIELD_fmt_idx >> 6] |= 1LL << (FIELD_fmt_idx & 63); + /* pcode: fmt_idx = fmt_idx + (Q == '1') */ + res->fields[FIELD_fmt_idx] = (res->fields[FIELD_fmt_idx]) + (((res->fields[FIELD_Q]) == (0x1))); + res->fields_mask[FIELD_fmt_idx >> 6] |= 1LL << (FIELD_fmt_idx & 63); + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: E4D354FF +int vmov_core_double(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + res->group = INSN_GROUP_NEON; + /* Encoding T1 */ + /* pattern="1110,1100,010,op.1,Rt2.4,Rt.4,1011,00,M.1,1,Vm.4" width=32 stringency=20 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFFE00FD0)==0xEC400B10)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ADVSIMD)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_op] = (instr & 0x100000)>>20; + res->fields_mask[FIELD_op >> 6] |= 1LL << (FIELD_op & 63); + char op_width = 1; + res->fields[FIELD_Rt2] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Rt2 >> 6] |= 1LL << (FIELD_Rt2 & 63); + char Rt2_width = 4; + res->fields[FIELD_Rt] = (instr & 0xF000)>>12; + res->fields_mask[FIELD_Rt >> 6] |= 1LL << (FIELD_Rt & 63); + char Rt_width = 4; + res->fields[FIELD_M] = (instr & 0x20)>>5; + res->fields_mask[FIELD_M >> 6] |= 1LL << (FIELD_M & 63); + char M_width = 1; + res->fields[FIELD_Vm] = instr & 0xF; + res->fields_mask[FIELD_Vm >> 6] |= 1LL << (FIELD_Vm & 63); + char Vm_width = 4; + + static const instruction_format instr_formats[] = + { + { /* VMOV<c> <Dm>,<Rt>,<Rt2> */ + "vmov", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_m,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG,FIELD_Rt,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rt2,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + { /* VMOV<c> <Rt>,<Rt2>,<Dm> */ + "vmov", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rt,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rt2,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG_FP,FIELD_m,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 2; + res->mnem = armv7::ARMV7_VMOV; + + /* pcode: t = UInt(Rt) */ + res->fields[FIELD_t] = (res->fields[FIELD_Rt]); + res->fields_mask[FIELD_t >> 6] |= 1LL << (FIELD_t & 63); + /* pcode: t2 = UInt(Rt2) */ + res->fields[FIELD_t2] = (res->fields[FIELD_Rt2]); + res->fields_mask[FIELD_t2 >> 6] |= 1LL << (FIELD_t2 & 63); + /* pcode: m = UInt(M:Vm) */ + res->fields[FIELD_m] = ((res->fields[FIELD_M]<<Vm_width)|(res->fields[FIELD_Vm])); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + /* pcode: if (t == 15 || t2 == 15) then UNPREDICTABLE */ + if((((res->fields[FIELD_t]) == (15)) || ((res->fields[FIELD_t2]) == (15)))) { + res->flags |= FLAG_UNPREDICTABLE; + } + /* pcode: if (t == 13 || t2 == 13) then UNPREDICTABLE */ + if((((res->fields[FIELD_t]) == (13)) || ((res->fields[FIELD_t2]) == (13)))) { + res->flags |= FLAG_UNPREDICTABLE; + } + /* pcode: if ((op == '1') && t == t2) then UNPREDICTABLE */ + if(((((res->fields[FIELD_op]) == (0x1))) && ((res->fields[FIELD_t]) == (res->fields[FIELD_t2])))) { + res->flags |= FLAG_UNPREDICTABLE; + } + /* pcode: fmt_idx = op */ + res->fields[FIELD_fmt_idx] = res->fields[FIELD_op]; + res->fields_mask[FIELD_fmt_idx >> 6] |= 1LL << (FIELD_fmt_idx & 63); + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: 8ABB8CDF +int vmov_core_scalar(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + res->group = INSN_GROUP_NEON; + /* Encoding T1 */ + /* pattern="1110,1110,0,opc1.2,0,Vd.4,Rt.4,1011,D.1,opc2.2,1,(0)(0)(0)(0)" width=32 stringency=21 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFF900F10)==0xEE000B10)) { + res->instrSize = 32; + if(!((instr & 0xF)==0x0)) { + res->flags |= FLAG_UNPREDICTABLE; + } + if(!(req->arch & ARCH_ADVSIMD)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_opc1] = (instr & 0x600000)>>21; + res->fields_mask[FIELD_opc1 >> 6] |= 1LL << (FIELD_opc1 & 63); + char opc1_width = 2; + res->fields[FIELD_Vd] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Vd >> 6] |= 1LL << (FIELD_Vd & 63); + char Vd_width = 4; + res->fields[FIELD_Rt] = (instr & 0xF000)>>12; + res->fields_mask[FIELD_Rt >> 6] |= 1LL << (FIELD_Rt & 63); + char Rt_width = 4; + res->fields[FIELD_D] = (instr & 0x80)>>7; + res->fields_mask[FIELD_D >> 6] |= 1LL << (FIELD_D & 63); + char D_width = 1; + res->fields[FIELD_opc2] = (instr & 0x60)>>5; + res->fields_mask[FIELD_opc2 >> 6] |= 1LL << (FIELD_opc2 & 63); + char opc2_width = 2; + + static const instruction_format instr_formats[] = + { + { /* VMOV<c>.<size> <Dd[x]>,<Rt> */ + "vmov", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_NEON_SIZE, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_INDEX,FIELD_d,FIELD_x,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG,FIELD_Rt,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_VMOV; + + /* pcode: if UInt(opc1) >= 2 then esize = 8 */ + if(((res->fields[FIELD_opc1])) >= (2)) { + res->fields[FIELD_esize] = 8; + res->fields_mask[FIELD_esize >> 6] |= 1LL << (FIELD_esize & 63); + } + /* pcode: if (UInt(opc1) < 2 && UInt(opc2 >= 1)) then esize = 16 */ + if(((((res->fields[FIELD_opc1])) < (2)) && (((res->fields[FIELD_opc2]) >= (1))))) { + res->fields[FIELD_esize] = 16; + res->fields_mask[FIELD_esize >> 6] |= 1LL << (FIELD_esize & 63); + } + /* pcode: if (UInt(opc1) < 2 && opc2 == '00') then esize = 32 */ + if(((((res->fields[FIELD_opc1])) < (2)) && ((res->fields[FIELD_opc2]) == (0x0)))) { + res->fields[FIELD_esize] = 32; + res->fields_mask[FIELD_esize >> 6] |= 1LL << (FIELD_esize & 63); + } + /* pcode: if (UInt(opc1) < 2 && opc2 == '10') then UNDEFINED */ + if(((((res->fields[FIELD_opc1])) < (2)) && ((res->fields[FIELD_opc2]) == (0x2)))) { + res->status |= STATUS_UNDEFINED; + } + /* pcode: d = UInt(D:Vd) */ + res->fields[FIELD_d] = ((res->fields[FIELD_D]<<Vd_width)|(res->fields[FIELD_Vd])); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: t = UInt(Rt) */ + res->fields[FIELD_t] = (res->fields[FIELD_Rt]); + res->fields_mask[FIELD_t >> 6] |= 1LL << (FIELD_t & 63); + /* pcode: if esize == 8 then x = UInt(opc1:opc2) - 8 */ + if((res->fields[FIELD_esize]) == (8)) { + res->fields[FIELD_x] = (((res->fields[FIELD_opc1]<<2)|(res->fields[FIELD_opc2]))) - (8); + res->fields_mask[FIELD_x >> 6] |= 1LL << (FIELD_x & 63); + } + /* pcode: if esize == 16 then x = UInt(opc1:opc2) >> 1 */ + if((res->fields[FIELD_esize]) == (16)) { + res->fields[FIELD_x] = (((res->fields[FIELD_opc1]<<2)|(res->fields[FIELD_opc2]))) >> (1); + res->fields_mask[FIELD_x >> 6] |= 1LL << (FIELD_x & 63); + } + /* pcode: if esize == 32 then x = UInt(opc1) */ + if((res->fields[FIELD_esize]) == (32)) { + res->fields[FIELD_x] = (res->fields[FIELD_opc1]); + res->fields_mask[FIELD_x >> 6] |= 1LL << (FIELD_x & 63); + } + /* pcode: if esize == 8 then size = 0 */ + if((res->fields[FIELD_esize]) == (8)) { + res->fields[FIELD_size] = 0; + res->fields_mask[FIELD_size >> 6] |= 1LL << (FIELD_size & 63); + } + /* pcode: if esize == 16 then size = 1 */ + if((res->fields[FIELD_esize]) == (16)) { + res->fields[FIELD_size] = 1; + res->fields_mask[FIELD_size >> 6] |= 1LL << (FIELD_size & 63); + } + /* pcode: if esize == 32 then size = 2 */ + if((res->fields[FIELD_esize]) == (32)) { + res->fields[FIELD_size] = 2; + res->fields_mask[FIELD_size >> 6] |= 1LL << (FIELD_size & 63); + } + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: BD86E760 +int vmov_core_single(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + res->group = INSN_GROUP_NEON; + /* Encoding T1 */ + /* pattern="1110,1110,000,op.1,Vn.4,Rt.4,1010,N.1,(0)(0),1,(0)(0)(0)(0)" width=32 stringency=24 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFFE00F10)==0xEE000A10)) { + res->instrSize = 32; + if(!((instr & 0x6F)==0x0)) { + res->flags |= FLAG_UNPREDICTABLE; + } + if(!(req->arch & ARCH_ADVSIMD)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_op] = (instr & 0x100000)>>20; + res->fields_mask[FIELD_op >> 6] |= 1LL << (FIELD_op & 63); + char op_width = 1; + res->fields[FIELD_Vn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Vn >> 6] |= 1LL << (FIELD_Vn & 63); + char Vn_width = 4; + res->fields[FIELD_Rt] = (instr & 0xF000)>>12; + res->fields_mask[FIELD_Rt >> 6] |= 1LL << (FIELD_Rt & 63); + char Rt_width = 4; + res->fields[FIELD_N] = (instr & 0x80)>>7; + res->fields_mask[FIELD_N >> 6] |= 1LL << (FIELD_N & 63); + char N_width = 1; + + static const instruction_format instr_formats[] = + { + { /* VMOV<c> <Sn>,<Rt> */ + "vmov", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_n,FIELD_UNINIT,"s","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG,FIELD_Rt,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + { /* VMOV<c> <Rt>,<Sn> */ + "vmov", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rt,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG_FP,FIELD_n,FIELD_UNINIT,"s","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 2; + res->mnem = armv7::ARMV7_VMOV; + + /* pcode: t = UInt(Rt) */ + res->fields[FIELD_t] = (res->fields[FIELD_Rt]); + res->fields_mask[FIELD_t >> 6] |= 1LL << (FIELD_t & 63); + /* pcode: n = UInt(Vn:N) */ + res->fields[FIELD_n] = ((res->fields[FIELD_Vn]<<N_width)|(res->fields[FIELD_N])); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: if t == 15 || t == 13 then UNPREDICTABLE */ + if(((res->fields[FIELD_t]) == (15)) || ((res->fields[FIELD_t]) == (13))) { + res->flags |= FLAG_UNPREDICTABLE; + } + /* pcode: fmt_idx = op */ + res->fields[FIELD_fmt_idx] = res->fields[FIELD_op]; + res->fields_mask[FIELD_fmt_idx >> 6] |= 1LL << (FIELD_fmt_idx & 63); + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: 73B3CE8D +int vmov_core_two_single(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + res->group = INSN_GROUP_NEON; + /* Encoding T1 */ + /* pattern="1110,1100,010,op.1,Rt2.4,Rt.4,1010,00,M.1,1,Vm.4" width=32 stringency=20 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFFE00FD0)==0xEC400A10)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ADVSIMD)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_op] = (instr & 0x100000)>>20; + res->fields_mask[FIELD_op >> 6] |= 1LL << (FIELD_op & 63); + char op_width = 1; + res->fields[FIELD_Rt2] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Rt2 >> 6] |= 1LL << (FIELD_Rt2 & 63); + char Rt2_width = 4; + res->fields[FIELD_Rt] = (instr & 0xF000)>>12; + res->fields_mask[FIELD_Rt >> 6] |= 1LL << (FIELD_Rt & 63); + char Rt_width = 4; + res->fields[FIELD_M] = (instr & 0x20)>>5; + res->fields_mask[FIELD_M >> 6] |= 1LL << (FIELD_M & 63); + char M_width = 1; + res->fields[FIELD_Vm] = instr & 0xF; + res->fields_mask[FIELD_Vm >> 6] |= 1LL << (FIELD_Vm & 63); + char Vm_width = 4; + + static const instruction_format instr_formats[] = + { + { /* VMOV<c> <Sm>,<Sd>,<Rt>,<Rt2> */ + "vmov", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_m,FIELD_UNINIT,"s","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"s","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG,FIELD_Rt,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rt2,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 4 /* .operandCount */ + }, + { /* VMOV<c> <Rt>,<Rt2>,<Sm>,<Sd> */ + "vmov", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rt,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rt2,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG_FP,FIELD_m,FIELD_UNINIT,"s","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"s","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 4 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 2; + res->mnem = armv7::ARMV7_VMOV; + + /* pcode: t = UInt(Rt) */ + res->fields[FIELD_t] = (res->fields[FIELD_Rt]); + res->fields_mask[FIELD_t >> 6] |= 1LL << (FIELD_t & 63); + /* pcode: t2 = UInt(Rt2) */ + res->fields[FIELD_t2] = (res->fields[FIELD_Rt2]); + res->fields_mask[FIELD_t2 >> 6] |= 1LL << (FIELD_t2 & 63); + /* pcode: m = UInt(Vm:M) */ + res->fields[FIELD_m] = ((res->fields[FIELD_Vm]<<M_width)|(res->fields[FIELD_M])); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + /* pcode: if (t == 15 || t2 == 15 || m == 31) then UNPREDICTABLE */ + if(((((res->fields[FIELD_t]) == (15)) || ((res->fields[FIELD_t2]) == (15))) || ((res->fields[FIELD_m]) == (31)))) { + res->flags |= FLAG_UNPREDICTABLE; + } + /* pcode: if (t == 13 || t2 == 13) then UNPREDICTABLE */ + if((((res->fields[FIELD_t]) == (13)) || ((res->fields[FIELD_t2]) == (13)))) { + res->flags |= FLAG_UNPREDICTABLE; + } + /* pcode: if ((op == '1') && t == t2) then UNPREDICTABLE */ + if(((((res->fields[FIELD_op]) == (0x1))) && ((res->fields[FIELD_t]) == (res->fields[FIELD_t2])))) { + res->flags |= FLAG_UNPREDICTABLE; + } + /* pcode: d = m + 1 */ + res->fields[FIELD_d] = (res->fields[FIELD_m]) + (1); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: fmt_idx = op */ + res->fields[FIELD_fmt_idx] = res->fields[FIELD_op]; + res->fields_mask[FIELD_fmt_idx >> 6] |= 1LL << (FIELD_fmt_idx & 63); + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: 6AE8E838 +int vmov_immediate(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + res->group = INSN_GROUP_NEON; + /* Encoding T2 */ + /* pattern="1110,11101,D.1,11,imm4H.4,Vd.4,101,sz.1,(0),0,(0),0,imm4L.4" width=32 stringency=20 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFFB00E50)==0xEEB00A00)) { + res->instrSize = 32; + if(!((instr & 0xA0)==0x0)) { + res->flags |= FLAG_UNPREDICTABLE; + } + if(!(req->arch & ARCH_VFPv3)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_D] = (instr & 0x400000)>>22; + res->fields_mask[FIELD_D >> 6] |= 1LL << (FIELD_D & 63); + char D_width = 1; + res->fields[FIELD_imm4H] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_imm4H >> 6] |= 1LL << (FIELD_imm4H & 63); + char imm4H_width = 4; + res->fields[FIELD_Vd] = (instr & 0xF000)>>12; + res->fields_mask[FIELD_Vd >> 6] |= 1LL << (FIELD_Vd & 63); + char Vd_width = 4; + res->fields[FIELD_sz] = (instr & 0x100)>>8; + res->fields_mask[FIELD_sz >> 6] |= 1LL << (FIELD_sz & 63); + char sz_width = 1; + res->fields[FIELD_imm4L] = instr & 0xF; + res->fields_mask[FIELD_imm4L >> 6] |= 1LL << (FIELD_imm4L & 63); + char imm4L_width = 4; + + static const instruction_format instr_formats[] = + { + { /* VMOV<c>.F64 <Dd>,#<imm64> */ + "vmov.f64", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_F64, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_IMM64,FIELD_UNINIT,FIELD_UNINIT,"#","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + { /* VMOV<c>.F32 <Sd>,#<imm64> */ + "vmov.f32", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_F32, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"s","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_IMM64,FIELD_UNINIT,FIELD_UNINIT,"#","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 2; + res->mnem = armv7::ARMV7_VMOV; + + /* pcode: single_register = (sz == '0') */ + res->fields[FIELD_single_register] = ((res->fields[FIELD_sz]) == (0x0)); + res->fields_mask[FIELD_single_register >> 6] |= 1LL << (FIELD_single_register & 63); + /* pcode: advsimd = FALSE */ + res->fields[FIELD_advsimd] = 0; + res->fields_mask[FIELD_advsimd >> 6] |= 1LL << (FIELD_advsimd & 63); + /* pcode: d = UInt(D:Vd) */ + res->fields[FIELD_d] = ((res->fields[FIELD_D]<<Vd_width)|(res->fields[FIELD_Vd])); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: imm64h = VFPExpandImm(imm4H:imm4L, 32, 0) */ + res->fields[FIELD_imm64h] = VFPExpandImm((res->fields[FIELD_imm4H]<<imm4L_width)|(res->fields[FIELD_imm4L]), 32, 0); + res->fields_mask[FIELD_imm64h >> 6] |= 1LL << (FIELD_imm64h & 63); + /* pcode: imm64l = VFPExpandImm(imm4H:imm4L, 32, 0) */ + res->fields[FIELD_imm64l] = VFPExpandImm((res->fields[FIELD_imm4H]<<imm4L_width)|(res->fields[FIELD_imm4L]), 32, 0); + res->fields_mask[FIELD_imm64l >> 6] |= 1LL << (FIELD_imm64l & 63); + /* pcode: if single_register then imm64h = 0 */ + if(res->fields[FIELD_single_register]) { + res->fields[FIELD_imm64h] = 0; + res->fields_mask[FIELD_imm64h >> 6] |= 1LL << (FIELD_imm64h & 63); + } + /* pcode: if !single_register then imm64l = 0 */ + if(!(res->fields[FIELD_single_register])) { + res->fields[FIELD_imm64l] = 0; + res->fields_mask[FIELD_imm64l >> 6] |= 1LL << (FIELD_imm64l & 63); + } + /* pcode: if sz == '0' then d = UInt(Vd:D) */ + if((res->fields[FIELD_sz]) == (0x0)) { + res->fields[FIELD_d] = ((res->fields[FIELD_Vd]<<D_width)|(res->fields[FIELD_D])); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + } + /* pcode: fmt_idx = (sz == '0') */ + res->fields[FIELD_fmt_idx] = ((res->fields[FIELD_sz]) == (0x0)); + res->fields_mask[FIELD_fmt_idx >> 6] |= 1LL << (FIELD_fmt_idx & 63); + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* Encoding T1 */ + /* pattern="111,i.1,1111,1,D.1,000,imm3.3,Vd.4,cmode.4,0,Q.1,op.1,1,imm4.4" width=32 stringency=17 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xEFB80090)==0xEF800010)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ADVSIMD)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_i] = (instr & 0x10000000)>>28; + res->fields_mask[FIELD_i >> 6] |= 1LL << (FIELD_i & 63); + char i_width = 1; + res->fields[FIELD_D] = (instr & 0x400000)>>22; + res->fields_mask[FIELD_D >> 6] |= 1LL << (FIELD_D & 63); + char D_width = 1; + res->fields[FIELD_imm3] = (instr & 0x70000)>>16; + res->fields_mask[FIELD_imm3 >> 6] |= 1LL << (FIELD_imm3 & 63); + char imm3_width = 3; + res->fields[FIELD_Vd] = (instr & 0xF000)>>12; + res->fields_mask[FIELD_Vd >> 6] |= 1LL << (FIELD_Vd & 63); + char Vd_width = 4; + res->fields[FIELD_cmode] = (instr & 0xF00)>>8; + res->fields_mask[FIELD_cmode >> 6] |= 1LL << (FIELD_cmode & 63); + char cmode_width = 4; + res->fields[FIELD_Q] = (instr & 0x40)>>6; + res->fields_mask[FIELD_Q >> 6] |= 1LL << (FIELD_Q & 63); + char Q_width = 1; + res->fields[FIELD_op] = (instr & 0x20)>>5; + res->fields_mask[FIELD_op >> 6] |= 1LL << (FIELD_op & 63); + char op_width = 1; + res->fields[FIELD_imm4] = instr & 0xF; + res->fields_mask[FIELD_imm4 >> 6] |= 1LL << (FIELD_imm4 & 63); + char imm4_width = 4; + + static const instruction_format instr_formats[] = + { + { /* VMOV<c>.<dt> <Dd>,#<imm64> */ + "vmov", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_VFP_DATA_SIZE, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_IMM64,FIELD_UNINIT,FIELD_UNINIT,"#","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + { /* VMOV<c>.<dt> <Qd>,#<imm64> */ + "vmov", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_VFP_DATA_SIZE, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"q","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_IMM64,FIELD_UNINIT,FIELD_UNINIT,"#","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 2; + res->mnem = armv7::ARMV7_VMOV; + + /* pcode: if (op == '1' && cmode != '1110') then SEE advsimd_one_reg_mod_imm */ + if((((res->fields[FIELD_op]) == (0x1)) && ((res->fields[FIELD_cmode]) != (0xE)))) { + + return advsimd_one_reg_mod_imm(req, res); + } + /* pcode: if (Q == '1' && Vd<0> == '1') then UNDEFINED */ + if((((res->fields[FIELD_Q]) == (0x1)) && (((res->fields[FIELD_Vd] & 1)) == (0x1)))) { + res->status |= STATUS_UNDEFINED; + } + /* pcode: single_register = FALSE */ + res->fields[FIELD_single_register] = 0; + res->fields_mask[FIELD_single_register >> 6] |= 1LL << (FIELD_single_register & 63); + /* pcode: advsimd = TRUE */ + res->fields[FIELD_advsimd] = 1; + res->fields_mask[FIELD_advsimd >> 6] |= 1LL << (FIELD_advsimd & 63); + /* pcode: d = UInt(D:Vd) */ + res->fields[FIELD_d] = ((res->fields[FIELD_D]<<Vd_width)|(res->fields[FIELD_Vd])); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: regs = if Q == '0' then 1 else 2 */ + if((res->fields[FIELD_Q]) == (0x0)) { + res->fields[FIELD_regs] = 1; + res->fields_mask[FIELD_regs >> 6] |= 1LL << (FIELD_regs & 63); + } + else { + res->fields[FIELD_regs] = 2; + res->fields_mask[FIELD_regs >> 6] |= 1LL << (FIELD_regs & 63); + } + /* pcode: imm64l = AdvSIMDExpandImm(op, cmode, i:imm3:imm4, 1) */ + res->fields[FIELD_imm64l] = AdvSIMDExpandImm(res->fields[FIELD_op], res->fields[FIELD_cmode], (res->fields[FIELD_i]<<(4+3))|(res->fields[FIELD_imm3]<<4)|(res->fields[FIELD_imm4]), 1); + res->fields_mask[FIELD_imm64l >> 6] |= 1LL << (FIELD_imm64l & 63); + /* pcode: imm64h = AdvSIMDExpandImm(op, cmode, i:imm3:imm4, 0) */ + res->fields[FIELD_imm64h] = AdvSIMDExpandImm(res->fields[FIELD_op], res->fields[FIELD_cmode], (res->fields[FIELD_i]<<(4+3))|(res->fields[FIELD_imm3]<<4)|(res->fields[FIELD_imm4]), 0); + res->fields_mask[FIELD_imm64h >> 6] |= 1LL << (FIELD_imm64h & 63); + /* pcode: fmt_idx = (Q == '1') */ + res->fields[FIELD_fmt_idx] = ((res->fields[FIELD_Q]) == (0x1)); + res->fields_mask[FIELD_fmt_idx >> 6] |= 1LL << (FIELD_fmt_idx & 63); + /* pcode: dt = UInt(imm3:i) */ + res->fields[FIELD_dt] = ((res->fields[FIELD_imm3]<<i_width)|(res->fields[FIELD_i])); + res->fields_mask[FIELD_dt >> 6] |= 1LL << (FIELD_dt & 63); + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: C892CBCF +int vmov_register(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + res->group = INSN_GROUP_NEON; + /* Encoding T2 */ + /* pattern="1110,11101,D.1,11,0000,Vd.4,101,sz.1,0,1,M.1,0,Vm.4" width=32 stringency=24 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFFBF0ED0)==0xEEB00A40)) { + res->instrSize = 32; + if(!(req->arch & ARCH_VFPv3)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_D] = (instr & 0x400000)>>22; + res->fields_mask[FIELD_D >> 6] |= 1LL << (FIELD_D & 63); + char D_width = 1; + res->fields[FIELD_Vd] = (instr & 0xF000)>>12; + res->fields_mask[FIELD_Vd >> 6] |= 1LL << (FIELD_Vd & 63); + char Vd_width = 4; + res->fields[FIELD_sz] = (instr & 0x100)>>8; + res->fields_mask[FIELD_sz >> 6] |= 1LL << (FIELD_sz & 63); + char sz_width = 1; + res->fields[FIELD_M] = (instr & 0x20)>>5; + res->fields_mask[FIELD_M >> 6] |= 1LL << (FIELD_M & 63); + char M_width = 1; + res->fields[FIELD_Vm] = instr & 0xF; + res->fields_mask[FIELD_Vm >> 6] |= 1LL << (FIELD_Vm & 63); + char Vm_width = 4; + + static const instruction_format instr_formats[] = + { + { /* VMOV<c>.F64 <Dd>,<Dm> */ + "vmov.f64", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_F64, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_m,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + { /* VMOV<c>.F32 <Sd>,<Sm> */ + "vmov.f32", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_F32, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"s","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_m,FIELD_UNINIT,"s","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 2; + res->mnem = armv7::ARMV7_VMOV; + + /* pcode: single_register = (sz == '0') */ + res->fields[FIELD_single_register] = ((res->fields[FIELD_sz]) == (0x0)); + res->fields_mask[FIELD_single_register >> 6] |= 1LL << (FIELD_single_register & 63); + /* pcode: advsimd = FALSE */ + res->fields[FIELD_advsimd] = 0; + res->fields_mask[FIELD_advsimd >> 6] |= 1LL << (FIELD_advsimd & 63); + /* pcode: d = UInt(D:Vd) */ + res->fields[FIELD_d] = ((res->fields[FIELD_D]<<Vd_width)|(res->fields[FIELD_Vd])); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: m = UInt(M:Vm) */ + res->fields[FIELD_m] = ((res->fields[FIELD_M]<<Vm_width)|(res->fields[FIELD_Vm])); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + /* pcode: if sz == '0' then d = UInt(Vd:D) */ + if((res->fields[FIELD_sz]) == (0x0)) { + res->fields[FIELD_d] = ((res->fields[FIELD_Vd]<<D_width)|(res->fields[FIELD_D])); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + } + /* pcode: if sz == '0' then m = UInt(Vm:M) */ + if((res->fields[FIELD_sz]) == (0x0)) { + res->fields[FIELD_m] = ((res->fields[FIELD_Vm]<<M_width)|(res->fields[FIELD_M])); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + } + /* pcode: fmt_idx = (sz == '0') */ + res->fields[FIELD_fmt_idx] = ((res->fields[FIELD_sz]) == (0x0)); + res->fields_mask[FIELD_fmt_idx >> 6] |= 1LL << (FIELD_fmt_idx & 63); + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* Encoding T1 */ + /* pattern="1110,1111,0,D.1,10,Vm.4,Vd.4,0001,M.1,Q.1,M.1,1,Vm.4" width=32 stringency=20 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFFB00F10)==0xEF200110)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ADVSIMD)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_D] = (instr & 0x400000)>>22; + res->fields_mask[FIELD_D >> 6] |= 1LL << (FIELD_D & 63); + char D_width = 1; + res->fields[FIELD_Vm] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Vm >> 6] |= 1LL << (FIELD_Vm & 63); + char Vm_width = 4; + res->fields[FIELD_Vd] = (instr & 0xF000)>>12; + res->fields_mask[FIELD_Vd >> 6] |= 1LL << (FIELD_Vd & 63); + char Vd_width = 4; + res->fields[FIELD_M] = (instr & 0x80)>>7; + res->fields_mask[FIELD_M >> 6] |= 1LL << (FIELD_M & 63); + char M_width = 1; + res->fields[FIELD_Q] = (instr & 0x40)>>6; + res->fields_mask[FIELD_Q >> 6] |= 1LL << (FIELD_Q & 63); + char Q_width = 1; + res->fields[FIELD_M_check] = (instr & 0x20)>>5; + res->fields_mask[FIELD_M_check >> 6] |= 1LL << (FIELD_M_check & 63); + char M_check_width = 1; + res->fields[FIELD_Vm_check] = instr & 0xF; + res->fields_mask[FIELD_Vm_check >> 6] |= 1LL << (FIELD_Vm_check & 63); + char Vm_check_width = 4; + + static const instruction_format instr_formats[] = + { + { /* VMOV<c> <Dd>,<Dm> */ + "vmov", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_m,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + { /* VMOV<c> <Qd>,<Qm> */ + "vmov", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"q","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_m,FIELD_UNINIT,"q","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 2; + res->mnem = armv7::ARMV7_VMOV; + + /* pcode: if (!Consistent(M) || !Consistent(Vm)) then SEE vorr_register */ + if((!(((res->fields[FIELD_M] == res->fields[FIELD_M_check])) || (!((res->fields[FIELD_Vm] == res->fields[FIELD_Vm_check])))))) { + + return vorr_register(req, res); + } + /* pcode: if (Q == '1' && (Vd<0> == '1' || Vm<0> == '1')) then UNDEFINED */ + if((((res->fields[FIELD_Q]) == (0x1)) && (((((res->fields[FIELD_Vd] & 1)) == (0x1)) || (((res->fields[FIELD_Vm] & 1)) == (0x1)))))) { + res->status |= STATUS_UNDEFINED; + } + /* pcode: single_register = FALSE */ + res->fields[FIELD_single_register] = 0; + res->fields_mask[FIELD_single_register >> 6] |= 1LL << (FIELD_single_register & 63); + /* pcode: advsimd = TRUE */ + res->fields[FIELD_advsimd] = 1; + res->fields_mask[FIELD_advsimd >> 6] |= 1LL << (FIELD_advsimd & 63); + /* pcode: d = UInt(D:Vd) */ + res->fields[FIELD_d] = ((res->fields[FIELD_D]<<Vd_width)|(res->fields[FIELD_Vd])); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: m = UInt(M:Vm) */ + res->fields[FIELD_m] = ((res->fields[FIELD_M]<<Vm_width)|(res->fields[FIELD_Vm])); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + /* pcode: regs = if Q == '0' then 1 else 2 */ + if((res->fields[FIELD_Q]) == (0x0)) { + res->fields[FIELD_regs] = 1; + res->fields_mask[FIELD_regs >> 6] |= 1LL << (FIELD_regs & 63); + } + else { + res->fields[FIELD_regs] = 2; + res->fields_mask[FIELD_regs >> 6] |= 1LL << (FIELD_regs & 63); + } + /* pcode: fmt_idx = (Q == '1') */ + res->fields[FIELD_fmt_idx] = ((res->fields[FIELD_Q]) == (0x1)); + res->fields_mask[FIELD_fmt_idx >> 6] |= 1LL << (FIELD_fmt_idx & 63); + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: 74B676B6 +int vmov_scalar_core(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + res->group = INSN_GROUP_NEON; + /* Encoding T1 */ + /* pattern="1110,1110,U.1,opc1.2,1,Vn.4,Rt.4,1011,N.1,opc2.2,1,(0)(0)(0)(0)" width=32 stringency=21 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFF100F10)==0xEE100B10)) { + res->instrSize = 32; + if(!((instr & 0xF)==0x0)) { + res->flags |= FLAG_UNPREDICTABLE; + } + if(!(req->arch & ARCH_ADVSIMD)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_U] = (instr & 0x800000)>>23; + res->fields_mask[FIELD_U >> 6] |= 1LL << (FIELD_U & 63); + char U_width = 1; + res->fields[FIELD_opc1] = (instr & 0x600000)>>21; + res->fields_mask[FIELD_opc1 >> 6] |= 1LL << (FIELD_opc1 & 63); + char opc1_width = 2; + res->fields[FIELD_Vn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Vn >> 6] |= 1LL << (FIELD_Vn & 63); + char Vn_width = 4; + res->fields[FIELD_Rt] = (instr & 0xF000)>>12; + res->fields_mask[FIELD_Rt >> 6] |= 1LL << (FIELD_Rt & 63); + char Rt_width = 4; + res->fields[FIELD_N] = (instr & 0x80)>>7; + res->fields_mask[FIELD_N >> 6] |= 1LL << (FIELD_N & 63); + char N_width = 1; + res->fields[FIELD_opc2] = (instr & 0x60)>>5; + res->fields_mask[FIELD_opc2 >> 6] |= 1LL << (FIELD_opc2 & 63); + char opc2_width = 2; + + static const instruction_format instr_formats[] = + { + { /* VMOV<c>.<dt> <Rt>,<Dn[x]> */ + "vmov", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_VFP_DATA_SIZE, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rt,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG_INDEX,FIELD_n,FIELD_x,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_VMOV; + + /* pcode: if (U == '1' && UInt(opc1) < 2 && opc2 == '00') then UNDEFINED */ + if(((((res->fields[FIELD_U]) == (0x1)) && (((res->fields[FIELD_opc1])) < (2))) && ((res->fields[FIELD_opc2]) == (0x0)))) { + res->status |= STATUS_UNDEFINED; + } + /* pcode: if (opc2 == '10' && UInt(opc1) < 2) then UNDEFINED */ + if((((res->fields[FIELD_opc2]) == (0x2)) && (((res->fields[FIELD_opc1])) < (2)))) { + res->status |= STATUS_UNDEFINED; + } + /* pcode: esize = 32 */ + res->fields[FIELD_esize] = 32; + res->fields_mask[FIELD_esize >> 6] |= 1LL << (FIELD_esize & 63); + /* pcode: if UInt(opc1) >= 2 then esize = 8 */ + if(((res->fields[FIELD_opc1])) >= (2)) { + res->fields[FIELD_esize] = 8; + res->fields_mask[FIELD_esize >> 6] |= 1LL << (FIELD_esize & 63); + } + /* pcode: if (UInt(opc1) < 2 && UInt(opc2) >= 1) then esize = 16 */ + if(((((res->fields[FIELD_opc1])) < (2)) && (((res->fields[FIELD_opc2])) >= (1)))) { + res->fields[FIELD_esize] = 16; + res->fields_mask[FIELD_esize >> 6] |= 1LL << (FIELD_esize & 63); + } + /* pcode: if esize == 8 then x = (UInt(opc1:opc2)) - 8 */ + if((res->fields[FIELD_esize]) == (8)) { + res->fields[FIELD_x] = ((((res->fields[FIELD_opc1]<<2)|(res->fields[FIELD_opc2])))) - (8); + res->fields_mask[FIELD_x >> 6] |= 1LL << (FIELD_x & 63); + } + /* pcode: if esize == 16 then x = (UInt(opc1:opc2) >> 1) */ + if((res->fields[FIELD_esize]) == (16)) { + res->fields[FIELD_x] = ((((res->fields[FIELD_opc1]<<2)|(res->fields[FIELD_opc2]))) >> (1)); + res->fields_mask[FIELD_x >> 6] |= 1LL << (FIELD_x & 63); + } + /* pcode: if esize == 32 then x = UInt(opc1) */ + if((res->fields[FIELD_esize]) == (32)) { + res->fields[FIELD_x] = (res->fields[FIELD_opc1]); + res->fields_mask[FIELD_x >> 6] |= 1LL << (FIELD_x & 63); + } + /* pcode: t = UInt(Rt) */ + res->fields[FIELD_t] = (res->fields[FIELD_Rt]); + res->fields_mask[FIELD_t >> 6] |= 1LL << (FIELD_t & 63); + /* pcode: n = UInt(N:Vn) */ + res->fields[FIELD_n] = ((res->fields[FIELD_N]<<Vn_width)|(res->fields[FIELD_Vn])); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: unsigned = (U == '1') */ + res->fields[FIELD_unsigned] = ((res->fields[FIELD_U]) == (0x1)); + res->fields_mask[FIELD_unsigned >> 6] |= 1LL << (FIELD_unsigned & 63); + /* pcode: dt = 11 */ + res->fields[FIELD_dt] = 11; + res->fields_mask[FIELD_dt >> 6] |= 1LL << (FIELD_dt & 63); + /* pcode: if (U == '0' && esize == 8) then dt = 0 */ + if((((res->fields[FIELD_U]) == (0x0)) && ((res->fields[FIELD_esize]) == (8)))) { + res->fields[FIELD_dt] = 0; + res->fields_mask[FIELD_dt >> 6] |= 1LL << (FIELD_dt & 63); + } + /* pcode: if (U == '0' && esize == 16) then dt = 1 */ + if((((res->fields[FIELD_U]) == (0x0)) && ((res->fields[FIELD_esize]) == (16)))) { + res->fields[FIELD_dt] = 1; + res->fields_mask[FIELD_dt >> 6] |= 1LL << (FIELD_dt & 63); + } + /* pcode: if (U == '1' && esize == 8) then dt = 4 */ + if((((res->fields[FIELD_U]) == (0x1)) && ((res->fields[FIELD_esize]) == (8)))) { + res->fields[FIELD_dt] = 4; + res->fields_mask[FIELD_dt >> 6] |= 1LL << (FIELD_dt & 63); + } + /* pcode: if (U == '1' && esize == 16) then dt = 5 */ + if((((res->fields[FIELD_U]) == (0x1)) && ((res->fields[FIELD_esize]) == (16)))) { + res->fields[FIELD_dt] = 5; + res->fields_mask[FIELD_dt >> 6] |= 1LL << (FIELD_dt & 63); + } + /* pcode: if (U == '0' && esize == 32) then dt = 8 */ + if((((res->fields[FIELD_U]) == (0x0)) && ((res->fields[FIELD_esize]) == (32)))) { + res->fields[FIELD_dt] = 8; + res->fields_mask[FIELD_dt >> 6] |= 1LL << (FIELD_dt & 63); + } + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: 8E858F6E +int vmovl(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + res->group = INSN_GROUP_NEON; + /* Encoding T1 */ + /* pattern="111,U.1,xx11,1,D.1,imm3.3,000,Vd.4,1010,0,0,M.1,1,Vm.4" width=32 stringency=19 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xE3870FD0)==0xE3800A10)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ADVSIMD)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_U] = (instr & 0x10000000)>>28; + res->fields_mask[FIELD_U >> 6] |= 1LL << (FIELD_U & 63); + char U_width = 1; + res->fields[FIELD_D] = (instr & 0x400000)>>22; + res->fields_mask[FIELD_D >> 6] |= 1LL << (FIELD_D & 63); + char D_width = 1; + res->fields[FIELD_imm3] = (instr & 0x380000)>>19; + res->fields_mask[FIELD_imm3 >> 6] |= 1LL << (FIELD_imm3 & 63); + char imm3_width = 3; + res->fields[FIELD_Vd] = (instr & 0xF000)>>12; + res->fields_mask[FIELD_Vd >> 6] |= 1LL << (FIELD_Vd & 63); + char Vd_width = 4; + res->fields[FIELD_M] = (instr & 0x20)>>5; + res->fields_mask[FIELD_M >> 6] |= 1LL << (FIELD_M & 63); + char M_width = 1; + res->fields[FIELD_Vm] = instr & 0xF; + res->fields_mask[FIELD_Vm >> 6] |= 1LL << (FIELD_Vm & 63); + char Vm_width = 4; + + static const instruction_format instr_formats[] = + { + { /* VMOVL<c>.<dt> <Qd>,<Dm> */ + "vmovl", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_VFP_DATA_SIZE, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"q","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_m,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_VMOVL; + + /* pcode: if imm3 == '000' then SEE advsimd_one_reg_mod_imm */ + if((res->fields[FIELD_imm3]) == (0x0)) { + + return advsimd_one_reg_mod_imm(req, res); + } + /* pcode: if ((imm3 != '001') && (imm3 != '010') && (imm3 != '100')) then SEE vshll */ + if((((((res->fields[FIELD_imm3]) != (0x1))) && (((res->fields[FIELD_imm3]) != (0x2)))) && (((res->fields[FIELD_imm3]) != (0x4))))) { + + return vshll(req, res); + } + /* pcode: if Vd<0> == '1' then UNDEFINED */ + if(((res->fields[FIELD_Vd] & 1)) == (0x1)) { + res->status |= STATUS_UNDEFINED; + } + /* pcode: esize = 8 * UInt(imm3) */ + res->fields[FIELD_esize] = (8) * ((res->fields[FIELD_imm3])); + res->fields_mask[FIELD_esize >> 6] |= 1LL << (FIELD_esize & 63); + /* pcode: unsigned = (U == '1') */ + res->fields[FIELD_unsigned] = ((res->fields[FIELD_U]) == (0x1)); + res->fields_mask[FIELD_unsigned >> 6] |= 1LL << (FIELD_unsigned & 63); + /* pcode: elements = 64 DIV esize */ + res->fields[FIELD_elements] = ((res->fields[FIELD_esize]) ? ((64) / (res->fields[FIELD_esize])) : 0); + res->fields_mask[FIELD_elements >> 6] |= 1LL << (FIELD_elements & 63); + /* pcode: d = UInt(D:Vd) */ + res->fields[FIELD_d] = ((res->fields[FIELD_D]<<Vd_width)|(res->fields[FIELD_Vd])); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: m = UInt(M:Vm) */ + res->fields[FIELD_m] = ((res->fields[FIELD_M]<<Vm_width)|(res->fields[FIELD_Vm])); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + /* pcode: unsigned = TRUE */ + res->fields[FIELD_unsigned] = 1; + res->fields_mask[FIELD_unsigned >> 6] |= 1LL << (FIELD_unsigned & 63); + /* pcode: dt = UInt(U:imm3) */ + res->fields[FIELD_dt] = ((res->fields[FIELD_U]<<3)|(res->fields[FIELD_imm3])); + res->fields_mask[FIELD_dt >> 6] |= 1LL << (FIELD_dt & 63); + /* pcode: dt = dt DIV 2 */ + res->fields[FIELD_dt] = ((2) ? ((res->fields[FIELD_dt]) / (2)) : 0); + res->fields_mask[FIELD_dt >> 6] |= 1LL << (FIELD_dt & 63); + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: 24E3ADE8 +int vmovn(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + res->group = INSN_GROUP_NEON; + /* Encoding T1 */ + /* pattern="1111,xx11,1,D.1,11,size.2,10,Vd.4,0,01000,M.1,0,Vm.4" width=32 stringency=20 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xF3B30FD0)==0xF3B20200)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ADVSIMD)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_D] = (instr & 0x400000)>>22; + res->fields_mask[FIELD_D >> 6] |= 1LL << (FIELD_D & 63); + char D_width = 1; + res->fields[FIELD_size] = (instr & 0xC0000)>>18; + res->fields_mask[FIELD_size >> 6] |= 1LL << (FIELD_size & 63); + char size_width = 2; + res->fields[FIELD_Vd] = (instr & 0xF000)>>12; + res->fields_mask[FIELD_Vd >> 6] |= 1LL << (FIELD_Vd & 63); + char Vd_width = 4; + res->fields[FIELD_M] = (instr & 0x20)>>5; + res->fields_mask[FIELD_M >> 6] |= 1LL << (FIELD_M & 63); + char M_width = 1; + res->fields[FIELD_Vm] = instr & 0xF; + res->fields_mask[FIELD_Vm >> 6] |= 1LL << (FIELD_Vm & 63); + char Vm_width = 4; + + static const instruction_format instr_formats[] = + { + { /* VMOVN<c>.<dt> <Dd>,<Qm> */ + "vmovn", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_VFP_DATA_SIZE, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_m,FIELD_UNINIT,"q","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_VMOVN; + + /* pcode: if size == '11' then UNDEFINED */ + if((res->fields[FIELD_size]) == (0x3)) { + res->status |= STATUS_UNDEFINED; + } + /* pcode: if Vm<0> == '1' then UNDEFINED */ + if(((res->fields[FIELD_Vm] & 1)) == (0x1)) { + res->status |= STATUS_UNDEFINED; + } + /* pcode: esize = 8 << UInt(size) */ + res->fields[FIELD_esize] = (8) << ((res->fields[FIELD_size])); + res->fields_mask[FIELD_esize >> 6] |= 1LL << (FIELD_esize & 63); + /* pcode: elements = 64 DIV esize */ + res->fields[FIELD_elements] = ((res->fields[FIELD_esize]) ? ((64) / (res->fields[FIELD_esize])) : 0); + res->fields_mask[FIELD_elements >> 6] |= 1LL << (FIELD_elements & 63); + /* pcode: d = UInt(D:Vd) */ + res->fields[FIELD_d] = ((res->fields[FIELD_D]<<Vd_width)|(res->fields[FIELD_Vd])); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: m = UInt(M:Vm) */ + res->fields[FIELD_m] = ((res->fields[FIELD_M]<<Vm_width)|(res->fields[FIELD_Vm])); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + /* pcode: iword = TRUE */ + res->fields[FIELD_iword] = 1; + res->fields_mask[FIELD_iword >> 6] |= 1LL << (FIELD_iword & 63); + /* pcode: dt = size + 1 */ + res->fields[FIELD_dt] = (res->fields[FIELD_size]) + (1); + res->fields_mask[FIELD_dt >> 6] |= 1LL << (FIELD_dt & 63); + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: 83C6FDAF +int vmrs(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + res->group = INSN_GROUP_NEON; + /* Encoding T1 */ + /* pattern="1110,11101111,FPSCR.4,Rt.4,1010,(0),(0)(0),1,(0)(0)(0)(0)" width=32 stringency=24 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFFF00F10)==0xEEF00A10)) { + res->instrSize = 32; + if(!((instr & 0xEF)==0x0)) { + res->flags |= FLAG_UNPREDICTABLE; + } + if(!(req->arch & ARCH_ADVSIMD)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_FPSCR] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_FPSCR >> 6] |= 1LL << (FIELD_FPSCR & 63); + char FPSCR_width = 4; + res->fields[FIELD_Rt] = (instr & 0xF000)>>12; + res->fields_mask[FIELD_Rt >> 6] |= 1LL << (FIELD_Rt & 63); + char Rt_width = 4; + + static const instruction_format instr_formats[] = + { + { /* VMRS<c> <Rt>,<fpscr> */ + "vmrs", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rt,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_FPSCR,FIELD_FPSCR,FIELD_UNINIT,"","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + { /* VMRS<c> <Rt_mrc>,<fpscr> */ + "vmrs", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_RT_MRC,FIELD_Rt_mrc,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_FPSCR,FIELD_FPSCR,FIELD_UNINIT,"","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 2; + res->mnem = armv7::ARMV7_VMRS; + + /* pcode: t = UInt(Rt) */ + res->fields[FIELD_t] = (res->fields[FIELD_Rt]); + res->fields_mask[FIELD_t >> 6] |= 1LL << (FIELD_t & 63); + /* pcode: if t == 13 then UNPREDICTABLE */ + if((res->fields[FIELD_t]) == (13)) { + res->flags |= FLAG_UNPREDICTABLE; + } + /* pcode: Rt_mrc = Rt */ + res->fields[FIELD_Rt_mrc] = res->fields[FIELD_Rt]; + res->fields_mask[FIELD_Rt_mrc >> 6] |= 1LL << (FIELD_Rt_mrc & 63); + /* pcode: fmt_idx = (Rt == '1111') */ + res->fields[FIELD_fmt_idx] = ((res->fields[FIELD_Rt]) == (0xF)); + res->fields_mask[FIELD_fmt_idx >> 6] |= 1LL << (FIELD_fmt_idx & 63); + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: 83988C51 +int vmsr(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + res->group = INSN_GROUP_NEON; + /* Encoding T1 */ + /* pattern="1110,11101110,FPSCR.4,Rt.4,1010,(0),(0)(0),1,(0)(0)(0)(0)" width=32 stringency=24 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFFF00F10)==0xEEE00A10)) { + res->instrSize = 32; + if(!((instr & 0xEF)==0x0)) { + res->flags |= FLAG_UNPREDICTABLE; + } + if(!(req->arch & ARCH_ADVSIMD)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_FPSCR] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_FPSCR >> 6] |= 1LL << (FIELD_FPSCR & 63); + char FPSCR_width = 4; + res->fields[FIELD_Rt] = (instr & 0xF000)>>12; + res->fields_mask[FIELD_Rt >> 6] |= 1LL << (FIELD_Rt & 63); + char Rt_width = 4; + + static const instruction_format instr_formats[] = + { + { /* VMSR<c> <fpscr>,<Rt> */ + "vmsr", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_FPSCR,FIELD_FPSCR,FIELD_UNINIT,"","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG,FIELD_Rt,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_VMSR; + + /* pcode: t = UInt(Rt) */ + res->fields[FIELD_t] = (res->fields[FIELD_Rt]); + res->fields_mask[FIELD_t >> 6] |= 1LL << (FIELD_t & 63); + /* pcode: if (t == 15 || t == 13) then UNPREDICTABLE */ + if((((res->fields[FIELD_t]) == (15)) || ((res->fields[FIELD_t]) == (13)))) { + res->flags |= FLAG_UNPREDICTABLE; + } + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: F5A07C57 +int vmul_float(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + res->group = INSN_GROUP_NEON; + /* Encoding T2 */ + /* pattern="1110,11100,D.1,10,Vn.4,Vd.4,101,sz.1,N.1,0,M.1,0,Vm.4" width=32 stringency=20 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFFB00E50)==0xEE200A00)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ADVSIMD)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_D] = (instr & 0x400000)>>22; + res->fields_mask[FIELD_D >> 6] |= 1LL << (FIELD_D & 63); + char D_width = 1; + res->fields[FIELD_Vn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Vn >> 6] |= 1LL << (FIELD_Vn & 63); + char Vn_width = 4; + res->fields[FIELD_Vd] = (instr & 0xF000)>>12; + res->fields_mask[FIELD_Vd >> 6] |= 1LL << (FIELD_Vd & 63); + char Vd_width = 4; + res->fields[FIELD_sz] = (instr & 0x100)>>8; + res->fields_mask[FIELD_sz >> 6] |= 1LL << (FIELD_sz & 63); + char sz_width = 1; + res->fields[FIELD_N] = (instr & 0x80)>>7; + res->fields_mask[FIELD_N >> 6] |= 1LL << (FIELD_N & 63); + char N_width = 1; + res->fields[FIELD_M] = (instr & 0x20)>>5; + res->fields_mask[FIELD_M >> 6] |= 1LL << (FIELD_M & 63); + char M_width = 1; + res->fields[FIELD_Vm] = instr & 0xF; + res->fields_mask[FIELD_Vm >> 6] |= 1LL << (FIELD_Vm & 63); + char Vm_width = 4; + + static const instruction_format instr_formats[] = + { + { /* VMUL<c>.F32 <Sd>,<Sn>,<Sm> */ + "vmul.f32", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_F32, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"s","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_n,FIELD_UNINIT,"s","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_m,FIELD_UNINIT,"s","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + { /* VMUL<c>.F64 <Dd>,<Dn>,<Dm> */ + "vmul.f64", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_F64, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_n,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_m,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 2; + res->mnem = armv7::ARMV7_VMUL; + + /* pcode: advsimd = FALSE */ + res->fields[FIELD_advsimd] = 0; + res->fields_mask[FIELD_advsimd >> 6] |= 1LL << (FIELD_advsimd & 63); + /* pcode: dp_operation = (sz == '1') */ + res->fields[FIELD_dp_operation] = ((res->fields[FIELD_sz]) == (0x1)); + res->fields_mask[FIELD_dp_operation >> 6] |= 1LL << (FIELD_dp_operation & 63); + /* pcode: d = if dp_operation then UInt(D:Vd) else UInt(Vd:D) */ + if(res->fields[FIELD_dp_operation]) { + res->fields[FIELD_d] = ((res->fields[FIELD_D]<<Vd_width)|(res->fields[FIELD_Vd])); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + } + else { + res->fields[FIELD_d] = ((res->fields[FIELD_Vd]<<D_width)|(res->fields[FIELD_D])); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + } + /* pcode: n = if dp_operation then UInt(N:Vn) else UInt(Vn:N) */ + if(res->fields[FIELD_dp_operation]) { + res->fields[FIELD_n] = ((res->fields[FIELD_N]<<Vn_width)|(res->fields[FIELD_Vn])); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + } + else { + res->fields[FIELD_n] = ((res->fields[FIELD_Vn]<<N_width)|(res->fields[FIELD_N])); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + } + /* pcode: m = if dp_operation then UInt(M:Vm) else UInt(Vm:M) */ + if(res->fields[FIELD_dp_operation]) { + res->fields[FIELD_m] = ((res->fields[FIELD_M]<<Vm_width)|(res->fields[FIELD_Vm])); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + } + else { + res->fields[FIELD_m] = ((res->fields[FIELD_Vm]<<M_width)|(res->fields[FIELD_M])); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + } + /* pcode: fmt_idx = dp_operation */ + res->fields[FIELD_fmt_idx] = res->fields[FIELD_dp_operation]; + res->fields_mask[FIELD_fmt_idx >> 6] |= 1LL << (FIELD_fmt_idx & 63); + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* Encoding T1 */ + /* pattern="1111,xx11,0,D.1,0,sz.1,Vn.4,Vd.4,1101,N.1,Q.1,M.1,1,Vm.4" width=32 stringency=18 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xF3A00F10)==0xF3000D10)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ADVSIMD)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_D] = (instr & 0x400000)>>22; + res->fields_mask[FIELD_D >> 6] |= 1LL << (FIELD_D & 63); + char D_width = 1; + res->fields[FIELD_sz] = (instr & 0x100000)>>20; + res->fields_mask[FIELD_sz >> 6] |= 1LL << (FIELD_sz & 63); + char sz_width = 1; + res->fields[FIELD_Vn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Vn >> 6] |= 1LL << (FIELD_Vn & 63); + char Vn_width = 4; + res->fields[FIELD_Vd] = (instr & 0xF000)>>12; + res->fields_mask[FIELD_Vd >> 6] |= 1LL << (FIELD_Vd & 63); + char Vd_width = 4; + res->fields[FIELD_N] = (instr & 0x80)>>7; + res->fields_mask[FIELD_N >> 6] |= 1LL << (FIELD_N & 63); + char N_width = 1; + res->fields[FIELD_Q] = (instr & 0x40)>>6; + res->fields_mask[FIELD_Q >> 6] |= 1LL << (FIELD_Q & 63); + char Q_width = 1; + res->fields[FIELD_M] = (instr & 0x20)>>5; + res->fields_mask[FIELD_M >> 6] |= 1LL << (FIELD_M & 63); + char M_width = 1; + res->fields[FIELD_Vm] = instr & 0xF; + res->fields_mask[FIELD_Vm >> 6] |= 1LL << (FIELD_Vm & 63); + char Vm_width = 4; + + static const instruction_format instr_formats[] = + { + { /* VMUL<c>.F32 <Dd>,<Dn>,<Dm> */ + "vmul.f32", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_F32, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_n,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_m,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + { /* VMUL<c>.F32 <Qd>,<Qn>,<Qm> */ + "vmul.f32", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_F32, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"q","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_n,FIELD_UNINIT,"q","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_m,FIELD_UNINIT,"q","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 2; + res->mnem = armv7::ARMV7_VMUL; + + /* pcode: if (Q == '1' && (Vd<0> == '1' || Vn<0> == '1' || Vm<0> == '1')) then UNDEFINED */ + if((((res->fields[FIELD_Q]) == (0x1)) && ((((((res->fields[FIELD_Vd] & 1)) == (0x1)) || (((res->fields[FIELD_Vn] & 1)) == (0x1))) || (((res->fields[FIELD_Vm] & 1)) == (0x1)))))) { + res->status |= STATUS_UNDEFINED; + } + /* pcode: if sz == '1' then UNDEFINED */ + if((res->fields[FIELD_sz]) == (0x1)) { + res->status |= STATUS_UNDEFINED; + } + /* pcode: advsimd = TRUE */ + res->fields[FIELD_advsimd] = 1; + res->fields_mask[FIELD_advsimd >> 6] |= 1LL << (FIELD_advsimd & 63); + /* pcode: esize = 32 */ + res->fields[FIELD_esize] = 32; + res->fields_mask[FIELD_esize >> 6] |= 1LL << (FIELD_esize & 63); + /* pcode: elements = 2 */ + res->fields[FIELD_elements] = 2; + res->fields_mask[FIELD_elements >> 6] |= 1LL << (FIELD_elements & 63); + /* pcode: d = UInt(D:Vd) */ + res->fields[FIELD_d] = ((res->fields[FIELD_D]<<Vd_width)|(res->fields[FIELD_Vd])); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: n = UInt(N:Vn) */ + res->fields[FIELD_n] = ((res->fields[FIELD_N]<<Vn_width)|(res->fields[FIELD_Vn])); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: m = UInt(M:Vm) */ + res->fields[FIELD_m] = ((res->fields[FIELD_M]<<Vm_width)|(res->fields[FIELD_Vm])); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + /* pcode: regs = if Q == '0' then 1 else 2 */ + if((res->fields[FIELD_Q]) == (0x0)) { + res->fields[FIELD_regs] = 1; + res->fields_mask[FIELD_regs >> 6] |= 1LL << (FIELD_regs & 63); + } + else { + res->fields[FIELD_regs] = 2; + res->fields_mask[FIELD_regs >> 6] |= 1LL << (FIELD_regs & 63); + } + /* pcode: fmt_idx = (Q == '1') */ + res->fields[FIELD_fmt_idx] = ((res->fields[FIELD_Q]) == (0x1)); + res->fields_mask[FIELD_fmt_idx >> 6] |= 1LL << (FIELD_fmt_idx & 63); + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: A5D959D0 +int vmul_integer(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + res->group = INSN_GROUP_NEON; + /* Encoding T3 */ + /* pattern="111,1,1111,0,D.1,size.2,Vn.4,Vd.4,1001,N.1,Q.1,M.1,1,Vm.4" width=32 stringency=18 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFF800F10)==0xFF000910)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ADVSIMD)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_D] = (instr & 0x400000)>>22; + res->fields_mask[FIELD_D >> 6] |= 1LL << (FIELD_D & 63); + char D_width = 1; + res->fields[FIELD_size] = (instr & 0x300000)>>20; + res->fields_mask[FIELD_size >> 6] |= 1LL << (FIELD_size & 63); + char size_width = 2; + res->fields[FIELD_Vn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Vn >> 6] |= 1LL << (FIELD_Vn & 63); + char Vn_width = 4; + res->fields[FIELD_Vd] = (instr & 0xF000)>>12; + res->fields_mask[FIELD_Vd >> 6] |= 1LL << (FIELD_Vd & 63); + char Vd_width = 4; + res->fields[FIELD_N] = (instr & 0x80)>>7; + res->fields_mask[FIELD_N >> 6] |= 1LL << (FIELD_N & 63); + char N_width = 1; + res->fields[FIELD_Q] = (instr & 0x40)>>6; + res->fields_mask[FIELD_Q >> 6] |= 1LL << (FIELD_Q & 63); + char Q_width = 1; + res->fields[FIELD_M] = (instr & 0x20)>>5; + res->fields_mask[FIELD_M >> 6] |= 1LL << (FIELD_M & 63); + char M_width = 1; + res->fields[FIELD_Vm] = instr & 0xF; + res->fields_mask[FIELD_Vm >> 6] |= 1LL << (FIELD_Vm & 63); + char Vm_width = 4; + + static const instruction_format instr_formats[] = + { + { /* VMUL<c>.P8 <Dd>,<Dn>,<Dm> */ + "vmul.p8", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_n,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_m,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + { /* VMUL<c>.P8 <Qd>,<Qn>,<Qm> */ + "vmul.p8", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"q","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_n,FIELD_UNINIT,"q","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_m,FIELD_UNINIT,"q","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 2; + res->mnem = armv7::ARMV7_VMUL; + + /* pcode: if (size == '11' || (op == '1' && size != '00')) then UNDEFINED */ + if((((res->fields[FIELD_size]) == (0x3)) || ((((res->fields[FIELD_op]) == (0x1)) && ((res->fields[FIELD_size]) != (0x0)))))) { + res->status |= STATUS_UNDEFINED; + } + /* pcode: if (Q == '1' && (Vd<0> == '1' || Vn<0> == '1' || Vm<0> == '1')) then UNDEFINED */ + if((((res->fields[FIELD_Q]) == (0x1)) && ((((((res->fields[FIELD_Vd] & 1)) == (0x1)) || (((res->fields[FIELD_Vn] & 1)) == (0x1))) || (((res->fields[FIELD_Vm] & 1)) == (0x1)))))) { + res->status |= STATUS_UNDEFINED; + } + /* pcode: long_destination = FALSE */ + res->fields[FIELD_long_destination] = 0; + res->fields_mask[FIELD_long_destination >> 6] |= 1LL << (FIELD_long_destination & 63); + /* pcode: esize = 8 << UInt(size) */ + res->fields[FIELD_esize] = (8) << ((res->fields[FIELD_size])); + res->fields_mask[FIELD_esize >> 6] |= 1LL << (FIELD_esize & 63); + /* pcode: elements = 64 DIV esize */ + res->fields[FIELD_elements] = ((res->fields[FIELD_esize]) ? ((64) / (res->fields[FIELD_esize])) : 0); + res->fields_mask[FIELD_elements >> 6] |= 1LL << (FIELD_elements & 63); + /* pcode: d = UInt(D:Vd) */ + res->fields[FIELD_d] = ((res->fields[FIELD_D]<<Vd_width)|(res->fields[FIELD_Vd])); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: n = UInt(N:Vn) */ + res->fields[FIELD_n] = ((res->fields[FIELD_N]<<Vn_width)|(res->fields[FIELD_Vn])); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: m = UInt(M:Vm) */ + res->fields[FIELD_m] = ((res->fields[FIELD_M]<<Vm_width)|(res->fields[FIELD_Vm])); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + /* pcode: regs = if Q == '0' then 1 else 2 */ + if((res->fields[FIELD_Q]) == (0x0)) { + res->fields[FIELD_regs] = 1; + res->fields_mask[FIELD_regs >> 6] |= 1LL << (FIELD_regs & 63); + } + else { + res->fields[FIELD_regs] = 2; + res->fields_mask[FIELD_regs >> 6] |= 1LL << (FIELD_regs & 63); + } + /* pcode: fmt_idx = (Q == '1') */ + res->fields[FIELD_fmt_idx] = ((res->fields[FIELD_Q]) == (0x1)); + res->fields_mask[FIELD_fmt_idx >> 6] |= 1LL << (FIELD_fmt_idx & 63); + /* pcode: dt = size */ + res->fields[FIELD_dt] = res->fields[FIELD_size]; + res->fields_mask[FIELD_dt >> 6] |= 1LL << (FIELD_dt & 63); + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* Encoding T2 */ + /* pattern="111,U.1,1111,1,D.1,size.2,Vn.4,Vd.4,11,op.1,0,N.1,0,M.1,0,Vm.4" width=32 stringency=18 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xEF800D50)==0xEF800C00)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ADVSIMD)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_U] = (instr & 0x10000000)>>28; + res->fields_mask[FIELD_U >> 6] |= 1LL << (FIELD_U & 63); + char U_width = 1; + res->fields[FIELD_D] = (instr & 0x400000)>>22; + res->fields_mask[FIELD_D >> 6] |= 1LL << (FIELD_D & 63); + char D_width = 1; + res->fields[FIELD_size] = (instr & 0x300000)>>20; + res->fields_mask[FIELD_size >> 6] |= 1LL << (FIELD_size & 63); + char size_width = 2; + res->fields[FIELD_Vn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Vn >> 6] |= 1LL << (FIELD_Vn & 63); + char Vn_width = 4; + res->fields[FIELD_Vd] = (instr & 0xF000)>>12; + res->fields_mask[FIELD_Vd >> 6] |= 1LL << (FIELD_Vd & 63); + char Vd_width = 4; + res->fields[FIELD_op] = (instr & 0x200)>>9; + res->fields_mask[FIELD_op >> 6] |= 1LL << (FIELD_op & 63); + char op_width = 1; + res->fields[FIELD_N] = (instr & 0x80)>>7; + res->fields_mask[FIELD_N >> 6] |= 1LL << (FIELD_N & 63); + char N_width = 1; + res->fields[FIELD_M] = (instr & 0x20)>>5; + res->fields_mask[FIELD_M >> 6] |= 1LL << (FIELD_M & 63); + char M_width = 1; + res->fields[FIELD_Vm] = instr & 0xF; + res->fields_mask[FIELD_Vm >> 6] |= 1LL << (FIELD_Vm & 63); + char Vm_width = 4; + + static const instruction_format instr_formats[] = + { + { /* VMULL<c>.<dt> <Qd>,<Dn>,<Dm> */ + "vmull", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_VFP_DATA_SIZE, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"q","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_n,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_m,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + { /* VMULL<c>.P8 <Qd>,<Dn>,<Dm> */ + "vmull.p8", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"q","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_n,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_m,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 2; + res->mnem = armv7::ARMV7_VMULL; + + /* pcode: if size == '11' then SEE advanced_simd_data_proc */ + if((res->fields[FIELD_size]) == (0x3)) { + + return advanced_simd_data_proc(req, res); + } + /* pcode: if (op == '1' && (U != '0' || size != '00')) then UNDEFINED */ + if((((res->fields[FIELD_op]) == (0x1)) && ((((res->fields[FIELD_U]) != (0x0)) || ((res->fields[FIELD_size]) != (0x0)))))) { + res->status |= STATUS_UNDEFINED; + } + /* pcode: if Vd<0> == '1' then UNDEFINED */ + if(((res->fields[FIELD_Vd] & 1)) == (0x1)) { + res->status |= STATUS_UNDEFINED; + } + /* pcode: long_destination = TRUE */ + res->fields[FIELD_long_destination] = 1; + res->fields_mask[FIELD_long_destination >> 6] |= 1LL << (FIELD_long_destination & 63); + /* pcode: unsigned = (U == '1') */ + res->fields[FIELD_unsigned] = ((res->fields[FIELD_U]) == (0x1)); + res->fields_mask[FIELD_unsigned >> 6] |= 1LL << (FIELD_unsigned & 63); + /* pcode: esize = 8 << UInt(size) */ + res->fields[FIELD_esize] = (8) << ((res->fields[FIELD_size])); + res->fields_mask[FIELD_esize >> 6] |= 1LL << (FIELD_esize & 63); + /* pcode: elements = 64 DIV esize */ + res->fields[FIELD_elements] = ((res->fields[FIELD_esize]) ? ((64) / (res->fields[FIELD_esize])) : 0); + res->fields_mask[FIELD_elements >> 6] |= 1LL << (FIELD_elements & 63); + /* pcode: d = UInt(D:Vd) */ + res->fields[FIELD_d] = ((res->fields[FIELD_D]<<Vd_width)|(res->fields[FIELD_Vd])); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: n = UInt(N:Vn) */ + res->fields[FIELD_n] = ((res->fields[FIELD_N]<<Vn_width)|(res->fields[FIELD_Vn])); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: m = UInt(M:Vm) */ + res->fields[FIELD_m] = ((res->fields[FIELD_M]<<Vm_width)|(res->fields[FIELD_Vm])); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + /* pcode: regs = 1 */ + res->fields[FIELD_regs] = 1; + res->fields_mask[FIELD_regs >> 6] |= 1LL << (FIELD_regs & 63); + /* pcode: fmt_idx = (op == '1') */ + res->fields[FIELD_fmt_idx] = ((res->fields[FIELD_op]) == (0x1)); + res->fields_mask[FIELD_fmt_idx >> 6] |= 1LL << (FIELD_fmt_idx & 63); + /* pcode: dt = UInt(U:size) */ + res->fields[FIELD_dt] = ((res->fields[FIELD_U]<<size_width)|(res->fields[FIELD_size])); + res->fields_mask[FIELD_dt >> 6] |= 1LL << (FIELD_dt & 63); + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* Encoding T1 */ + /* pattern="111,op.1,1111,0,D.1,size.2,Vn.4,Vd.4,1001,N.1,Q.1,M.1,1,Vm.4" width=32 stringency=18 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xEF800F10)==0xEF000910)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ADVSIMD)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_op] = (instr & 0x10000000)>>28; + res->fields_mask[FIELD_op >> 6] |= 1LL << (FIELD_op & 63); + char op_width = 1; + res->fields[FIELD_D] = (instr & 0x400000)>>22; + res->fields_mask[FIELD_D >> 6] |= 1LL << (FIELD_D & 63); + char D_width = 1; + res->fields[FIELD_size] = (instr & 0x300000)>>20; + res->fields_mask[FIELD_size >> 6] |= 1LL << (FIELD_size & 63); + char size_width = 2; + res->fields[FIELD_Vn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Vn >> 6] |= 1LL << (FIELD_Vn & 63); + char Vn_width = 4; + res->fields[FIELD_Vd] = (instr & 0xF000)>>12; + res->fields_mask[FIELD_Vd >> 6] |= 1LL << (FIELD_Vd & 63); + char Vd_width = 4; + res->fields[FIELD_N] = (instr & 0x80)>>7; + res->fields_mask[FIELD_N >> 6] |= 1LL << (FIELD_N & 63); + char N_width = 1; + res->fields[FIELD_Q] = (instr & 0x40)>>6; + res->fields_mask[FIELD_Q >> 6] |= 1LL << (FIELD_Q & 63); + char Q_width = 1; + res->fields[FIELD_M] = (instr & 0x20)>>5; + res->fields_mask[FIELD_M >> 6] |= 1LL << (FIELD_M & 63); + char M_width = 1; + res->fields[FIELD_Vm] = instr & 0xF; + res->fields_mask[FIELD_Vm >> 6] |= 1LL << (FIELD_Vm & 63); + char Vm_width = 4; + + static const instruction_format instr_formats[] = + { + { /* VMUL<c>.<dt> <Dd>,<Dn>,<Dm> */ + "vmul", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_VFP_DATA_SIZE, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_n,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_m,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + { /* VMUL<c>.<dt> <Qd>,<Qn>,<Qm> */ + "vmul", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_VFP_DATA_SIZE, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"q","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_n,FIELD_UNINIT,"q","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_m,FIELD_UNINIT,"q","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 2; + res->mnem = armv7::ARMV7_VMUL; + + /* pcode: if (size == '11' || (op == '1' && size != '00')) then UNDEFINED */ + if((((res->fields[FIELD_size]) == (0x3)) || ((((res->fields[FIELD_op]) == (0x1)) && ((res->fields[FIELD_size]) != (0x0)))))) { + res->status |= STATUS_UNDEFINED; + } + /* pcode: if (Q == '1' && (Vd<0> == '1' || Vn<0> == '1' || Vm<0> == '1')) then UNDEFINED */ + if((((res->fields[FIELD_Q]) == (0x1)) && ((((((res->fields[FIELD_Vd] & 1)) == (0x1)) || (((res->fields[FIELD_Vn] & 1)) == (0x1))) || (((res->fields[FIELD_Vm] & 1)) == (0x1)))))) { + res->status |= STATUS_UNDEFINED; + } + /* pcode: long_destination = FALSE */ + res->fields[FIELD_long_destination] = 0; + res->fields_mask[FIELD_long_destination >> 6] |= 1LL << (FIELD_long_destination & 63); + /* pcode: esize = 8 << UInt(size) */ + res->fields[FIELD_esize] = (8) << ((res->fields[FIELD_size])); + res->fields_mask[FIELD_esize >> 6] |= 1LL << (FIELD_esize & 63); + /* pcode: elements = 64 DIV esize */ + res->fields[FIELD_elements] = ((res->fields[FIELD_esize]) ? ((64) / (res->fields[FIELD_esize])) : 0); + res->fields_mask[FIELD_elements >> 6] |= 1LL << (FIELD_elements & 63); + /* pcode: d = UInt(D:Vd) */ + res->fields[FIELD_d] = ((res->fields[FIELD_D]<<Vd_width)|(res->fields[FIELD_Vd])); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: n = UInt(N:Vn) */ + res->fields[FIELD_n] = ((res->fields[FIELD_N]<<Vn_width)|(res->fields[FIELD_Vn])); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: m = UInt(M:Vm) */ + res->fields[FIELD_m] = ((res->fields[FIELD_M]<<Vm_width)|(res->fields[FIELD_Vm])); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + /* pcode: regs = if Q == '0' then 1 else 2 */ + if((res->fields[FIELD_Q]) == (0x0)) { + res->fields[FIELD_regs] = 1; + res->fields_mask[FIELD_regs >> 6] |= 1LL << (FIELD_regs & 63); + } + else { + res->fields[FIELD_regs] = 2; + res->fields_mask[FIELD_regs >> 6] |= 1LL << (FIELD_regs & 63); + } + /* pcode: iword = TRUE */ + res->fields[FIELD_iword] = 1; + res->fields_mask[FIELD_iword >> 6] |= 1LL << (FIELD_iword & 63); + /* pcode: fmt_idx = (Q == '1') */ + res->fields[FIELD_fmt_idx] = ((res->fields[FIELD_Q]) == (0x1)); + res->fields_mask[FIELD_fmt_idx >> 6] |= 1LL << (FIELD_fmt_idx & 63); + /* pcode: dt = size */ + res->fields[FIELD_dt] = res->fields[FIELD_size]; + res->fields_mask[FIELD_dt >> 6] |= 1LL << (FIELD_dt & 63); + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: 80471B35 +int vmul_scalar(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + res->group = INSN_GROUP_NEON; + /* Encoding T2 */ + /* pattern="111,U.1,1111,1,D.1,size.2,Vn.4,Vd.4,1010,N.1,1,M.1,0,Vm.4" width=32 stringency=18 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xEF800F50)==0xEF800A40)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ADVSIMD)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_U] = (instr & 0x10000000)>>28; + res->fields_mask[FIELD_U >> 6] |= 1LL << (FIELD_U & 63); + char U_width = 1; + res->fields[FIELD_D] = (instr & 0x400000)>>22; + res->fields_mask[FIELD_D >> 6] |= 1LL << (FIELD_D & 63); + char D_width = 1; + res->fields[FIELD_size] = (instr & 0x300000)>>20; + res->fields_mask[FIELD_size >> 6] |= 1LL << (FIELD_size & 63); + char size_width = 2; + res->fields[FIELD_Vn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Vn >> 6] |= 1LL << (FIELD_Vn & 63); + char Vn_width = 4; + res->fields[FIELD_Vd] = (instr & 0xF000)>>12; + res->fields_mask[FIELD_Vd >> 6] |= 1LL << (FIELD_Vd & 63); + char Vd_width = 4; + res->fields[FIELD_N] = (instr & 0x80)>>7; + res->fields_mask[FIELD_N >> 6] |= 1LL << (FIELD_N & 63); + char N_width = 1; + res->fields[FIELD_M] = (instr & 0x20)>>5; + res->fields_mask[FIELD_M >> 6] |= 1LL << (FIELD_M & 63); + char M_width = 1; + res->fields[FIELD_Vm] = instr & 0xF; + res->fields_mask[FIELD_Vm >> 6] |= 1LL << (FIELD_Vm & 63); + char Vm_width = 4; + + static const instruction_format instr_formats[] = + { + { /* VMULL<c>.<dt> <Qd>,<Dn>,<Dm[x]> */ + "vmull", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_VFP_DATA_SIZE, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"q","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_n,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_INDEX,FIELD_m,FIELD_x,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_VMULL; + + /* pcode: if size == '11' then SEE advanced_simd_data_proc */ + if((res->fields[FIELD_size]) == (0x3)) { + + return advanced_simd_data_proc(req, res); + } + /* pcode: if size == '00' || Vd<0> == '1' then UNDEFINED */ + if(((res->fields[FIELD_size]) == (0x0)) || (((res->fields[FIELD_Vd] & 1)) == (0x1))) { + res->status |= STATUS_UNDEFINED; + } + /* pcode: unsigned = (U == '1') */ + res->fields[FIELD_unsigned] = ((res->fields[FIELD_U]) == (0x1)); + res->fields_mask[FIELD_unsigned >> 6] |= 1LL << (FIELD_unsigned & 63); + /* pcode: long_destination = TRUE */ + res->fields[FIELD_long_destination] = 1; + res->fields_mask[FIELD_long_destination >> 6] |= 1LL << (FIELD_long_destination & 63); + /* pcode: floating_point = FALSE */ + res->fields[FIELD_floating_point] = 0; + res->fields_mask[FIELD_floating_point >> 6] |= 1LL << (FIELD_floating_point & 63); + /* pcode: d = UInt(D:Vd) */ + res->fields[FIELD_d] = ((res->fields[FIELD_D]<<Vd_width)|(res->fields[FIELD_Vd])); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: n = UInt(N:Vn) */ + res->fields[FIELD_n] = ((res->fields[FIELD_N]<<Vn_width)|(res->fields[FIELD_Vn])); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: regs = 1 */ + res->fields[FIELD_regs] = 1; + res->fields_mask[FIELD_regs >> 6] |= 1LL << (FIELD_regs & 63); + /* pcode: if size == '01' then esize = 16 */ + if((res->fields[FIELD_size]) == (0x1)) { + res->fields[FIELD_esize] = 16; + res->fields_mask[FIELD_esize >> 6] |= 1LL << (FIELD_esize & 63); + } + /* pcode: if size == '10' then esize = 32 */ + if((res->fields[FIELD_size]) == (0x2)) { + res->fields[FIELD_esize] = 32; + res->fields_mask[FIELD_esize >> 6] |= 1LL << (FIELD_esize & 63); + } + /* pcode: elements = 64 DIV esize */ + res->fields[FIELD_elements] = ((res->fields[FIELD_esize]) ? ((64) / (res->fields[FIELD_esize])) : 0); + res->fields_mask[FIELD_elements >> 6] |= 1LL << (FIELD_elements & 63); + /* pcode: m = UInt(Vm<2:0>) */ + res->fields[FIELD_m] = ((res->fields[FIELD_Vm] & 0x7)); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + /* pcode: x = (M * 2) + Vm<3> */ + res->fields[FIELD_x] = (((res->fields[FIELD_M]) * (2))) + (((res->fields[FIELD_Vm] >> 3) & 1)); + res->fields_mask[FIELD_x >> 6] |= 1LL << (FIELD_x & 63); + /* pcode: if esize == 32 then m = UInt(Vm) */ + if((res->fields[FIELD_esize]) == (32)) { + res->fields[FIELD_m] = (res->fields[FIELD_Vm]); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + } + /* pcode: if esize == 32 then x = UInt(M) */ + if((res->fields[FIELD_esize]) == (32)) { + res->fields[FIELD_x] = (res->fields[FIELD_M]); + res->fields_mask[FIELD_x >> 6] |= 1LL << (FIELD_x & 63); + } + /* pcode: dt = size + (U * 4) */ + res->fields[FIELD_dt] = (res->fields[FIELD_size]) + (((res->fields[FIELD_U]) * (4))); + res->fields_mask[FIELD_dt >> 6] |= 1LL << (FIELD_dt & 63); + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* Encoding T1 */ + /* pattern="111,Q.1,1111,1,D.1,size.2,Vn.4,Vd.4,100,F.1,N.1,1,M.1,0,Vm.4" width=32 stringency=18 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xEF800E50)==0xEF800840)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ADVSIMD)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_Q] = (instr & 0x10000000)>>28; + res->fields_mask[FIELD_Q >> 6] |= 1LL << (FIELD_Q & 63); + char Q_width = 1; + res->fields[FIELD_D] = (instr & 0x400000)>>22; + res->fields_mask[FIELD_D >> 6] |= 1LL << (FIELD_D & 63); + char D_width = 1; + res->fields[FIELD_size] = (instr & 0x300000)>>20; + res->fields_mask[FIELD_size >> 6] |= 1LL << (FIELD_size & 63); + char size_width = 2; + res->fields[FIELD_Vn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Vn >> 6] |= 1LL << (FIELD_Vn & 63); + char Vn_width = 4; + res->fields[FIELD_Vd] = (instr & 0xF000)>>12; + res->fields_mask[FIELD_Vd >> 6] |= 1LL << (FIELD_Vd & 63); + char Vd_width = 4; + res->fields[FIELD_F] = (instr & 0x100)>>8; + res->fields_mask[FIELD_F >> 6] |= 1LL << (FIELD_F & 63); + char F_width = 1; + res->fields[FIELD_N] = (instr & 0x80)>>7; + res->fields_mask[FIELD_N >> 6] |= 1LL << (FIELD_N & 63); + char N_width = 1; + res->fields[FIELD_M] = (instr & 0x20)>>5; + res->fields_mask[FIELD_M >> 6] |= 1LL << (FIELD_M & 63); + char M_width = 1; + res->fields[FIELD_Vm] = instr & 0xF; + res->fields_mask[FIELD_Vm >> 6] |= 1LL << (FIELD_Vm & 63); + char Vm_width = 4; + + static const instruction_format instr_formats[] = + { + { /* VMUL<c>.<dt> <Dd>,<Dn>,<Dm[x]> */ + "vmul", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_VFP_DATA_SIZE, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_n,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_INDEX,FIELD_m,FIELD_x,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + { /* VMUL<c>.<dt> <Qd>,<Qn>,<Dm[x]> */ + "vmul", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_VFP_DATA_SIZE, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"q","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_n,FIELD_UNINIT,"q","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_INDEX,FIELD_m,FIELD_x,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 2; + res->mnem = armv7::ARMV7_VMUL; + + /* pcode: if size == '11' then SEE advanced_simd_data_proc */ + if((res->fields[FIELD_size]) == (0x3)) { + + return advanced_simd_data_proc(req, res); + } + /* pcode: if (size == '00' || (F == '1' && size == '01')) then UNDEFINED */ + if((((res->fields[FIELD_size]) == (0x0)) || ((((res->fields[FIELD_F]) == (0x1)) && ((res->fields[FIELD_size]) == (0x1)))))) { + res->status |= STATUS_UNDEFINED; + } + /* pcode: if (Q == '1' && (Vd<0> == '1' || Vn<0> == '1')) then UNDEFINED */ + if((((res->fields[FIELD_Q]) == (0x1)) && (((((res->fields[FIELD_Vd] & 1)) == (0x1)) || (((res->fields[FIELD_Vn] & 1)) == (0x1)))))) { + res->status |= STATUS_UNDEFINED; + } + /* pcode: floating_point = (F == '1') */ + res->fields[FIELD_floating_point] = ((res->fields[FIELD_F]) == (0x1)); + res->fields_mask[FIELD_floating_point >> 6] |= 1LL << (FIELD_floating_point & 63); + /* pcode: long_destination = FALSE */ + res->fields[FIELD_long_destination] = 0; + res->fields_mask[FIELD_long_destination >> 6] |= 1LL << (FIELD_long_destination & 63); + /* pcode: d = UInt(D:Vd) */ + res->fields[FIELD_d] = ((res->fields[FIELD_D]<<Vd_width)|(res->fields[FIELD_Vd])); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: n = UInt(N:Vn) */ + res->fields[FIELD_n] = ((res->fields[FIELD_N]<<Vn_width)|(res->fields[FIELD_Vn])); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: regs = if Q == '0' then 1 else 2 */ + if((res->fields[FIELD_Q]) == (0x0)) { + res->fields[FIELD_regs] = 1; + res->fields_mask[FIELD_regs >> 6] |= 1LL << (FIELD_regs & 63); + } + else { + res->fields[FIELD_regs] = 2; + res->fields_mask[FIELD_regs >> 6] |= 1LL << (FIELD_regs & 63); + } + /* pcode: if size == '01' then esize = 16 */ + if((res->fields[FIELD_size]) == (0x1)) { + res->fields[FIELD_esize] = 16; + res->fields_mask[FIELD_esize >> 6] |= 1LL << (FIELD_esize & 63); + } + /* pcode: if size == '10' then esize = 32 */ + if((res->fields[FIELD_size]) == (0x2)) { + res->fields[FIELD_esize] = 32; + res->fields_mask[FIELD_esize >> 6] |= 1LL << (FIELD_esize & 63); + } + /* pcode: elements = 64 DIV esize */ + res->fields[FIELD_elements] = ((res->fields[FIELD_esize]) ? ((64) / (res->fields[FIELD_esize])) : 0); + res->fields_mask[FIELD_elements >> 6] |= 1LL << (FIELD_elements & 63); + /* pcode: x = UInt(M:Vm) */ + res->fields[FIELD_x] = ((res->fields[FIELD_M]<<Vm_width)|(res->fields[FIELD_Vm])); + res->fields_mask[FIELD_x >> 6] |= 1LL << (FIELD_x & 63); + /* pcode: if esize == 16 then x = x >> 3 */ + if((res->fields[FIELD_esize]) == (16)) { + res->fields[FIELD_x] = (res->fields[FIELD_x]) >> (3); + res->fields_mask[FIELD_x >> 6] |= 1LL << (FIELD_x & 63); + } + /* pcode: if esize == 32 then x = UInt(M) */ + if((res->fields[FIELD_esize]) == (32)) { + res->fields[FIELD_x] = (res->fields[FIELD_M]); + res->fields_mask[FIELD_x >> 6] |= 1LL << (FIELD_x & 63); + } + /* pcode: if esize == 16 then m = Vm - ((Vm >> 3)*8) */ + if((res->fields[FIELD_esize]) == (16)) { + res->fields[FIELD_m] = (res->fields[FIELD_Vm]) - (((((res->fields[FIELD_Vm]) >> (3))) * (8))); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + } + /* pcode: if esize == 32 then m = UInt(Vm) */ + if((res->fields[FIELD_esize]) == (32)) { + res->fields[FIELD_m] = (res->fields[FIELD_Vm]); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + } + /* pcode: iword = TRUE */ + res->fields[FIELD_iword] = 1; + res->fields_mask[FIELD_iword >> 6] |= 1LL << (FIELD_iword & 63); + /* pcode: fmt_idx = (Q == '1') */ + res->fields[FIELD_fmt_idx] = ((res->fields[FIELD_Q]) == (0x1)); + res->fields_mask[FIELD_fmt_idx >> 6] |= 1LL << (FIELD_fmt_idx & 63); + /* pcode: dt = if F == '1' then 4 else size */ + if((res->fields[FIELD_F]) == (0x1)) { + res->fields[FIELD_dt] = 4; + res->fields_mask[FIELD_dt >> 6] |= 1LL << (FIELD_dt & 63); + } + else { + res->fields[FIELD_dt] = res->fields[FIELD_size]; + res->fields_mask[FIELD_dt >> 6] |= 1LL << (FIELD_dt & 63); + } + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: D4DFDBDC +int vmvn(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + res->group = INSN_GROUP_NEON; + /* Encoding T1 */ + /* pattern="1111,xx11,1,D.1,11,size.2,00,Vd.4,0,1011,Q.1,M.1,0,Vm.4" width=32 stringency=20 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xF3B30F90)==0xF3B00580)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ADVSIMD)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_D] = (instr & 0x400000)>>22; + res->fields_mask[FIELD_D >> 6] |= 1LL << (FIELD_D & 63); + char D_width = 1; + res->fields[FIELD_size] = (instr & 0xC0000)>>18; + res->fields_mask[FIELD_size >> 6] |= 1LL << (FIELD_size & 63); + char size_width = 2; + res->fields[FIELD_Vd] = (instr & 0xF000)>>12; + res->fields_mask[FIELD_Vd >> 6] |= 1LL << (FIELD_Vd & 63); + char Vd_width = 4; + res->fields[FIELD_Q] = (instr & 0x40)>>6; + res->fields_mask[FIELD_Q >> 6] |= 1LL << (FIELD_Q & 63); + char Q_width = 1; + res->fields[FIELD_M] = (instr & 0x20)>>5; + res->fields_mask[FIELD_M >> 6] |= 1LL << (FIELD_M & 63); + char M_width = 1; + res->fields[FIELD_Vm] = instr & 0xF; + res->fields_mask[FIELD_Vm >> 6] |= 1LL << (FIELD_Vm & 63); + char Vm_width = 4; + + static const instruction_format instr_formats[] = + { + { /* VMVN<c> <Dd>,<Dm> */ + "vmvn", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_m,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + { /* VMVN<c> <Qd>,<Qm> */ + "vmvn", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"q","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_m,FIELD_UNINIT,"q","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 2; + res->mnem = armv7::ARMV7_VMVN; + + /* pcode: if size != '00' then UNDEFINED */ + if((res->fields[FIELD_size]) != (0x0)) { + res->status |= STATUS_UNDEFINED; + } + /* pcode: if Q == '1' && (Vd<0> == '1' || Vm<0> == '1') then UNDEFINED */ + if(((res->fields[FIELD_Q]) == (0x1)) && (((((res->fields[FIELD_Vd] & 1)) == (0x1)) || (((res->fields[FIELD_Vm] & 1)) == (0x1))))) { + res->status |= STATUS_UNDEFINED; + } + /* pcode: d = UInt(D:Vd) */ + res->fields[FIELD_d] = ((res->fields[FIELD_D]<<Vd_width)|(res->fields[FIELD_Vd])); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: m = UInt(M:Vm) */ + res->fields[FIELD_m] = ((res->fields[FIELD_M]<<Vm_width)|(res->fields[FIELD_Vm])); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + /* pcode: regs = if Q == '0' then 1 else 2 */ + if((res->fields[FIELD_Q]) == (0x0)) { + res->fields[FIELD_regs] = 1; + res->fields_mask[FIELD_regs >> 6] |= 1LL << (FIELD_regs & 63); + } + else { + res->fields[FIELD_regs] = 2; + res->fields_mask[FIELD_regs >> 6] |= 1LL << (FIELD_regs & 63); + } + /* pcode: fmt_idx = (Q == '1') */ + res->fields[FIELD_fmt_idx] = ((res->fields[FIELD_Q]) == (0x1)); + res->fields_mask[FIELD_fmt_idx >> 6] |= 1LL << (FIELD_fmt_idx & 63); + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: B335A3A5 +int vmvn_immediate(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + res->group = INSN_GROUP_NEON; + /* Encoding T1 */ + /* pattern="111,i.1,1111,1,D.1,000,imm3.3,Vd.4,cmode.4,0,Q.1,1,1,imm4.4" width=32 stringency=17 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xEFB800B0)==0xEF800030)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ADVSIMD)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_i] = (instr & 0x10000000)>>28; + res->fields_mask[FIELD_i >> 6] |= 1LL << (FIELD_i & 63); + char i_width = 1; + res->fields[FIELD_D] = (instr & 0x400000)>>22; + res->fields_mask[FIELD_D >> 6] |= 1LL << (FIELD_D & 63); + char D_width = 1; + res->fields[FIELD_imm3] = (instr & 0x70000)>>16; + res->fields_mask[FIELD_imm3 >> 6] |= 1LL << (FIELD_imm3 & 63); + char imm3_width = 3; + res->fields[FIELD_Vd] = (instr & 0xF000)>>12; + res->fields_mask[FIELD_Vd >> 6] |= 1LL << (FIELD_Vd & 63); + char Vd_width = 4; + res->fields[FIELD_cmode] = (instr & 0xF00)>>8; + res->fields_mask[FIELD_cmode >> 6] |= 1LL << (FIELD_cmode & 63); + char cmode_width = 4; + res->fields[FIELD_Q] = (instr & 0x40)>>6; + res->fields_mask[FIELD_Q >> 6] |= 1LL << (FIELD_Q & 63); + char Q_width = 1; + res->fields[FIELD_imm4] = instr & 0xF; + res->fields_mask[FIELD_imm4 >> 6] |= 1LL << (FIELD_imm4 & 63); + char imm4_width = 4; + + static const instruction_format instr_formats[] = + { + { /* VMVN<c>.<dt> <Dd>,#<imm64> */ + "vmvn", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_VFP_DATA_SIZE, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_IMM64,FIELD_UNINIT,FIELD_UNINIT,"#","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + { /* VMVN<c>.<dt> <Qd>,#<imm64> */ + "vmvn", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_VFP_DATA_SIZE, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"q","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_IMM64,FIELD_UNINIT,FIELD_UNINIT,"#","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 2; + res->mnem = armv7::ARMV7_VMVN; + + /* pcode: if (Q == '1' && Vd<0> == '1') then UNDEFINED */ + if((((res->fields[FIELD_Q]) == (0x1)) && (((res->fields[FIELD_Vd] & 1)) == (0x1)))) { + res->status |= STATUS_UNDEFINED; + } + /* pcode: imm64l = AdvSIMDExpandImm('1', cmode, i:imm3:imm4, 1) */ + res->fields[FIELD_imm64l] = AdvSIMDExpandImm(0x1, res->fields[FIELD_cmode], (res->fields[FIELD_i]<<(4+3))|(res->fields[FIELD_imm3]<<4)|(res->fields[FIELD_imm4]), 1); + res->fields_mask[FIELD_imm64l >> 6] |= 1LL << (FIELD_imm64l & 63); + /* pcode: imm64h = AdvSIMDExpandImm('1', cmode, i:imm3:imm4, 0) */ + res->fields[FIELD_imm64h] = AdvSIMDExpandImm(0x1, res->fields[FIELD_cmode], (res->fields[FIELD_i]<<(4+3))|(res->fields[FIELD_imm3]<<4)|(res->fields[FIELD_imm4]), 0); + res->fields_mask[FIELD_imm64h >> 6] |= 1LL << (FIELD_imm64h & 63); + /* pcode: d = UInt(D:Vd) */ + res->fields[FIELD_d] = ((res->fields[FIELD_D]<<Vd_width)|(res->fields[FIELD_Vd])); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: regs = if Q == '0' then 1 else 2 */ + if((res->fields[FIELD_Q]) == (0x0)) { + res->fields[FIELD_regs] = 1; + res->fields_mask[FIELD_regs >> 6] |= 1LL << (FIELD_regs & 63); + } + else { + res->fields[FIELD_regs] = 2; + res->fields_mask[FIELD_regs >> 6] |= 1LL << (FIELD_regs & 63); + } + /* pcode: fmt_idx = (Q == '1') */ + res->fields[FIELD_fmt_idx] = ((res->fields[FIELD_Q]) == (0x1)); + res->fields_mask[FIELD_fmt_idx >> 6] |= 1LL << (FIELD_fmt_idx & 63); + /* pcode: dt = UInt(imm3:i) */ + res->fields[FIELD_dt] = ((res->fields[FIELD_imm3]<<i_width)|(res->fields[FIELD_i])); + res->fields_mask[FIELD_dt >> 6] |= 1LL << (FIELD_dt & 63); + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: 8E1CB28A +int vneg(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + res->group = INSN_GROUP_NEON; + /* Encoding T2 */ + /* pattern="1110,11101,D.1,11,0001,Vd.4,101,sz.1,0,1,M.1,0,Vm.4" width=32 stringency=24 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFFBF0ED0)==0xEEB10A40)) { + res->instrSize = 32; + if(!(req->arch & ARCH_VFPv2) && !(req->arch & ARCH_VFPv3)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_D] = (instr & 0x400000)>>22; + res->fields_mask[FIELD_D >> 6] |= 1LL << (FIELD_D & 63); + char D_width = 1; + res->fields[FIELD_Vd] = (instr & 0xF000)>>12; + res->fields_mask[FIELD_Vd >> 6] |= 1LL << (FIELD_Vd & 63); + char Vd_width = 4; + res->fields[FIELD_sz] = (instr & 0x100)>>8; + res->fields_mask[FIELD_sz >> 6] |= 1LL << (FIELD_sz & 63); + char sz_width = 1; + res->fields[FIELD_M] = (instr & 0x20)>>5; + res->fields_mask[FIELD_M >> 6] |= 1LL << (FIELD_M & 63); + char M_width = 1; + res->fields[FIELD_Vm] = instr & 0xF; + res->fields_mask[FIELD_Vm >> 6] |= 1LL << (FIELD_Vm & 63); + char Vm_width = 4; + + static const instruction_format instr_formats[] = + { + { /* VNEG<c>.F32 <Sd>,<Sm> */ + "vneg.f32", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_F32, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"s","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_m,FIELD_UNINIT,"s","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + { /* VNEG<c>.F64 <Dd>,<Dm> */ + "vneg.f64", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_F64, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_m,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 2; + res->mnem = armv7::ARMV7_VNEG; + + /* pcode: advsimd = FALSE */ + res->fields[FIELD_advsimd] = 0; + res->fields_mask[FIELD_advsimd >> 6] |= 1LL << (FIELD_advsimd & 63); + /* pcode: dp_operation = (sz == '1') */ + res->fields[FIELD_dp_operation] = ((res->fields[FIELD_sz]) == (0x1)); + res->fields_mask[FIELD_dp_operation >> 6] |= 1LL << (FIELD_dp_operation & 63); + /* pcode: d = if dp_operation then UInt(D:Vd) else UInt(Vd:D) */ + if(res->fields[FIELD_dp_operation]) { + res->fields[FIELD_d] = ((res->fields[FIELD_D]<<Vd_width)|(res->fields[FIELD_Vd])); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + } + else { + res->fields[FIELD_d] = ((res->fields[FIELD_Vd]<<D_width)|(res->fields[FIELD_D])); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + } + /* pcode: m = if dp_operation then UInt(M:Vm) else UInt(Vm:M) */ + if(res->fields[FIELD_dp_operation]) { + res->fields[FIELD_m] = ((res->fields[FIELD_M]<<Vm_width)|(res->fields[FIELD_Vm])); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + } + else { + res->fields[FIELD_m] = ((res->fields[FIELD_Vm]<<M_width)|(res->fields[FIELD_M])); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + } + /* pcode: fmt_idx = (sz == '1') */ + res->fields[FIELD_fmt_idx] = ((res->fields[FIELD_sz]) == (0x1)); + res->fields_mask[FIELD_fmt_idx >> 6] |= 1LL << (FIELD_fmt_idx & 63); + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* Encoding T1 */ + /* pattern="1111,xx11,1,D.1,11,size.2,01,Vd.4,0,F.1,111,Q.1,M.1,0,Vm.4" width=32 stringency=20 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xF3B30B90)==0xF3B10380)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ADVSIMD)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_D] = (instr & 0x400000)>>22; + res->fields_mask[FIELD_D >> 6] |= 1LL << (FIELD_D & 63); + char D_width = 1; + res->fields[FIELD_size] = (instr & 0xC0000)>>18; + res->fields_mask[FIELD_size >> 6] |= 1LL << (FIELD_size & 63); + char size_width = 2; + res->fields[FIELD_Vd] = (instr & 0xF000)>>12; + res->fields_mask[FIELD_Vd >> 6] |= 1LL << (FIELD_Vd & 63); + char Vd_width = 4; + res->fields[FIELD_F] = (instr & 0x400)>>10; + res->fields_mask[FIELD_F >> 6] |= 1LL << (FIELD_F & 63); + char F_width = 1; + res->fields[FIELD_Q] = (instr & 0x40)>>6; + res->fields_mask[FIELD_Q >> 6] |= 1LL << (FIELD_Q & 63); + char Q_width = 1; + res->fields[FIELD_M] = (instr & 0x20)>>5; + res->fields_mask[FIELD_M >> 6] |= 1LL << (FIELD_M & 63); + char M_width = 1; + res->fields[FIELD_Vm] = instr & 0xF; + res->fields_mask[FIELD_Vm >> 6] |= 1LL << (FIELD_Vm & 63); + char Vm_width = 4; + + static const instruction_format instr_formats[] = + { + { /* VNEG<c>.<dt> <Dd>,<Dm> */ + "vneg", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_VFP_DATA_SIZE, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_m,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + { /* VNEG<c>.<dt> <Qd>,<Qm> */ + "vneg", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_VFP_DATA_SIZE, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"q","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_m,FIELD_UNINIT,"q","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 2; + res->mnem = armv7::ARMV7_VNEG; + + /* pcode: if (size == '11' || (F == '1' && size != '10')) then UNDEFINED */ + if((((res->fields[FIELD_size]) == (0x3)) || ((((res->fields[FIELD_F]) == (0x1)) && ((res->fields[FIELD_size]) != (0x2)))))) { + res->status |= STATUS_UNDEFINED; + } + /* pcode: if (Q == '1' && (Vd<0> == '1' || Vm<0> == '1')) then UNDEFINED */ + if((((res->fields[FIELD_Q]) == (0x1)) && (((((res->fields[FIELD_Vd] & 1)) == (0x1)) || (((res->fields[FIELD_Vm] & 1)) == (0x1)))))) { + res->status |= STATUS_UNDEFINED; + } + /* pcode: advsimd = TRUE */ + res->fields[FIELD_advsimd] = 1; + res->fields_mask[FIELD_advsimd >> 6] |= 1LL << (FIELD_advsimd & 63); + /* pcode: floating_point = (F == '1') */ + res->fields[FIELD_floating_point] = ((res->fields[FIELD_F]) == (0x1)); + res->fields_mask[FIELD_floating_point >> 6] |= 1LL << (FIELD_floating_point & 63); + /* pcode: esize = 8 << UInt(size) */ + res->fields[FIELD_esize] = (8) << ((res->fields[FIELD_size])); + res->fields_mask[FIELD_esize >> 6] |= 1LL << (FIELD_esize & 63); + /* pcode: elements = 64 DIV esize */ + res->fields[FIELD_elements] = ((res->fields[FIELD_esize]) ? ((64) / (res->fields[FIELD_esize])) : 0); + res->fields_mask[FIELD_elements >> 6] |= 1LL << (FIELD_elements & 63); + /* pcode: d = UInt(D:Vd) */ + res->fields[FIELD_d] = ((res->fields[FIELD_D]<<Vd_width)|(res->fields[FIELD_Vd])); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: m = UInt(M:Vm) */ + res->fields[FIELD_m] = ((res->fields[FIELD_M]<<Vm_width)|(res->fields[FIELD_Vm])); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + /* pcode: regs = if Q == '0' then 1 else 2 */ + if((res->fields[FIELD_Q]) == (0x0)) { + res->fields[FIELD_regs] = 1; + res->fields_mask[FIELD_regs >> 6] |= 1LL << (FIELD_regs & 63); + } + else { + res->fields[FIELD_regs] = 2; + res->fields_mask[FIELD_regs >> 6] |= 1LL << (FIELD_regs & 63); + } + /* pcode: fmt_idx = (Q == '1') */ + res->fields[FIELD_fmt_idx] = ((res->fields[FIELD_Q]) == (0x1)); + res->fields_mask[FIELD_fmt_idx >> 6] |= 1LL << (FIELD_fmt_idx & 63); + /* pcode: dt = size */ + res->fields[FIELD_dt] = res->fields[FIELD_size]; + res->fields_mask[FIELD_dt >> 6] |= 1LL << (FIELD_dt & 63); + /* pcode: dt = dt + UInt(F) */ + res->fields[FIELD_dt] = (res->fields[FIELD_dt]) + ((res->fields[FIELD_F])); + res->fields_mask[FIELD_dt >> 6] |= 1LL << (FIELD_dt & 63); + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: 470669F1 +int vnmla(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + res->group = INSN_GROUP_NEON; + /* Encoding T2 */ + /* pattern="1110,11100,D.1,10,Vn.4,Vd.4,101,sz.1,N.1,1,M.1,0,Vm.4" width=32 stringency=20 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFFB00E50)==0xEE200A40)) { + res->instrSize = 32; + if(!(req->arch & ARCH_VFPv2) && !(req->arch & ARCH_VFPv3)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_D] = (instr & 0x400000)>>22; + res->fields_mask[FIELD_D >> 6] |= 1LL << (FIELD_D & 63); + char D_width = 1; + res->fields[FIELD_Vn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Vn >> 6] |= 1LL << (FIELD_Vn & 63); + char Vn_width = 4; + res->fields[FIELD_Vd] = (instr & 0xF000)>>12; + res->fields_mask[FIELD_Vd >> 6] |= 1LL << (FIELD_Vd & 63); + char Vd_width = 4; + res->fields[FIELD_sz] = (instr & 0x100)>>8; + res->fields_mask[FIELD_sz >> 6] |= 1LL << (FIELD_sz & 63); + char sz_width = 1; + res->fields[FIELD_N] = (instr & 0x80)>>7; + res->fields_mask[FIELD_N >> 6] |= 1LL << (FIELD_N & 63); + char N_width = 1; + res->fields[FIELD_M] = (instr & 0x20)>>5; + res->fields_mask[FIELD_M >> 6] |= 1LL << (FIELD_M & 63); + char M_width = 1; + res->fields[FIELD_Vm] = instr & 0xF; + res->fields_mask[FIELD_Vm >> 6] |= 1LL << (FIELD_Vm & 63); + char Vm_width = 4; + + static const instruction_format instr_formats[] = + { + { /* VNMUL<c>.F32 <Sd>,<Sn>,<Sm> */ + "vnmul.f32", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_F32, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"s","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_n,FIELD_UNINIT,"s","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_m,FIELD_UNINIT,"s","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + { /* VNMUL<c>.F64 <Dd>,<Dn>,<Dm> */ + "vnmul.f64", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_F64, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_n,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_m,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 2; + res->mnem = armv7::ARMV7_VNMUL; + + /* pcode: dp_operation = (sz == '1') */ + res->fields[FIELD_dp_operation] = ((res->fields[FIELD_sz]) == (0x1)); + res->fields_mask[FIELD_dp_operation >> 6] |= 1LL << (FIELD_dp_operation & 63); + /* pcode: d = if dp_operation then UInt(D:Vd) else UInt(Vd:D) */ + if(res->fields[FIELD_dp_operation]) { + res->fields[FIELD_d] = ((res->fields[FIELD_D]<<Vd_width)|(res->fields[FIELD_Vd])); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + } + else { + res->fields[FIELD_d] = ((res->fields[FIELD_Vd]<<D_width)|(res->fields[FIELD_D])); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + } + /* pcode: n = if dp_operation then UInt(N:Vn) else UInt(Vn:N) */ + if(res->fields[FIELD_dp_operation]) { + res->fields[FIELD_n] = ((res->fields[FIELD_N]<<Vn_width)|(res->fields[FIELD_Vn])); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + } + else { + res->fields[FIELD_n] = ((res->fields[FIELD_Vn]<<N_width)|(res->fields[FIELD_N])); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + } + /* pcode: m = if dp_operation then UInt(M:Vm) else UInt(Vm:M) */ + if(res->fields[FIELD_dp_operation]) { + res->fields[FIELD_m] = ((res->fields[FIELD_M]<<Vm_width)|(res->fields[FIELD_Vm])); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + } + else { + res->fields[FIELD_m] = ((res->fields[FIELD_Vm]<<M_width)|(res->fields[FIELD_M])); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + } + /* pcode: fmt_idx = dp_operation */ + res->fields[FIELD_fmt_idx] = res->fields[FIELD_dp_operation]; + res->fields_mask[FIELD_fmt_idx >> 6] |= 1LL << (FIELD_fmt_idx & 63); + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* Encoding T1 */ + /* pattern="1110,11100,D.1,01,Vn.4,Vd.4,101,sz.1,N.1,op.1,M.1,0,Vm.4" width=32 stringency=20 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFFB00E10)==0xEE100A00)) { + res->instrSize = 32; + if(!(req->arch & ARCH_VFPv2) && !(req->arch & ARCH_VFPv3)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_D] = (instr & 0x400000)>>22; + res->fields_mask[FIELD_D >> 6] |= 1LL << (FIELD_D & 63); + char D_width = 1; + res->fields[FIELD_Vn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Vn >> 6] |= 1LL << (FIELD_Vn & 63); + char Vn_width = 4; + res->fields[FIELD_Vd] = (instr & 0xF000)>>12; + res->fields_mask[FIELD_Vd >> 6] |= 1LL << (FIELD_Vd & 63); + char Vd_width = 4; + res->fields[FIELD_sz] = (instr & 0x100)>>8; + res->fields_mask[FIELD_sz >> 6] |= 1LL << (FIELD_sz & 63); + char sz_width = 1; + res->fields[FIELD_N] = (instr & 0x80)>>7; + res->fields_mask[FIELD_N >> 6] |= 1LL << (FIELD_N & 63); + char N_width = 1; + res->fields[FIELD_op] = (instr & 0x40)>>6; + res->fields_mask[FIELD_op >> 6] |= 1LL << (FIELD_op & 63); + char op_width = 1; + res->fields[FIELD_M] = (instr & 0x20)>>5; + res->fields_mask[FIELD_M >> 6] |= 1LL << (FIELD_M & 63); + char M_width = 1; + res->fields[FIELD_Vm] = instr & 0xF; + res->fields_mask[FIELD_Vm >> 6] |= 1LL << (FIELD_Vm & 63); + char Vm_width = 4; + + static const instruction_format instr_formats[] = + { + { /* VNMLS<c>.F32 <Sd>,<Sn>,<Sm> */ + "vnmls.f32", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_F32, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"s","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_n,FIELD_UNINIT,"s","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_m,FIELD_UNINIT,"s","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + { /* VNMLS<c>.F64 <Dd>,<Dn>,<Dm> */ + "vnmls.f64", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_F64, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_n,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_m,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + { /* VNMLA<c>.F32 <Sd>,<Sn>,<Sm> */ + "vnmla.f32", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_F32, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"s","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_n,FIELD_UNINIT,"s","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_m,FIELD_UNINIT,"s","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + { /* VNMLA<c>.F64 <Dd>,<Dn>,<Dm> */ + "vnmla.f64", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_F64, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_n,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_m,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 4; + res->mnem = armv7::ARMV7_VNMLS; + + /* pcode: dp_operation = (sz == '1') */ + res->fields[FIELD_dp_operation] = ((res->fields[FIELD_sz]) == (0x1)); + res->fields_mask[FIELD_dp_operation >> 6] |= 1LL << (FIELD_dp_operation & 63); + /* pcode: d = if dp_operation then UInt(D:Vd) else UInt(Vd:D) */ + if(res->fields[FIELD_dp_operation]) { + res->fields[FIELD_d] = ((res->fields[FIELD_D]<<Vd_width)|(res->fields[FIELD_Vd])); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + } + else { + res->fields[FIELD_d] = ((res->fields[FIELD_Vd]<<D_width)|(res->fields[FIELD_D])); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + } + /* pcode: n = if dp_operation then UInt(N:Vn) else UInt(Vn:N) */ + if(res->fields[FIELD_dp_operation]) { + res->fields[FIELD_n] = ((res->fields[FIELD_N]<<Vn_width)|(res->fields[FIELD_Vn])); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + } + else { + res->fields[FIELD_n] = ((res->fields[FIELD_Vn]<<N_width)|(res->fields[FIELD_N])); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + } + /* pcode: m = if dp_operation then UInt(M:Vm) else UInt(Vm:M) */ + if(res->fields[FIELD_dp_operation]) { + res->fields[FIELD_m] = ((res->fields[FIELD_M]<<Vm_width)|(res->fields[FIELD_Vm])); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + } + else { + res->fields[FIELD_m] = ((res->fields[FIELD_Vm]<<M_width)|(res->fields[FIELD_M])); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + } + /* pcode: fmt_idx = (op * 2) + dp_operation */ + res->fields[FIELD_fmt_idx] = (((res->fields[FIELD_op]) * (2))) + (res->fields[FIELD_dp_operation]); + res->fields_mask[FIELD_fmt_idx >> 6] |= 1LL << (FIELD_fmt_idx & 63); + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: 881CD71A +int vorn_register(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + /* Encoding T1 */ + /* pattern="111x,xx1x,0,D.1,11,Vn.4,Vd.4,0001,N.1,Q.1,M.1,1,Vm.4" width=32 stringency=16 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xE2B00F10)==0xE2300110)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ADVSIMD)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_D] = (instr & 0x400000)>>22; + res->fields_mask[FIELD_D >> 6] |= 1LL << (FIELD_D & 63); + char D_width = 1; + res->fields[FIELD_Vn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Vn >> 6] |= 1LL << (FIELD_Vn & 63); + char Vn_width = 4; + res->fields[FIELD_Vd] = (instr & 0xF000)>>12; + res->fields_mask[FIELD_Vd >> 6] |= 1LL << (FIELD_Vd & 63); + char Vd_width = 4; + res->fields[FIELD_N] = (instr & 0x80)>>7; + res->fields_mask[FIELD_N >> 6] |= 1LL << (FIELD_N & 63); + char N_width = 1; + res->fields[FIELD_Q] = (instr & 0x40)>>6; + res->fields_mask[FIELD_Q >> 6] |= 1LL << (FIELD_Q & 63); + char Q_width = 1; + res->fields[FIELD_M] = (instr & 0x20)>>5; + res->fields_mask[FIELD_M >> 6] |= 1LL << (FIELD_M & 63); + char M_width = 1; + res->fields[FIELD_Vm] = instr & 0xF; + res->fields_mask[FIELD_Vm >> 6] |= 1LL << (FIELD_Vm & 63); + char Vm_width = 4; + + static const instruction_format instr_formats[] = + { + { /* VORN<c> <Dd>,<Dn>,<Dm> */ + "vorn", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_n,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_m,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + { /* VORN<c> <Qd>,<Qn>,<Qm> */ + "vorn", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"q","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_n,FIELD_UNINIT,"q","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_m,FIELD_UNINIT,"q","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 2; + res->mnem = armv7::ARMV7_VORN; + + /* pcode: if Q == '1' && (Vd<0> == '1' || Vn<0> == '1' || Vm<0> == '1') then UNDEFINED */ + if(((res->fields[FIELD_Q]) == (0x1)) && ((((((res->fields[FIELD_Vd] & 1)) == (0x1)) || (((res->fields[FIELD_Vn] & 1)) == (0x1))) || (((res->fields[FIELD_Vm] & 1)) == (0x1))))) { + res->status |= STATUS_UNDEFINED; + } + /* pcode: d = UInt(D:Vd) */ + res->fields[FIELD_d] = ((res->fields[FIELD_D]<<Vd_width)|(res->fields[FIELD_Vd])); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: n = UInt(N:Vn) */ + res->fields[FIELD_n] = ((res->fields[FIELD_N]<<Vn_width)|(res->fields[FIELD_Vn])); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: m = UInt(M:Vm) */ + res->fields[FIELD_m] = ((res->fields[FIELD_M]<<Vm_width)|(res->fields[FIELD_Vm])); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + /* pcode: regs = if Q == '0' then 1 else 2 */ + if((res->fields[FIELD_Q]) == (0x0)) { + res->fields[FIELD_regs] = 1; + res->fields_mask[FIELD_regs >> 6] |= 1LL << (FIELD_regs & 63); + } + else { + res->fields[FIELD_regs] = 2; + res->fields_mask[FIELD_regs >> 6] |= 1LL << (FIELD_regs & 63); + } + /* pcode: fmt_idx = (Q == '1') */ + res->fields[FIELD_fmt_idx] = ((res->fields[FIELD_Q]) == (0x1)); + res->fields_mask[FIELD_fmt_idx >> 6] |= 1LL << (FIELD_fmt_idx & 63); + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: 5FE7F2EF +int vorr_immediate(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + /* Encoding T1 */ + /* pattern="111,i.1,1111,1,D.1,000,imm3.3,Vd.4,cmode.4,0,Q.1,0,1,imm4.4" width=32 stringency=17 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xEFB800B0)==0xEF800010)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ADVSIMD)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_i] = (instr & 0x10000000)>>28; + res->fields_mask[FIELD_i >> 6] |= 1LL << (FIELD_i & 63); + char i_width = 1; + res->fields[FIELD_D] = (instr & 0x400000)>>22; + res->fields_mask[FIELD_D >> 6] |= 1LL << (FIELD_D & 63); + char D_width = 1; + res->fields[FIELD_imm3] = (instr & 0x70000)>>16; + res->fields_mask[FIELD_imm3 >> 6] |= 1LL << (FIELD_imm3 & 63); + char imm3_width = 3; + res->fields[FIELD_Vd] = (instr & 0xF000)>>12; + res->fields_mask[FIELD_Vd >> 6] |= 1LL << (FIELD_Vd & 63); + char Vd_width = 4; + res->fields[FIELD_cmode] = (instr & 0xF00)>>8; + res->fields_mask[FIELD_cmode >> 6] |= 1LL << (FIELD_cmode & 63); + char cmode_width = 4; + res->fields[FIELD_Q] = (instr & 0x40)>>6; + res->fields_mask[FIELD_Q >> 6] |= 1LL << (FIELD_Q & 63); + char Q_width = 1; + res->fields[FIELD_imm4] = instr & 0xF; + res->fields_mask[FIELD_imm4 >> 6] |= 1LL << (FIELD_imm4 & 63); + char imm4_width = 4; + + static const instruction_format instr_formats[] = + { + { /* VORR<c>.<dt> <Dd>,#<imm64> */ + "vorr", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_VFP_DATA_SIZE, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_IMM64,FIELD_UNINIT,FIELD_UNINIT,"#","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + { /* VORR<c>.<dt> <Qd>,#<imm64> */ + "vorr", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_VFP_DATA_SIZE, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"q","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_IMM64,FIELD_UNINIT,FIELD_UNINIT,"#","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 2; + res->mnem = armv7::ARMV7_VORR; + + /* pcode: if cmode<0> == '0' || cmode<3:2> == '11' then SEE VMOV (immediate) */ + if((((res->fields[FIELD_cmode] & 1)) == (0x0)) || ((((res->fields[FIELD_cmode] >> 2) & 0x3)) == (0x3))) { + + return vmov_immediate(req, res); + } + /* pcode: if Q == '1' && Vd<0> == '1' then UNDEFINED */ + if(((res->fields[FIELD_Q]) == (0x1)) && (((res->fields[FIELD_Vd] & 1)) == (0x1))) { + res->status |= STATUS_UNDEFINED; + } + /* pcode: imm64l = AdvSIMDExpandImm('0', cmode, i:imm3:imm4, 1) */ + res->fields[FIELD_imm64l] = AdvSIMDExpandImm(0x0, res->fields[FIELD_cmode], (res->fields[FIELD_i]<<(4+3))|(res->fields[FIELD_imm3]<<4)|(res->fields[FIELD_imm4]), 1); + res->fields_mask[FIELD_imm64l >> 6] |= 1LL << (FIELD_imm64l & 63); + /* pcode: imm64h = AdvSIMDExpandImm('0', cmode, i:imm3:imm4, 0) */ + res->fields[FIELD_imm64h] = AdvSIMDExpandImm(0x0, res->fields[FIELD_cmode], (res->fields[FIELD_i]<<(4+3))|(res->fields[FIELD_imm3]<<4)|(res->fields[FIELD_imm4]), 0); + res->fields_mask[FIELD_imm64h >> 6] |= 1LL << (FIELD_imm64h & 63); + /* pcode: d = UInt(D:Vd) */ + res->fields[FIELD_d] = ((res->fields[FIELD_D]<<Vd_width)|(res->fields[FIELD_Vd])); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: regs = if Q == '0' then 1 else 2 */ + if((res->fields[FIELD_Q]) == (0x0)) { + res->fields[FIELD_regs] = 1; + res->fields_mask[FIELD_regs >> 6] |= 1LL << (FIELD_regs & 63); + } + else { + res->fields[FIELD_regs] = 2; + res->fields_mask[FIELD_regs >> 6] |= 1LL << (FIELD_regs & 63); + } + /* pcode: iword = TRUE */ + res->fields[FIELD_iword] = 1; + res->fields_mask[FIELD_iword >> 6] |= 1LL << (FIELD_iword & 63); + /* pcode: fmt_idx = (Q == '1') */ + res->fields[FIELD_fmt_idx] = ((res->fields[FIELD_Q]) == (0x1)); + res->fields_mask[FIELD_fmt_idx >> 6] |= 1LL << (FIELD_fmt_idx & 63); + /* pcode: dt = 1 */ + res->fields[FIELD_dt] = 1; + res->fields_mask[FIELD_dt >> 6] |= 1LL << (FIELD_dt & 63); + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: CF433343 +int vorr_register(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + /* Encoding T1 */ + /* pattern="1110,xx11,0,D.1,10,Vn.4,Vd.4,0001,N.1,Q.1,M.1,1,Vm.4" width=32 stringency=18 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xF3B00F10)==0xE3200110)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ADVSIMD)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_D] = (instr & 0x400000)>>22; + res->fields_mask[FIELD_D >> 6] |= 1LL << (FIELD_D & 63); + char D_width = 1; + res->fields[FIELD_Vn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Vn >> 6] |= 1LL << (FIELD_Vn & 63); + char Vn_width = 4; + res->fields[FIELD_Vd] = (instr & 0xF000)>>12; + res->fields_mask[FIELD_Vd >> 6] |= 1LL << (FIELD_Vd & 63); + char Vd_width = 4; + res->fields[FIELD_N] = (instr & 0x80)>>7; + res->fields_mask[FIELD_N >> 6] |= 1LL << (FIELD_N & 63); + char N_width = 1; + res->fields[FIELD_Q] = (instr & 0x40)>>6; + res->fields_mask[FIELD_Q >> 6] |= 1LL << (FIELD_Q & 63); + char Q_width = 1; + res->fields[FIELD_M] = (instr & 0x20)>>5; + res->fields_mask[FIELD_M >> 6] |= 1LL << (FIELD_M & 63); + char M_width = 1; + res->fields[FIELD_Vm] = instr & 0xF; + res->fields_mask[FIELD_Vm >> 6] |= 1LL << (FIELD_Vm & 63); + char Vm_width = 4; + + static const instruction_format instr_formats[] = + { + { /* VORR<c> <Dd>,<Dn>,<Dm> */ + "vorr", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_n,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_m,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + { /* VORR<c> <Qd>,<Qn>,<Qm> */ + "vorr", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"q","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_n,FIELD_UNINIT,"q","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_m,FIELD_UNINIT,"q","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 2; + res->mnem = armv7::ARMV7_VORR; + + /* pcode: if N == M && Vn == Vm then SEE vmov_register */ + if(((res->fields[FIELD_N]) == (res->fields[FIELD_M])) && ((res->fields[FIELD_Vn]) == (res->fields[FIELD_Vm]))) { + + return vmov_register(req, res); + } + /* pcode: if Q == '1' && (Vd<0> == '1' || Vn<0> == '1' || Vm<0> == '1') then UNDEFINED */ + if(((res->fields[FIELD_Q]) == (0x1)) && ((((((res->fields[FIELD_Vd] & 1)) == (0x1)) || (((res->fields[FIELD_Vn] & 1)) == (0x1))) || (((res->fields[FIELD_Vm] & 1)) == (0x1))))) { + res->status |= STATUS_UNDEFINED; + } + /* pcode: d = UInt(D:Vd) */ + res->fields[FIELD_d] = ((res->fields[FIELD_D]<<Vd_width)|(res->fields[FIELD_Vd])); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: n = UInt(N:Vn) */ + res->fields[FIELD_n] = ((res->fields[FIELD_N]<<Vn_width)|(res->fields[FIELD_Vn])); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: m = UInt(M:Vm) */ + res->fields[FIELD_m] = ((res->fields[FIELD_M]<<Vm_width)|(res->fields[FIELD_Vm])); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + /* pcode: regs = if Q == '0' then 1 else 2 */ + if((res->fields[FIELD_Q]) == (0x0)) { + res->fields[FIELD_regs] = 1; + res->fields_mask[FIELD_regs >> 6] |= 1LL << (FIELD_regs & 63); + } + else { + res->fields[FIELD_regs] = 2; + res->fields_mask[FIELD_regs >> 6] |= 1LL << (FIELD_regs & 63); + } + /* pcode: fmt_idx = (Q == '1') */ + res->fields[FIELD_fmt_idx] = ((res->fields[FIELD_Q]) == (0x1)); + res->fields_mask[FIELD_fmt_idx >> 6] |= 1LL << (FIELD_fmt_idx & 63); + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: 5E1A926E +int vpadal(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + res->group = INSN_GROUP_NEON; + /* Encoding T1 */ + /* pattern="1111,xx11,1,D.1,11,size.2,00,Vd.4,0110,op.1,Q.1,M.1,0,Vm.4" width=32 stringency=20 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xF3B30F10)==0xF3B00600)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ADVSIMD)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_D] = (instr & 0x400000)>>22; + res->fields_mask[FIELD_D >> 6] |= 1LL << (FIELD_D & 63); + char D_width = 1; + res->fields[FIELD_size] = (instr & 0xC0000)>>18; + res->fields_mask[FIELD_size >> 6] |= 1LL << (FIELD_size & 63); + char size_width = 2; + res->fields[FIELD_Vd] = (instr & 0xF000)>>12; + res->fields_mask[FIELD_Vd >> 6] |= 1LL << (FIELD_Vd & 63); + char Vd_width = 4; + res->fields[FIELD_op] = (instr & 0x80)>>7; + res->fields_mask[FIELD_op >> 6] |= 1LL << (FIELD_op & 63); + char op_width = 1; + res->fields[FIELD_Q] = (instr & 0x40)>>6; + res->fields_mask[FIELD_Q >> 6] |= 1LL << (FIELD_Q & 63); + char Q_width = 1; + res->fields[FIELD_M] = (instr & 0x20)>>5; + res->fields_mask[FIELD_M >> 6] |= 1LL << (FIELD_M & 63); + char M_width = 1; + res->fields[FIELD_Vm] = instr & 0xF; + res->fields_mask[FIELD_Vm >> 6] |= 1LL << (FIELD_Vm & 63); + char Vm_width = 4; + + static const instruction_format instr_formats[] = + { + { /* VPADAL<c>.<dt> <Dd>,<Dm> */ + "vpadal", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_VFP_DATA_SIZE, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_m,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + { /* VPADAL<c>.<dt> <Qd>,<Qm> */ + "vpadal", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_VFP_DATA_SIZE, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"q","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_m,FIELD_UNINIT,"q","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 2; + res->mnem = armv7::ARMV7_VPADAL; + + /* pcode: if size == '11' then UNDEFINED */ + if((res->fields[FIELD_size]) == (0x3)) { + res->status |= STATUS_UNDEFINED; + } + /* pcode: if (Q == '1' && (Vd<0> == '1' || Vm<0> == '1')) then UNDEFINED */ + if((((res->fields[FIELD_Q]) == (0x1)) && (((((res->fields[FIELD_Vd] & 1)) == (0x1)) || (((res->fields[FIELD_Vm] & 1)) == (0x1)))))) { + res->status |= STATUS_UNDEFINED; + } + /* pcode: unsigned = (op == '1') */ + res->fields[FIELD_unsigned] = ((res->fields[FIELD_op]) == (0x1)); + res->fields_mask[FIELD_unsigned >> 6] |= 1LL << (FIELD_unsigned & 63); + /* pcode: esize = 8 << UInt(size) */ + res->fields[FIELD_esize] = (8) << ((res->fields[FIELD_size])); + res->fields_mask[FIELD_esize >> 6] |= 1LL << (FIELD_esize & 63); + /* pcode: elements = 64 DIV esize */ + res->fields[FIELD_elements] = ((res->fields[FIELD_esize]) ? ((64) / (res->fields[FIELD_esize])) : 0); + res->fields_mask[FIELD_elements >> 6] |= 1LL << (FIELD_elements & 63); + /* pcode: d = UInt(D:Vd) */ + res->fields[FIELD_d] = ((res->fields[FIELD_D]<<Vd_width)|(res->fields[FIELD_Vd])); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: m = UInt(M:Vm) */ + res->fields[FIELD_m] = ((res->fields[FIELD_M]<<Vm_width)|(res->fields[FIELD_Vm])); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + /* pcode: regs = if Q == '0' then 1 else 2 */ + if((res->fields[FIELD_Q]) == (0x0)) { + res->fields[FIELD_regs] = 1; + res->fields_mask[FIELD_regs >> 6] |= 1LL << (FIELD_regs & 63); + } + else { + res->fields[FIELD_regs] = 2; + res->fields_mask[FIELD_regs >> 6] |= 1LL << (FIELD_regs & 63); + } + /* pcode: fmt_idx = (Q == '1') */ + res->fields[FIELD_fmt_idx] = ((res->fields[FIELD_Q]) == (0x1)); + res->fields_mask[FIELD_fmt_idx >> 6] |= 1LL << (FIELD_fmt_idx & 63); + /* pcode: dt = UInt(op:size) */ + res->fields[FIELD_dt] = ((res->fields[FIELD_op]<<size_width)|(res->fields[FIELD_size])); + res->fields_mask[FIELD_dt >> 6] |= 1LL << (FIELD_dt & 63); + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: 3CC297E9 +int vpadd_float(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + res->group = INSN_GROUP_NEON; + /* Encoding T1 */ + /* pattern="1111,xx11,0,D.1,0,sz.1,Vn.4,Vd.4,1101,N.1,Q.1,M.1,0,Vm.4" width=32 stringency=18 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xF3A00F10)==0xF3000D00)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ADVSIMD)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_D] = (instr & 0x400000)>>22; + res->fields_mask[FIELD_D >> 6] |= 1LL << (FIELD_D & 63); + char D_width = 1; + res->fields[FIELD_sz] = (instr & 0x100000)>>20; + res->fields_mask[FIELD_sz >> 6] |= 1LL << (FIELD_sz & 63); + char sz_width = 1; + res->fields[FIELD_Vn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Vn >> 6] |= 1LL << (FIELD_Vn & 63); + char Vn_width = 4; + res->fields[FIELD_Vd] = (instr & 0xF000)>>12; + res->fields_mask[FIELD_Vd >> 6] |= 1LL << (FIELD_Vd & 63); + char Vd_width = 4; + res->fields[FIELD_N] = (instr & 0x80)>>7; + res->fields_mask[FIELD_N >> 6] |= 1LL << (FIELD_N & 63); + char N_width = 1; + res->fields[FIELD_Q] = (instr & 0x40)>>6; + res->fields_mask[FIELD_Q >> 6] |= 1LL << (FIELD_Q & 63); + char Q_width = 1; + res->fields[FIELD_M] = (instr & 0x20)>>5; + res->fields_mask[FIELD_M >> 6] |= 1LL << (FIELD_M & 63); + char M_width = 1; + res->fields[FIELD_Vm] = instr & 0xF; + res->fields_mask[FIELD_Vm >> 6] |= 1LL << (FIELD_Vm & 63); + char Vm_width = 4; + + static const instruction_format instr_formats[] = + { + { /* VPADD<c>.F32 <Dd>,<Dn>,<Dm> */ + "vpadd.f32", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_F32, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_n,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_m,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_VPADD; + + /* pcode: if (sz == '1' || Q == '1') then UNDEFINED */ + if((((res->fields[FIELD_sz]) == (0x1)) || ((res->fields[FIELD_Q]) == (0x1)))) { + res->status |= STATUS_UNDEFINED; + } + /* pcode: esize = 32 */ + res->fields[FIELD_esize] = 32; + res->fields_mask[FIELD_esize >> 6] |= 1LL << (FIELD_esize & 63); + /* pcode: elements = 2 */ + res->fields[FIELD_elements] = 2; + res->fields_mask[FIELD_elements >> 6] |= 1LL << (FIELD_elements & 63); + /* pcode: d = UInt(D:Vd) */ + res->fields[FIELD_d] = ((res->fields[FIELD_D]<<Vd_width)|(res->fields[FIELD_Vd])); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: n = UInt(N:Vn) */ + res->fields[FIELD_n] = ((res->fields[FIELD_N]<<Vn_width)|(res->fields[FIELD_Vn])); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: m = UInt(M:Vm) */ + res->fields[FIELD_m] = ((res->fields[FIELD_M]<<Vm_width)|(res->fields[FIELD_Vm])); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: 72549138 +int vpadd_integer(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + res->group = INSN_GROUP_NEON; + /* Encoding T1 */ + /* pattern="111x,xx1x,0,D.1,size.2,Vn.4,Vd.4,1011,N.1,Q.1,M.1,1,Vm.4" width=32 stringency=14 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xE2800F10)==0xE2000B10)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ADVSIMD)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_D] = (instr & 0x400000)>>22; + res->fields_mask[FIELD_D >> 6] |= 1LL << (FIELD_D & 63); + char D_width = 1; + res->fields[FIELD_size] = (instr & 0x300000)>>20; + res->fields_mask[FIELD_size >> 6] |= 1LL << (FIELD_size & 63); + char size_width = 2; + res->fields[FIELD_Vn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Vn >> 6] |= 1LL << (FIELD_Vn & 63); + char Vn_width = 4; + res->fields[FIELD_Vd] = (instr & 0xF000)>>12; + res->fields_mask[FIELD_Vd >> 6] |= 1LL << (FIELD_Vd & 63); + char Vd_width = 4; + res->fields[FIELD_N] = (instr & 0x80)>>7; + res->fields_mask[FIELD_N >> 6] |= 1LL << (FIELD_N & 63); + char N_width = 1; + res->fields[FIELD_Q] = (instr & 0x40)>>6; + res->fields_mask[FIELD_Q >> 6] |= 1LL << (FIELD_Q & 63); + char Q_width = 1; + res->fields[FIELD_M] = (instr & 0x20)>>5; + res->fields_mask[FIELD_M >> 6] |= 1LL << (FIELD_M & 63); + char M_width = 1; + res->fields[FIELD_Vm] = instr & 0xF; + res->fields_mask[FIELD_Vm >> 6] |= 1LL << (FIELD_Vm & 63); + char Vm_width = 4; + + static const instruction_format instr_formats[] = + { + { /* VPADD<c>.<dt> <Dd>,<Dn>,<Dm> */ + "vpadd", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_VFP_DATA_SIZE, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_n,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_m,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_VPADD; + + /* pcode: if (size == '11' || Q == '1') then UNDEFINED */ + if((((res->fields[FIELD_size]) == (0x3)) || ((res->fields[FIELD_Q]) == (0x1)))) { + res->status |= STATUS_UNDEFINED; + } + /* pcode: esize = 8 << UInt(size) */ + res->fields[FIELD_esize] = (8) << ((res->fields[FIELD_size])); + res->fields_mask[FIELD_esize >> 6] |= 1LL << (FIELD_esize & 63); + /* pcode: elements = 64 DIV esize */ + res->fields[FIELD_elements] = ((res->fields[FIELD_esize]) ? ((64) / (res->fields[FIELD_esize])) : 0); + res->fields_mask[FIELD_elements >> 6] |= 1LL << (FIELD_elements & 63); + /* pcode: d = UInt(D:Vd) */ + res->fields[FIELD_d] = ((res->fields[FIELD_D]<<Vd_width)|(res->fields[FIELD_Vd])); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: n = UInt(N:Vn) */ + res->fields[FIELD_n] = ((res->fields[FIELD_N]<<Vn_width)|(res->fields[FIELD_Vn])); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: m = UInt(M:Vm) */ + res->fields[FIELD_m] = ((res->fields[FIELD_M]<<Vm_width)|(res->fields[FIELD_Vm])); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + /* pcode: iword = TRUE */ + res->fields[FIELD_iword] = 1; + res->fields_mask[FIELD_iword >> 6] |= 1LL << (FIELD_iword & 63); + /* pcode: dt = size */ + res->fields[FIELD_dt] = res->fields[FIELD_size]; + res->fields_mask[FIELD_dt >> 6] |= 1LL << (FIELD_dt & 63); + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: 3CE519FE +int vpaddl(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + res->group = INSN_GROUP_NEON; + /* Encoding T1 */ + /* pattern="1111,xx11,1,D.1,11,size.2,00,Vd.4,0010,op.1,Q.1,M.1,0,Vm.4" width=32 stringency=20 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xF3B30F10)==0xF3B00200)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ADVSIMD)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_D] = (instr & 0x400000)>>22; + res->fields_mask[FIELD_D >> 6] |= 1LL << (FIELD_D & 63); + char D_width = 1; + res->fields[FIELD_size] = (instr & 0xC0000)>>18; + res->fields_mask[FIELD_size >> 6] |= 1LL << (FIELD_size & 63); + char size_width = 2; + res->fields[FIELD_Vd] = (instr & 0xF000)>>12; + res->fields_mask[FIELD_Vd >> 6] |= 1LL << (FIELD_Vd & 63); + char Vd_width = 4; + res->fields[FIELD_op] = (instr & 0x80)>>7; + res->fields_mask[FIELD_op >> 6] |= 1LL << (FIELD_op & 63); + char op_width = 1; + res->fields[FIELD_Q] = (instr & 0x40)>>6; + res->fields_mask[FIELD_Q >> 6] |= 1LL << (FIELD_Q & 63); + char Q_width = 1; + res->fields[FIELD_M] = (instr & 0x20)>>5; + res->fields_mask[FIELD_M >> 6] |= 1LL << (FIELD_M & 63); + char M_width = 1; + res->fields[FIELD_Vm] = instr & 0xF; + res->fields_mask[FIELD_Vm >> 6] |= 1LL << (FIELD_Vm & 63); + char Vm_width = 4; + + static const instruction_format instr_formats[] = + { + { /* VPADDL<c>.<dt> <Dd>,<Dm> */ + "vpaddl", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_VFP_DATA_SIZE, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_m,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + { /* VPADDL<c>.<dt> <Qd>,<Qm> */ + "vpaddl", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_VFP_DATA_SIZE, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"q","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_m,FIELD_UNINIT,"q","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 2; + res->mnem = armv7::ARMV7_VPADDL; + + /* pcode: if size == '11' then UNDEFINED */ + if((res->fields[FIELD_size]) == (0x3)) { + res->status |= STATUS_UNDEFINED; + } + /* pcode: if (Q == '1' && (Vd<0> == '1' || Vm<0> == '1')) then UNDEFINED */ + if((((res->fields[FIELD_Q]) == (0x1)) && (((((res->fields[FIELD_Vd] & 1)) == (0x1)) || (((res->fields[FIELD_Vm] & 1)) == (0x1)))))) { + res->status |= STATUS_UNDEFINED; + } + /* pcode: unsigned = (op == '1') */ + res->fields[FIELD_unsigned] = ((res->fields[FIELD_op]) == (0x1)); + res->fields_mask[FIELD_unsigned >> 6] |= 1LL << (FIELD_unsigned & 63); + /* pcode: esize = 8 << UInt(size) */ + res->fields[FIELD_esize] = (8) << ((res->fields[FIELD_size])); + res->fields_mask[FIELD_esize >> 6] |= 1LL << (FIELD_esize & 63); + /* pcode: elements = 64 DIV esize */ + res->fields[FIELD_elements] = ((res->fields[FIELD_esize]) ? ((64) / (res->fields[FIELD_esize])) : 0); + res->fields_mask[FIELD_elements >> 6] |= 1LL << (FIELD_elements & 63); + /* pcode: d = UInt(D:Vd) */ + res->fields[FIELD_d] = ((res->fields[FIELD_D]<<Vd_width)|(res->fields[FIELD_Vd])); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: m = UInt(M:Vm) */ + res->fields[FIELD_m] = ((res->fields[FIELD_M]<<Vm_width)|(res->fields[FIELD_Vm])); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + /* pcode: regs = if Q == '0' then 1 else 2 */ + if((res->fields[FIELD_Q]) == (0x0)) { + res->fields[FIELD_regs] = 1; + res->fields_mask[FIELD_regs >> 6] |= 1LL << (FIELD_regs & 63); + } + else { + res->fields[FIELD_regs] = 2; + res->fields_mask[FIELD_regs >> 6] |= 1LL << (FIELD_regs & 63); + } + /* pcode: fmt_idx = (Q == '1') */ + res->fields[FIELD_fmt_idx] = ((res->fields[FIELD_Q]) == (0x1)); + res->fields_mask[FIELD_fmt_idx >> 6] |= 1LL << (FIELD_fmt_idx & 63); + /* pcode: dt = UInt(op:size) */ + res->fields[FIELD_dt] = ((res->fields[FIELD_op]<<size_width)|(res->fields[FIELD_size])); + res->fields_mask[FIELD_dt >> 6] |= 1LL << (FIELD_dt & 63); + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: 5FCBAB5C +int vpmax_float(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + res->group = INSN_GROUP_NEON; + /* Encoding T1 */ + /* pattern="1111,xx11,0,D.1,op.1,sz.1,Vn.4,Vd.4,1111,N.1,Q.1,M.1,0,Vm.4" width=32 stringency=18 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xF3800F10)==0xF3000F00)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ADVSIMD)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_D] = (instr & 0x400000)>>22; + res->fields_mask[FIELD_D >> 6] |= 1LL << (FIELD_D & 63); + char D_width = 1; + res->fields[FIELD_op] = (instr & 0x200000)>>21; + res->fields_mask[FIELD_op >> 6] |= 1LL << (FIELD_op & 63); + char op_width = 1; + res->fields[FIELD_sz] = (instr & 0x100000)>>20; + res->fields_mask[FIELD_sz >> 6] |= 1LL << (FIELD_sz & 63); + char sz_width = 1; + res->fields[FIELD_Vn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Vn >> 6] |= 1LL << (FIELD_Vn & 63); + char Vn_width = 4; + res->fields[FIELD_Vd] = (instr & 0xF000)>>12; + res->fields_mask[FIELD_Vd >> 6] |= 1LL << (FIELD_Vd & 63); + char Vd_width = 4; + res->fields[FIELD_N] = (instr & 0x80)>>7; + res->fields_mask[FIELD_N >> 6] |= 1LL << (FIELD_N & 63); + char N_width = 1; + res->fields[FIELD_Q] = (instr & 0x40)>>6; + res->fields_mask[FIELD_Q >> 6] |= 1LL << (FIELD_Q & 63); + char Q_width = 1; + res->fields[FIELD_M] = (instr & 0x20)>>5; + res->fields_mask[FIELD_M >> 6] |= 1LL << (FIELD_M & 63); + char M_width = 1; + res->fields[FIELD_Vm] = instr & 0xF; + res->fields_mask[FIELD_Vm >> 6] |= 1LL << (FIELD_Vm & 63); + char Vm_width = 4; + + static const instruction_format instr_formats[] = + { + { /* VPMAX<c>.F32 <Dd>,<Dn>,<Dm> */ + "vpmax.f32", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_F32, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_n,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_m,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + { /* VPMIN<c>.F32 <Dd>,<Dn>,<Dm> */ + "vpmin.f32", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_F32, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_n,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_m,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 2; + res->mnem = armv7::ARMV7_VPMAX; + + /* pcode: if (sz == '1' || Q == '1') then UNDEFINED */ + if((((res->fields[FIELD_sz]) == (0x1)) || ((res->fields[FIELD_Q]) == (0x1)))) { + res->status |= STATUS_UNDEFINED; + } + /* pcode: esize = 32 */ + res->fields[FIELD_esize] = 32; + res->fields_mask[FIELD_esize >> 6] |= 1LL << (FIELD_esize & 63); + /* pcode: elements = 2 */ + res->fields[FIELD_elements] = 2; + res->fields_mask[FIELD_elements >> 6] |= 1LL << (FIELD_elements & 63); + /* pcode: d = UInt(D:Vd) */ + res->fields[FIELD_d] = ((res->fields[FIELD_D]<<Vd_width)|(res->fields[FIELD_Vd])); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: n = UInt(N:Vn) */ + res->fields[FIELD_n] = ((res->fields[FIELD_N]<<Vn_width)|(res->fields[FIELD_Vn])); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: m = UInt(M:Vm) */ + res->fields[FIELD_m] = ((res->fields[FIELD_M]<<Vm_width)|(res->fields[FIELD_Vm])); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + /* pcode: fmt_idx = (op == '1') */ + res->fields[FIELD_fmt_idx] = ((res->fields[FIELD_op]) == (0x1)); + res->fields_mask[FIELD_fmt_idx >> 6] |= 1LL << (FIELD_fmt_idx & 63); + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: 3DD07569 +int vpmax_integer(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + res->group = INSN_GROUP_NEON; + /* Encoding T1 */ + /* pattern="111,U.1,1111,0,D.1,size.2,Vn.4,Vd.4,1010,N.1,Q.1,M.1,op.1,Vm.4" width=32 stringency=18 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xEF800F00)==0xEF000A00)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ADVSIMD)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_U] = (instr & 0x10000000)>>28; + res->fields_mask[FIELD_U >> 6] |= 1LL << (FIELD_U & 63); + char U_width = 1; + res->fields[FIELD_D] = (instr & 0x400000)>>22; + res->fields_mask[FIELD_D >> 6] |= 1LL << (FIELD_D & 63); + char D_width = 1; + res->fields[FIELD_size] = (instr & 0x300000)>>20; + res->fields_mask[FIELD_size >> 6] |= 1LL << (FIELD_size & 63); + char size_width = 2; + res->fields[FIELD_Vn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Vn >> 6] |= 1LL << (FIELD_Vn & 63); + char Vn_width = 4; + res->fields[FIELD_Vd] = (instr & 0xF000)>>12; + res->fields_mask[FIELD_Vd >> 6] |= 1LL << (FIELD_Vd & 63); + char Vd_width = 4; + res->fields[FIELD_N] = (instr & 0x80)>>7; + res->fields_mask[FIELD_N >> 6] |= 1LL << (FIELD_N & 63); + char N_width = 1; + res->fields[FIELD_Q] = (instr & 0x40)>>6; + res->fields_mask[FIELD_Q >> 6] |= 1LL << (FIELD_Q & 63); + char Q_width = 1; + res->fields[FIELD_M] = (instr & 0x20)>>5; + res->fields_mask[FIELD_M >> 6] |= 1LL << (FIELD_M & 63); + char M_width = 1; + res->fields[FIELD_op] = (instr & 0x10)>>4; + res->fields_mask[FIELD_op >> 6] |= 1LL << (FIELD_op & 63); + char op_width = 1; + res->fields[FIELD_Vm] = instr & 0xF; + res->fields_mask[FIELD_Vm >> 6] |= 1LL << (FIELD_Vm & 63); + char Vm_width = 4; + + static const instruction_format instr_formats[] = + { + { /* VPMAX<c>.<dt> <Dd>,<Dn>,<Dm> */ + "vpmax", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_VFP_DATA_SIZE, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_n,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_m,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + { /* VPMIN<c>.<dt> <Dd>,<Dn>,<Dm> */ + "vpmin", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_VFP_DATA_SIZE, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_n,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_m,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 2; + res->mnem = armv7::ARMV7_VPMAX; + + /* pcode: if (size == '11' || Q == '1') then UNDEFINED */ + if((((res->fields[FIELD_size]) == (0x3)) || ((res->fields[FIELD_Q]) == (0x1)))) { + res->status |= STATUS_UNDEFINED; + } + /* pcode: unsigned = (U == '1') */ + res->fields[FIELD_unsigned] = ((res->fields[FIELD_U]) == (0x1)); + res->fields_mask[FIELD_unsigned >> 6] |= 1LL << (FIELD_unsigned & 63); + /* pcode: esize = 8 << UInt(size) */ + res->fields[FIELD_esize] = (8) << ((res->fields[FIELD_size])); + res->fields_mask[FIELD_esize >> 6] |= 1LL << (FIELD_esize & 63); + /* pcode: elements = 64 DIV esize */ + res->fields[FIELD_elements] = ((res->fields[FIELD_esize]) ? ((64) / (res->fields[FIELD_esize])) : 0); + res->fields_mask[FIELD_elements >> 6] |= 1LL << (FIELD_elements & 63); + /* pcode: d = UInt(D:Vd) */ + res->fields[FIELD_d] = ((res->fields[FIELD_D]<<Vd_width)|(res->fields[FIELD_Vd])); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: n = UInt(N:Vn) */ + res->fields[FIELD_n] = ((res->fields[FIELD_N]<<Vn_width)|(res->fields[FIELD_Vn])); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: m = UInt(M:Vm) */ + res->fields[FIELD_m] = ((res->fields[FIELD_M]<<Vm_width)|(res->fields[FIELD_Vm])); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + /* pcode: fmt_idx = (op == '1') */ + res->fields[FIELD_fmt_idx] = ((res->fields[FIELD_op]) == (0x1)); + res->fields_mask[FIELD_fmt_idx >> 6] |= 1LL << (FIELD_fmt_idx & 63); + /* pcode: dt = UInt(U:size) */ + res->fields[FIELD_dt] = ((res->fields[FIELD_U]<<size_width)|(res->fields[FIELD_size])); + res->fields_mask[FIELD_dt >> 6] |= 1LL << (FIELD_dt & 63); + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: 1A1F516C +int vpop(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + res->group = INSN_GROUP_NEON; + /* Encoding T1 */ + /* pattern="cond.4,110,0,1,D.1,1,1,1101,Vd.4,1011,imm8.8" width=32 stringency=16 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFBF0F00)==0xCBD0B00)) { + res->instrSize = 32; + if(!(req->arch & ARCH_VFPv2) && !(req->arch & ARCH_VFPv3) && !(req->arch & ARCH_ADVSIMD)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = (instr & 0xF0000000)>>28; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + char cond_width = 4; + res->fields[FIELD_D] = (instr & 0x400000)>>22; + res->fields_mask[FIELD_D >> 6] |= 1LL << (FIELD_D & 63); + char D_width = 1; + res->fields[FIELD_Vd] = (instr & 0xF000)>>12; + res->fields_mask[FIELD_Vd >> 6] |= 1LL << (FIELD_Vd & 63); + char Vd_width = 4; + res->fields[FIELD_imm8] = instr & 0xFF; + res->fields_mask[FIELD_imm8 >> 6] |= 1LL << (FIELD_imm8 & 63); + char imm8_width = 8; + + static const instruction_format instr_formats[] = + { + { /* VPOP<c> <registers> */ + "vpop", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REGISTERS,FIELD_registers,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 1 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_VPOP; + + /* pcode: single_regs = FALSE */ + res->fields[FIELD_single_regs] = 0; + res->fields_mask[FIELD_single_regs >> 6] |= 1LL << (FIELD_single_regs & 63); + /* pcode: d = UInt(D:Vd) */ + res->fields[FIELD_d] = ((res->fields[FIELD_D]<<Vd_width)|(res->fields[FIELD_Vd])); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: imm32 = ZeroExtend(imm8:'00', 32) */ + res->fields[FIELD_imm32] = (res->fields[FIELD_imm8]<<2)|(0x0); + res->fields_mask[FIELD_imm32 >> 6] |= 1LL << (FIELD_imm32 & 63); + /* pcode: regs = UInt(imm8) / 2 */ + res->fields[FIELD_regs] = ((2) ? (((res->fields[FIELD_imm8])) / (2)) : 0); + res->fields_mask[FIELD_regs >> 6] |= 1LL << (FIELD_regs & 63); + /* pcode: if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE */ + if((((res->fields[FIELD_regs]) == (0)) || ((res->fields[FIELD_regs]) > (16))) || ((((res->fields[FIELD_d]) + (res->fields[FIELD_regs]))) > (32))) { + res->flags |= FLAG_UNPREDICTABLE; + } + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* Encoding T2 */ + /* pattern="cond.4,110,0,1,D.1,1,1,1101,Vd.4,1010,imm8.8" width=32 stringency=16 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFBF0F00)==0xCBD0A00)) { + res->instrSize = 32; + if(!(req->arch & ARCH_VFPv2) && !(req->arch & ARCH_VFPv3)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = (instr & 0xF0000000)>>28; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + char cond_width = 4; + res->fields[FIELD_D] = (instr & 0x400000)>>22; + res->fields_mask[FIELD_D >> 6] |= 1LL << (FIELD_D & 63); + char D_width = 1; + res->fields[FIELD_Vd] = (instr & 0xF000)>>12; + res->fields_mask[FIELD_Vd >> 6] |= 1LL << (FIELD_Vd & 63); + char Vd_width = 4; + res->fields[FIELD_imm8] = instr & 0xFF; + res->fields_mask[FIELD_imm8 >> 6] |= 1LL << (FIELD_imm8 & 63); + char imm8_width = 8; + + static const instruction_format instr_formats[] = + { + { /* VPOP<c> <registers> */ + "vpop", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REGISTERS,FIELD_registers,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 1 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_VPOP; + + /* pcode: single_regs = TRUE */ + res->fields[FIELD_single_regs] = 1; + res->fields_mask[FIELD_single_regs >> 6] |= 1LL << (FIELD_single_regs & 63); + /* pcode: d = UInt(Vd:D) */ + res->fields[FIELD_d] = ((res->fields[FIELD_Vd]<<D_width)|(res->fields[FIELD_D])); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: imm32 = ZeroExtend(imm8:'00', 32) */ + res->fields[FIELD_imm32] = (res->fields[FIELD_imm8]<<2)|(0x0); + res->fields_mask[FIELD_imm32 >> 6] |= 1LL << (FIELD_imm32 & 63); + /* pcode: regs = UInt(imm8) */ + res->fields[FIELD_regs] = (res->fields[FIELD_imm8]); + res->fields_mask[FIELD_regs >> 6] |= 1LL << (FIELD_regs & 63); + /* pcode: if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE */ + if((((res->fields[FIELD_regs]) == (0)) || ((res->fields[FIELD_regs]) > (16))) || ((((res->fields[FIELD_d]) + (res->fields[FIELD_regs]))) > (32))) { + res->flags |= FLAG_UNPREDICTABLE; + } + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: 524C58C7 +int vpush(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + res->group = INSN_GROUP_NEON; + /* Encoding T1 */ + /* pattern="cond.4,110,1,0,D.1,1,0,1101,Vd.4,1011,imm8.8" width=32 stringency=16 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFBF0F00)==0xD2D0B00)) { + res->instrSize = 32; + if(!(req->arch & ARCH_VFPv2) && !(req->arch & ARCH_VFPv3) && !(req->arch & ARCH_ADVSIMD)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = (instr & 0xF0000000)>>28; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + char cond_width = 4; + res->fields[FIELD_D] = (instr & 0x400000)>>22; + res->fields_mask[FIELD_D >> 6] |= 1LL << (FIELD_D & 63); + char D_width = 1; + res->fields[FIELD_Vd] = (instr & 0xF000)>>12; + res->fields_mask[FIELD_Vd >> 6] |= 1LL << (FIELD_Vd & 63); + char Vd_width = 4; + res->fields[FIELD_imm8] = instr & 0xFF; + res->fields_mask[FIELD_imm8 >> 6] |= 1LL << (FIELD_imm8 & 63); + char imm8_width = 8; + + static const instruction_format instr_formats[] = + { + { /* VPUSH<c> <registers> */ + "vpush", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REGISTERS,FIELD_registers,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 1 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_VPUSH; + + /* pcode: single_regs = FALSE */ + res->fields[FIELD_single_regs] = 0; + res->fields_mask[FIELD_single_regs >> 6] |= 1LL << (FIELD_single_regs & 63); + /* pcode: d = UInt(D:Vd) */ + res->fields[FIELD_d] = ((res->fields[FIELD_D]<<Vd_width)|(res->fields[FIELD_Vd])); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: imm32 = ZeroExtend(imm8:'00', 32) */ + res->fields[FIELD_imm32] = (res->fields[FIELD_imm8]<<2)|(0x0); + res->fields_mask[FIELD_imm32 >> 6] |= 1LL << (FIELD_imm32 & 63); + /* pcode: regs = UInt(imm8) / 2 */ + res->fields[FIELD_regs] = ((2) ? (((res->fields[FIELD_imm8])) / (2)) : 0); + res->fields_mask[FIELD_regs >> 6] |= 1LL << (FIELD_regs & 63); + /* pcode: if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE */ + if((((res->fields[FIELD_regs]) == (0)) || ((res->fields[FIELD_regs]) > (16))) || ((((res->fields[FIELD_d]) + (res->fields[FIELD_regs]))) > (32))) { + res->flags |= FLAG_UNPREDICTABLE; + } + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* Encoding T2 */ + /* pattern="cond.4,110,1,0,D.1,1,0,1101,Vd.4,1010,imm8.8" width=32 stringency=16 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFBF0F00)==0xD2D0A00)) { + res->instrSize = 32; + if(!(req->arch & ARCH_VFPv2) && !(req->arch & ARCH_VFPv3)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = (instr & 0xF0000000)>>28; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + char cond_width = 4; + res->fields[FIELD_D] = (instr & 0x400000)>>22; + res->fields_mask[FIELD_D >> 6] |= 1LL << (FIELD_D & 63); + char D_width = 1; + res->fields[FIELD_Vd] = (instr & 0xF000)>>12; + res->fields_mask[FIELD_Vd >> 6] |= 1LL << (FIELD_Vd & 63); + char Vd_width = 4; + res->fields[FIELD_imm8] = instr & 0xFF; + res->fields_mask[FIELD_imm8 >> 6] |= 1LL << (FIELD_imm8 & 63); + char imm8_width = 8; + + static const instruction_format instr_formats[] = + { + { /* VPUSH<c> <registers> */ + "vpush", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REGISTERS,FIELD_registers,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 1 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_VPUSH; + + /* pcode: single_regs = TRUE */ + res->fields[FIELD_single_regs] = 1; + res->fields_mask[FIELD_single_regs >> 6] |= 1LL << (FIELD_single_regs & 63); + /* pcode: d = UInt(Vd:D) */ + res->fields[FIELD_d] = ((res->fields[FIELD_Vd]<<D_width)|(res->fields[FIELD_D])); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: imm32 = ZeroExtend(imm8:'00', 32) */ + res->fields[FIELD_imm32] = (res->fields[FIELD_imm8]<<2)|(0x0); + res->fields_mask[FIELD_imm32 >> 6] |= 1LL << (FIELD_imm32 & 63); + /* pcode: regs = UInt(imm8) */ + res->fields[FIELD_regs] = (res->fields[FIELD_imm8]); + res->fields_mask[FIELD_regs >> 6] |= 1LL << (FIELD_regs & 63); + /* pcode: if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE */ + if((((res->fields[FIELD_regs]) == (0)) || ((res->fields[FIELD_regs]) > (16))) || ((((res->fields[FIELD_d]) + (res->fields[FIELD_regs]))) > (32))) { + res->flags |= FLAG_UNPREDICTABLE; + } + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: 442C1865 +int vqabs(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + /* Encoding T1 */ + /* pattern="1111,xx11,1,D.1,11,size.2,00,Vd.4,0111,0,Q.1,M.1,0,Vm.4" width=32 stringency=20 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xF3B30F90)==0xF3B00700)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ADVSIMD)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_D] = (instr & 0x400000)>>22; + res->fields_mask[FIELD_D >> 6] |= 1LL << (FIELD_D & 63); + char D_width = 1; + res->fields[FIELD_size] = (instr & 0xC0000)>>18; + res->fields_mask[FIELD_size >> 6] |= 1LL << (FIELD_size & 63); + char size_width = 2; + res->fields[FIELD_Vd] = (instr & 0xF000)>>12; + res->fields_mask[FIELD_Vd >> 6] |= 1LL << (FIELD_Vd & 63); + char Vd_width = 4; + res->fields[FIELD_Q] = (instr & 0x40)>>6; + res->fields_mask[FIELD_Q >> 6] |= 1LL << (FIELD_Q & 63); + char Q_width = 1; + res->fields[FIELD_M] = (instr & 0x20)>>5; + res->fields_mask[FIELD_M >> 6] |= 1LL << (FIELD_M & 63); + char M_width = 1; + res->fields[FIELD_Vm] = instr & 0xF; + res->fields_mask[FIELD_Vm >> 6] |= 1LL << (FIELD_Vm & 63); + char Vm_width = 4; + + static const instruction_format instr_formats[] = + { + { /* VQABS<c>.<dt> <Dd>,<Dm> */ + "vqabs", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_VFP_DATA_SIZE, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_m,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + { /* VQABS<c>.<dt> <Qd>,<Qm> */ + "vqabs", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_VFP_DATA_SIZE, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"q","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_m,FIELD_UNINIT,"q","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 2; + res->mnem = armv7::ARMV7_VQABS; + + /* pcode: if size == '11' then UNDEFINED */ + if((res->fields[FIELD_size]) == (0x3)) { + res->status |= STATUS_UNDEFINED; + } + /* pcode: if Q == '1' && (Vd<0> == '1' || Vm<0> == '1') then UNDEFINED */ + if(((res->fields[FIELD_Q]) == (0x1)) && (((((res->fields[FIELD_Vd] & 1)) == (0x1)) || (((res->fields[FIELD_Vm] & 1)) == (0x1))))) { + res->status |= STATUS_UNDEFINED; + } + /* pcode: esize = 8 << UInt(size) */ + res->fields[FIELD_esize] = (8) << ((res->fields[FIELD_size])); + res->fields_mask[FIELD_esize >> 6] |= 1LL << (FIELD_esize & 63); + /* pcode: elements = 64 DIV esize */ + res->fields[FIELD_elements] = ((res->fields[FIELD_esize]) ? ((64) / (res->fields[FIELD_esize])) : 0); + res->fields_mask[FIELD_elements >> 6] |= 1LL << (FIELD_elements & 63); + /* pcode: d = UInt(D:Vd) */ + res->fields[FIELD_d] = ((res->fields[FIELD_D]<<Vd_width)|(res->fields[FIELD_Vd])); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: m = UInt(M:Vm) */ + res->fields[FIELD_m] = ((res->fields[FIELD_M]<<Vm_width)|(res->fields[FIELD_Vm])); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + /* pcode: regs = if Q == '0' then 1 else 2 */ + if((res->fields[FIELD_Q]) == (0x0)) { + res->fields[FIELD_regs] = 1; + res->fields_mask[FIELD_regs >> 6] |= 1LL << (FIELD_regs & 63); + } + else { + res->fields[FIELD_regs] = 2; + res->fields_mask[FIELD_regs >> 6] |= 1LL << (FIELD_regs & 63); + } + /* pcode: fmt_idx = (Q=='1') */ + res->fields[FIELD_fmt_idx] = ((res->fields[FIELD_Q]) == (0x1)); + res->fields_mask[FIELD_fmt_idx >> 6] |= 1LL << (FIELD_fmt_idx & 63); + /* pcode: dt = size */ + res->fields[FIELD_dt] = res->fields[FIELD_size]; + res->fields_mask[FIELD_dt >> 6] |= 1LL << (FIELD_dt & 63); + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: 246E6FD9 +int vqadd(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + res->group = INSN_GROUP_NEON; + /* Encoding T1 */ + /* pattern="111,U.1,1111,0,D.1,size.2,Vn.4,Vd.4,0000,N.1,Q.1,M.1,1,Vm.4" width=32 stringency=18 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xEF800F10)==0xEF000010)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ADVSIMD)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_U] = (instr & 0x10000000)>>28; + res->fields_mask[FIELD_U >> 6] |= 1LL << (FIELD_U & 63); + char U_width = 1; + res->fields[FIELD_D] = (instr & 0x400000)>>22; + res->fields_mask[FIELD_D >> 6] |= 1LL << (FIELD_D & 63); + char D_width = 1; + res->fields[FIELD_size] = (instr & 0x300000)>>20; + res->fields_mask[FIELD_size >> 6] |= 1LL << (FIELD_size & 63); + char size_width = 2; + res->fields[FIELD_Vn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Vn >> 6] |= 1LL << (FIELD_Vn & 63); + char Vn_width = 4; + res->fields[FIELD_Vd] = (instr & 0xF000)>>12; + res->fields_mask[FIELD_Vd >> 6] |= 1LL << (FIELD_Vd & 63); + char Vd_width = 4; + res->fields[FIELD_N] = (instr & 0x80)>>7; + res->fields_mask[FIELD_N >> 6] |= 1LL << (FIELD_N & 63); + char N_width = 1; + res->fields[FIELD_Q] = (instr & 0x40)>>6; + res->fields_mask[FIELD_Q >> 6] |= 1LL << (FIELD_Q & 63); + char Q_width = 1; + res->fields[FIELD_M] = (instr & 0x20)>>5; + res->fields_mask[FIELD_M >> 6] |= 1LL << (FIELD_M & 63); + char M_width = 1; + res->fields[FIELD_Vm] = instr & 0xF; + res->fields_mask[FIELD_Vm >> 6] |= 1LL << (FIELD_Vm & 63); + char Vm_width = 4; + + static const instruction_format instr_formats[] = + { + { /* VQADD<c>.<dt> <Dd>,<Dn>,<Dm> */ + "vqadd", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_VFP_DATA_SIZE, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_n,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_m,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + { /* VQADD<c>.<dt> <Qd>,<Qn>,<Qm> */ + "vqadd", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_VFP_DATA_SIZE, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"q","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_n,FIELD_UNINIT,"q","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_m,FIELD_UNINIT,"q","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 2; + res->mnem = armv7::ARMV7_VQADD; + + /* pcode: if Q == '1' && (Vd<0> == '1' || Vn<0> == '1' || Vm<0> == '1') then UNDEFINED */ + if(((res->fields[FIELD_Q]) == (0x1)) && ((((((res->fields[FIELD_Vd] & 1)) == (0x1)) || (((res->fields[FIELD_Vn] & 1)) == (0x1))) || (((res->fields[FIELD_Vm] & 1)) == (0x1))))) { + res->status |= STATUS_UNDEFINED; + } + /* pcode: unsigned = (U == '1') */ + res->fields[FIELD_unsigned] = ((res->fields[FIELD_U]) == (0x1)); + res->fields_mask[FIELD_unsigned >> 6] |= 1LL << (FIELD_unsigned & 63); + /* pcode: esize = 8 << UInt(size) */ + res->fields[FIELD_esize] = (8) << ((res->fields[FIELD_size])); + res->fields_mask[FIELD_esize >> 6] |= 1LL << (FIELD_esize & 63); + /* pcode: elements = 64 DIV esize */ + res->fields[FIELD_elements] = ((res->fields[FIELD_esize]) ? ((64) / (res->fields[FIELD_esize])) : 0); + res->fields_mask[FIELD_elements >> 6] |= 1LL << (FIELD_elements & 63); + /* pcode: d = UInt(D:Vd) */ + res->fields[FIELD_d] = ((res->fields[FIELD_D]<<Vd_width)|(res->fields[FIELD_Vd])); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: n = UInt(N:Vn) */ + res->fields[FIELD_n] = ((res->fields[FIELD_N]<<Vn_width)|(res->fields[FIELD_Vn])); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: m = UInt(M:Vm) */ + res->fields[FIELD_m] = ((res->fields[FIELD_M]<<Vm_width)|(res->fields[FIELD_Vm])); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + /* pcode: fmt_idx = (Q == '1') */ + res->fields[FIELD_fmt_idx] = ((res->fields[FIELD_Q]) == (0x1)); + res->fields_mask[FIELD_fmt_idx >> 6] |= 1LL << (FIELD_fmt_idx & 63); + /* pcode: regs = if Q == '0' then 1 else 2 */ + if((res->fields[FIELD_Q]) == (0x0)) { + res->fields[FIELD_regs] = 1; + res->fields_mask[FIELD_regs >> 6] |= 1LL << (FIELD_regs & 63); + } + else { + res->fields[FIELD_regs] = 2; + res->fields_mask[FIELD_regs >> 6] |= 1LL << (FIELD_regs & 63); + } + /* pcode: dt = UInt(U:size) */ + res->fields[FIELD_dt] = ((res->fields[FIELD_U]<<size_width)|(res->fields[FIELD_size])); + res->fields_mask[FIELD_dt >> 6] |= 1LL << (FIELD_dt & 63); + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: B035D797 +int vqdmlal(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + res->group = INSN_GROUP_NEON; + /* Encoding T2 */ + /* pattern="111x,xx1x,1,D.1,size.2,Vn.4,Vd.4,0,op.1,11,N.1,1,M.1,0,Vm.4" width=32 stringency=14 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xE2800B50)==0xE2800340)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ADVSIMD)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_D] = (instr & 0x400000)>>22; + res->fields_mask[FIELD_D >> 6] |= 1LL << (FIELD_D & 63); + char D_width = 1; + res->fields[FIELD_size] = (instr & 0x300000)>>20; + res->fields_mask[FIELD_size >> 6] |= 1LL << (FIELD_size & 63); + char size_width = 2; + res->fields[FIELD_Vn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Vn >> 6] |= 1LL << (FIELD_Vn & 63); + char Vn_width = 4; + res->fields[FIELD_Vd] = (instr & 0xF000)>>12; + res->fields_mask[FIELD_Vd >> 6] |= 1LL << (FIELD_Vd & 63); + char Vd_width = 4; + res->fields[FIELD_op] = (instr & 0x400)>>10; + res->fields_mask[FIELD_op >> 6] |= 1LL << (FIELD_op & 63); + char op_width = 1; + res->fields[FIELD_N] = (instr & 0x80)>>7; + res->fields_mask[FIELD_N >> 6] |= 1LL << (FIELD_N & 63); + char N_width = 1; + res->fields[FIELD_M] = (instr & 0x20)>>5; + res->fields_mask[FIELD_M >> 6] |= 1LL << (FIELD_M & 63); + char M_width = 1; + res->fields[FIELD_Vm] = instr & 0xF; + res->fields_mask[FIELD_Vm >> 6] |= 1LL << (FIELD_Vm & 63); + char Vm_width = 4; + + static const instruction_format instr_formats[] = + { + { /* VQDMLAL<c>.<dt> <Qd>,<Dn>,<Dm[x]> */ + "vqdmlal", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_VFP_DATA_SIZE, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"q","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_n,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_INDEX,FIELD_m,FIELD_x,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + { /* VQDMLSL<c>.<dt> <Qd>,<Dn>,<Dm[x]> */ + "vqdmlsl", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_VFP_DATA_SIZE, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"q","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_n,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_INDEX,FIELD_m,FIELD_x,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 2; + res->mnem = armv7::ARMV7_VQDMLAL; + + /* pcode: if size == '11' then SEE advanced_simd_data_proc */ + if((res->fields[FIELD_size]) == (0x3)) { + + return advanced_simd_data_proc(req, res); + } + /* pcode: if (size == '00' || Vd<0> == '1') then UNDEFINED */ + if((((res->fields[FIELD_size]) == (0x0)) || (((res->fields[FIELD_Vd] & 1)) == (0x1)))) { + res->status |= STATUS_UNDEFINED; + } + /* pcode: d = UInt(D:Vd) */ + res->fields[FIELD_d] = ((res->fields[FIELD_D]<<Vd_width)|(res->fields[FIELD_Vd])); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: n = UInt(N:Vn) */ + res->fields[FIELD_n] = ((res->fields[FIELD_N]<<Vn_width)|(res->fields[FIELD_Vn])); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: if size == '01' then esize = 16 */ + if((res->fields[FIELD_size]) == (0x1)) { + res->fields[FIELD_esize] = 16; + res->fields_mask[FIELD_esize >> 6] |= 1LL << (FIELD_esize & 63); + } + /* pcode: if size == '10' then esize = 32 */ + if((res->fields[FIELD_size]) == (0x2)) { + res->fields[FIELD_esize] = 32; + res->fields_mask[FIELD_esize >> 6] |= 1LL << (FIELD_esize & 63); + } + /* pcode: elements = 64 DIV esize */ + res->fields[FIELD_elements] = ((res->fields[FIELD_esize]) ? ((64) / (res->fields[FIELD_esize])) : 0); + res->fields_mask[FIELD_elements >> 6] |= 1LL << (FIELD_elements & 63); + /* pcode: x = UInt(M:Vm) */ + res->fields[FIELD_x] = ((res->fields[FIELD_M]<<Vm_width)|(res->fields[FIELD_Vm])); + res->fields_mask[FIELD_x >> 6] |= 1LL << (FIELD_x & 63); + /* pcode: if esize == 16 then x = x >> 3 */ + if((res->fields[FIELD_esize]) == (16)) { + res->fields[FIELD_x] = (res->fields[FIELD_x]) >> (3); + res->fields_mask[FIELD_x >> 6] |= 1LL << (FIELD_x & 63); + } + /* pcode: if esize == 32 then x = UInt(M) */ + if((res->fields[FIELD_esize]) == (32)) { + res->fields[FIELD_x] = (res->fields[FIELD_M]); + res->fields_mask[FIELD_x >> 6] |= 1LL << (FIELD_x & 63); + } + /* pcode: m = UInt(Vm) */ + res->fields[FIELD_m] = (res->fields[FIELD_Vm]); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + /* pcode: if esize == 16 then m = m - ((UInt(Vm) >> 3) * 8) */ + if((res->fields[FIELD_esize]) == (16)) { + res->fields[FIELD_m] = (res->fields[FIELD_m]) - ((((((res->fields[FIELD_Vm])) >> (3))) * (8))); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + } + /* pcode: fmt_idx = (op == '1') */ + res->fields[FIELD_fmt_idx] = ((res->fields[FIELD_op]) == (0x1)); + res->fields_mask[FIELD_fmt_idx >> 6] |= 1LL << (FIELD_fmt_idx & 63); + /* pcode: dt = size */ + res->fields[FIELD_dt] = res->fields[FIELD_size]; + res->fields_mask[FIELD_dt >> 6] |= 1LL << (FIELD_dt & 63); + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* Encoding T1 */ + /* pattern="111x,xx1x,1,D.1,size.2,Vn.4,Vd.4,10,op.1,1,N.1,0,M.1,0,Vm.4" width=32 stringency=14 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xE2800D50)==0xE2800900)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ADVSIMD)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_D] = (instr & 0x400000)>>22; + res->fields_mask[FIELD_D >> 6] |= 1LL << (FIELD_D & 63); + char D_width = 1; + res->fields[FIELD_size] = (instr & 0x300000)>>20; + res->fields_mask[FIELD_size >> 6] |= 1LL << (FIELD_size & 63); + char size_width = 2; + res->fields[FIELD_Vn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Vn >> 6] |= 1LL << (FIELD_Vn & 63); + char Vn_width = 4; + res->fields[FIELD_Vd] = (instr & 0xF000)>>12; + res->fields_mask[FIELD_Vd >> 6] |= 1LL << (FIELD_Vd & 63); + char Vd_width = 4; + res->fields[FIELD_op] = (instr & 0x200)>>9; + res->fields_mask[FIELD_op >> 6] |= 1LL << (FIELD_op & 63); + char op_width = 1; + res->fields[FIELD_N] = (instr & 0x80)>>7; + res->fields_mask[FIELD_N >> 6] |= 1LL << (FIELD_N & 63); + char N_width = 1; + res->fields[FIELD_M] = (instr & 0x20)>>5; + res->fields_mask[FIELD_M >> 6] |= 1LL << (FIELD_M & 63); + char M_width = 1; + res->fields[FIELD_Vm] = instr & 0xF; + res->fields_mask[FIELD_Vm >> 6] |= 1LL << (FIELD_Vm & 63); + char Vm_width = 4; + + static const instruction_format instr_formats[] = + { + { /* VQDMLAL<c>.<dt> <Qd>,<Dn>,<Dm> */ + "vqdmlal", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_VFP_DATA_SIZE, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"q","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_n,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_m,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + { /* VQDMLSL<c>.<dt> <Qd>,<Dn>,<Dm> */ + "vqdmlsl", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_VFP_DATA_SIZE, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"q","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_n,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_m,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 2; + res->mnem = armv7::ARMV7_VQDMLAL; + + /* pcode: if size == '11' then SEE advanced_simd_data_proc */ + if((res->fields[FIELD_size]) == (0x3)) { + + return advanced_simd_data_proc(req, res); + } + /* pcode: if (size == '00' || Vd<0> == '1') then UNDEFINED */ + if((((res->fields[FIELD_size]) == (0x0)) || (((res->fields[FIELD_Vd] & 1)) == (0x1)))) { + res->status |= STATUS_UNDEFINED; + } + /* pcode: d = UInt(D:Vd) */ + res->fields[FIELD_d] = ((res->fields[FIELD_D]<<Vd_width)|(res->fields[FIELD_Vd])); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: n = UInt(N:Vn) */ + res->fields[FIELD_n] = ((res->fields[FIELD_N]<<Vn_width)|(res->fields[FIELD_Vn])); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: m = UInt(M:Vm) */ + res->fields[FIELD_m] = ((res->fields[FIELD_M]<<Vm_width)|(res->fields[FIELD_Vm])); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + /* pcode: esize = 8 << UInt(size) */ + res->fields[FIELD_esize] = (8) << ((res->fields[FIELD_size])); + res->fields_mask[FIELD_esize >> 6] |= 1LL << (FIELD_esize & 63); + /* pcode: elements = 64 DIV esize */ + res->fields[FIELD_elements] = ((res->fields[FIELD_esize]) ? ((64) / (res->fields[FIELD_esize])) : 0); + res->fields_mask[FIELD_elements >> 6] |= 1LL << (FIELD_elements & 63); + /* pcode: fmt_idx = (op == '1') */ + res->fields[FIELD_fmt_idx] = ((res->fields[FIELD_op]) == (0x1)); + res->fields_mask[FIELD_fmt_idx >> 6] |= 1LL << (FIELD_fmt_idx & 63); + /* pcode: dt = size */ + res->fields[FIELD_dt] = res->fields[FIELD_size]; + res->fields_mask[FIELD_dt >> 6] |= 1LL << (FIELD_dt & 63); + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: 73480F55 +int vqdmulh(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + res->group = INSN_GROUP_NEON; + /* Encoding T2 */ + /* pattern="111,Q.1,1111,1,D.1,size.2,Vn.4,Vd.4,1100,N.1,1,M.1,0,Vm.4" width=32 stringency=18 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xEF800F50)==0xEF800C40)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ADVSIMD)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_Q] = (instr & 0x10000000)>>28; + res->fields_mask[FIELD_Q >> 6] |= 1LL << (FIELD_Q & 63); + char Q_width = 1; + res->fields[FIELD_D] = (instr & 0x400000)>>22; + res->fields_mask[FIELD_D >> 6] |= 1LL << (FIELD_D & 63); + char D_width = 1; + res->fields[FIELD_size] = (instr & 0x300000)>>20; + res->fields_mask[FIELD_size >> 6] |= 1LL << (FIELD_size & 63); + char size_width = 2; + res->fields[FIELD_Vn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Vn >> 6] |= 1LL << (FIELD_Vn & 63); + char Vn_width = 4; + res->fields[FIELD_Vd] = (instr & 0xF000)>>12; + res->fields_mask[FIELD_Vd >> 6] |= 1LL << (FIELD_Vd & 63); + char Vd_width = 4; + res->fields[FIELD_N] = (instr & 0x80)>>7; + res->fields_mask[FIELD_N >> 6] |= 1LL << (FIELD_N & 63); + char N_width = 1; + res->fields[FIELD_M] = (instr & 0x20)>>5; + res->fields_mask[FIELD_M >> 6] |= 1LL << (FIELD_M & 63); + char M_width = 1; + res->fields[FIELD_Vm] = instr & 0xF; + res->fields_mask[FIELD_Vm >> 6] |= 1LL << (FIELD_Vm & 63); + char Vm_width = 4; + + static const instruction_format instr_formats[] = + { + { /* VQDMULH<c>.<dt> <Dd>,<Dn>,<Dm[x]> */ + "vqdmulh", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_VFP_DATA_SIZE, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_n,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_INDEX,FIELD_m,FIELD_x,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + { /* VQDMULH<c>.<dt> <Qd>,<Qn>,<Dm[x]> */ + "vqdmulh", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_VFP_DATA_SIZE, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"q","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_n,FIELD_UNINIT,"q","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_INDEX,FIELD_m,FIELD_x,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 2; + res->mnem = armv7::ARMV7_VQDMULH; + + /* pcode: if size == '11' then SEE advanced_simd_data_proc */ + if((res->fields[FIELD_size]) == (0x3)) { + + return advanced_simd_data_proc(req, res); + } + /* pcode: if size == '00' then UNDEFINED */ + if((res->fields[FIELD_size]) == (0x0)) { + res->status |= STATUS_UNDEFINED; + } + /* pcode: if (Q == '1' && (Vd<0> == '1' || Vn<0> == '1')) then UNDEFINED */ + if((((res->fields[FIELD_Q]) == (0x1)) && (((((res->fields[FIELD_Vd] & 1)) == (0x1)) || (((res->fields[FIELD_Vn] & 1)) == (0x1)))))) { + res->status |= STATUS_UNDEFINED; + } + /* pcode: d = UInt(D:Vd) */ + res->fields[FIELD_d] = ((res->fields[FIELD_D]<<Vd_width)|(res->fields[FIELD_Vd])); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: n = UInt(N:Vn) */ + res->fields[FIELD_n] = ((res->fields[FIELD_N]<<Vn_width)|(res->fields[FIELD_Vn])); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: regs = if Q == '0' then 1 else 2 */ + if((res->fields[FIELD_Q]) == (0x0)) { + res->fields[FIELD_regs] = 1; + res->fields_mask[FIELD_regs >> 6] |= 1LL << (FIELD_regs & 63); + } + else { + res->fields[FIELD_regs] = 2; + res->fields_mask[FIELD_regs >> 6] |= 1LL << (FIELD_regs & 63); + } + /* pcode: if size == '01' then esize = 16 */ + if((res->fields[FIELD_size]) == (0x1)) { + res->fields[FIELD_esize] = 16; + res->fields_mask[FIELD_esize >> 6] |= 1LL << (FIELD_esize & 63); + } + /* pcode: if size == '10' then esize = 32 */ + if((res->fields[FIELD_size]) == (0x2)) { + res->fields[FIELD_esize] = 32; + res->fields_mask[FIELD_esize >> 6] |= 1LL << (FIELD_esize & 63); + } + /* pcode: elements = 64 DIV esize */ + res->fields[FIELD_elements] = ((res->fields[FIELD_esize]) ? ((64) / (res->fields[FIELD_esize])) : 0); + res->fields_mask[FIELD_elements >> 6] |= 1LL << (FIELD_elements & 63); + /* pcode: x = UInt(M:Vm) */ + res->fields[FIELD_x] = ((res->fields[FIELD_M]<<Vm_width)|(res->fields[FIELD_Vm])); + res->fields_mask[FIELD_x >> 6] |= 1LL << (FIELD_x & 63); + /* pcode: if esize == 16 then x = x >> 3 */ + if((res->fields[FIELD_esize]) == (16)) { + res->fields[FIELD_x] = (res->fields[FIELD_x]) >> (3); + res->fields_mask[FIELD_x >> 6] |= 1LL << (FIELD_x & 63); + } + /* pcode: if esize == 32 then x = UInt(M) */ + if((res->fields[FIELD_esize]) == (32)) { + res->fields[FIELD_x] = (res->fields[FIELD_M]); + res->fields_mask[FIELD_x >> 6] |= 1LL << (FIELD_x & 63); + } + /* pcode: m = UInt(Vm) */ + res->fields[FIELD_m] = (res->fields[FIELD_Vm]); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + /* pcode: if esize == 16 then m = m - ((UInt(Vm) >> 3) * 8) */ + if((res->fields[FIELD_esize]) == (16)) { + res->fields[FIELD_m] = (res->fields[FIELD_m]) - ((((((res->fields[FIELD_Vm])) >> (3))) * (8))); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + } + /* pcode: fmt_idx = (op == '1') */ + res->fields[FIELD_fmt_idx] = ((res->fields[FIELD_op]) == (0x1)); + res->fields_mask[FIELD_fmt_idx >> 6] |= 1LL << (FIELD_fmt_idx & 63); + /* pcode: dt = size */ + res->fields[FIELD_dt] = res->fields[FIELD_size]; + res->fields_mask[FIELD_dt >> 6] |= 1LL << (FIELD_dt & 63); + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* Encoding T1 */ + /* pattern="111x,xx1x,0,D.1,size.2,Vn.4,Vd.4,1011,N.1,Q.1,M.1,0,Vm.4" width=32 stringency=14 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xE2800F10)==0xE2000B00)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ADVSIMD)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_D] = (instr & 0x400000)>>22; + res->fields_mask[FIELD_D >> 6] |= 1LL << (FIELD_D & 63); + char D_width = 1; + res->fields[FIELD_size] = (instr & 0x300000)>>20; + res->fields_mask[FIELD_size >> 6] |= 1LL << (FIELD_size & 63); + char size_width = 2; + res->fields[FIELD_Vn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Vn >> 6] |= 1LL << (FIELD_Vn & 63); + char Vn_width = 4; + res->fields[FIELD_Vd] = (instr & 0xF000)>>12; + res->fields_mask[FIELD_Vd >> 6] |= 1LL << (FIELD_Vd & 63); + char Vd_width = 4; + res->fields[FIELD_N] = (instr & 0x80)>>7; + res->fields_mask[FIELD_N >> 6] |= 1LL << (FIELD_N & 63); + char N_width = 1; + res->fields[FIELD_Q] = (instr & 0x40)>>6; + res->fields_mask[FIELD_Q >> 6] |= 1LL << (FIELD_Q & 63); + char Q_width = 1; + res->fields[FIELD_M] = (instr & 0x20)>>5; + res->fields_mask[FIELD_M >> 6] |= 1LL << (FIELD_M & 63); + char M_width = 1; + res->fields[FIELD_Vm] = instr & 0xF; + res->fields_mask[FIELD_Vm >> 6] |= 1LL << (FIELD_Vm & 63); + char Vm_width = 4; + + static const instruction_format instr_formats[] = + { + { /* VQDMULH<c>.<dt> <Dd>,<Dn>,<Dm> */ + "vqdmulh", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_VFP_DATA_SIZE, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_n,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_m,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + { /* VQDMULH<c>.<dt> <Qd>,<Qn>,<Qm> */ + "vqdmulh", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_VFP_DATA_SIZE, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"q","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_n,FIELD_UNINIT,"q","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_m,FIELD_UNINIT,"q","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 2; + res->mnem = armv7::ARMV7_VQDMULH; + + /* pcode: if (Q == '1' && (Vd<0> == '1' || Vn<0> == '1' || Vm<0> == '1')) then UNDEFINED */ + if((((res->fields[FIELD_Q]) == (0x1)) && ((((((res->fields[FIELD_Vd] & 1)) == (0x1)) || (((res->fields[FIELD_Vn] & 1)) == (0x1))) || (((res->fields[FIELD_Vm] & 1)) == (0x1)))))) { + res->status |= STATUS_UNDEFINED; + } + /* pcode: if (size == '00' || size == '11') then UNDEFINED */ + if((((res->fields[FIELD_size]) == (0x0)) || ((res->fields[FIELD_size]) == (0x3)))) { + res->status |= STATUS_UNDEFINED; + } + /* pcode: esize = 8 << UInt(size) */ + res->fields[FIELD_esize] = (8) << ((res->fields[FIELD_size])); + res->fields_mask[FIELD_esize >> 6] |= 1LL << (FIELD_esize & 63); + /* pcode: elements = 64 DIV esize */ + res->fields[FIELD_elements] = ((res->fields[FIELD_esize]) ? ((64) / (res->fields[FIELD_esize])) : 0); + res->fields_mask[FIELD_elements >> 6] |= 1LL << (FIELD_elements & 63); + /* pcode: d = UInt(D:Vd) */ + res->fields[FIELD_d] = ((res->fields[FIELD_D]<<Vd_width)|(res->fields[FIELD_Vd])); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: n = UInt(N:Vn) */ + res->fields[FIELD_n] = ((res->fields[FIELD_N]<<Vn_width)|(res->fields[FIELD_Vn])); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: m = UInt(M:Vm) */ + res->fields[FIELD_m] = ((res->fields[FIELD_M]<<Vm_width)|(res->fields[FIELD_Vm])); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + /* pcode: regs = if Q == '0' then 1 else 2 */ + if((res->fields[FIELD_Q]) == (0x0)) { + res->fields[FIELD_regs] = 1; + res->fields_mask[FIELD_regs >> 6] |= 1LL << (FIELD_regs & 63); + } + else { + res->fields[FIELD_regs] = 2; + res->fields_mask[FIELD_regs >> 6] |= 1LL << (FIELD_regs & 63); + } + /* pcode: fmt_idx = (Q == '1') */ + res->fields[FIELD_fmt_idx] = ((res->fields[FIELD_Q]) == (0x1)); + res->fields_mask[FIELD_fmt_idx >> 6] |= 1LL << (FIELD_fmt_idx & 63); + /* pcode: dt = size */ + res->fields[FIELD_dt] = res->fields[FIELD_size]; + res->fields_mask[FIELD_dt >> 6] |= 1LL << (FIELD_dt & 63); + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: 52F5882D +int vqdmull(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + res->group = INSN_GROUP_NEON; + /* Encoding T2 */ + /* pattern="1110,1111,1,D.1,size.2,Vn.4,Vd.4,1011,N.1,1,M.1,0,Vm.4" width=32 stringency=18 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFF800F50)==0xEF800B40)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ADVSIMD)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_D] = (instr & 0x400000)>>22; + res->fields_mask[FIELD_D >> 6] |= 1LL << (FIELD_D & 63); + char D_width = 1; + res->fields[FIELD_size] = (instr & 0x300000)>>20; + res->fields_mask[FIELD_size >> 6] |= 1LL << (FIELD_size & 63); + char size_width = 2; + res->fields[FIELD_Vn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Vn >> 6] |= 1LL << (FIELD_Vn & 63); + char Vn_width = 4; + res->fields[FIELD_Vd] = (instr & 0xF000)>>12; + res->fields_mask[FIELD_Vd >> 6] |= 1LL << (FIELD_Vd & 63); + char Vd_width = 4; + res->fields[FIELD_N] = (instr & 0x80)>>7; + res->fields_mask[FIELD_N >> 6] |= 1LL << (FIELD_N & 63); + char N_width = 1; + res->fields[FIELD_M] = (instr & 0x20)>>5; + res->fields_mask[FIELD_M >> 6] |= 1LL << (FIELD_M & 63); + char M_width = 1; + res->fields[FIELD_Vm] = instr & 0xF; + res->fields_mask[FIELD_Vm >> 6] |= 1LL << (FIELD_Vm & 63); + char Vm_width = 4; + + static const instruction_format instr_formats[] = + { + { /* VQDMULL<c>.<dt> <Qd>,<Dn>,<Dm[x]> */ + "vqdmull", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_VFP_DATA_SIZE, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"q","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_n,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_INDEX,FIELD_m,FIELD_x,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_VQDMULL; + + /* pcode: if size == '11' then SEE advanced_simd_data_proc */ + if((res->fields[FIELD_size]) == (0x3)) { + + return advanced_simd_data_proc(req, res); + } + /* pcode: if (size == '00' || Vd<0> == '1') then UNDEFINED */ + if((((res->fields[FIELD_size]) == (0x0)) || (((res->fields[FIELD_Vd] & 1)) == (0x1)))) { + res->status |= STATUS_UNDEFINED; + } + /* pcode: d = UInt(D:Vd) */ + res->fields[FIELD_d] = ((res->fields[FIELD_D]<<Vd_width)|(res->fields[FIELD_Vd])); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: n = UInt(N:Vn) */ + res->fields[FIELD_n] = ((res->fields[FIELD_N]<<Vn_width)|(res->fields[FIELD_Vn])); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: if size == '01' then esize = 16 */ + if((res->fields[FIELD_size]) == (0x1)) { + res->fields[FIELD_esize] = 16; + res->fields_mask[FIELD_esize >> 6] |= 1LL << (FIELD_esize & 63); + } + /* pcode: if size == '10' then esize = 32 */ + if((res->fields[FIELD_size]) == (0x2)) { + res->fields[FIELD_esize] = 32; + res->fields_mask[FIELD_esize >> 6] |= 1LL << (FIELD_esize & 63); + } + /* pcode: elements = 64 DIV esize */ + res->fields[FIELD_elements] = ((res->fields[FIELD_esize]) ? ((64) / (res->fields[FIELD_esize])) : 0); + res->fields_mask[FIELD_elements >> 6] |= 1LL << (FIELD_elements & 63); + /* pcode: x = UInt(M:Vm) */ + res->fields[FIELD_x] = ((res->fields[FIELD_M]<<Vm_width)|(res->fields[FIELD_Vm])); + res->fields_mask[FIELD_x >> 6] |= 1LL << (FIELD_x & 63); + /* pcode: if esize == 16 then x = x >> 3 */ + if((res->fields[FIELD_esize]) == (16)) { + res->fields[FIELD_x] = (res->fields[FIELD_x]) >> (3); + res->fields_mask[FIELD_x >> 6] |= 1LL << (FIELD_x & 63); + } + /* pcode: if esize == 32 then x = UInt(M) */ + if((res->fields[FIELD_esize]) == (32)) { + res->fields[FIELD_x] = (res->fields[FIELD_M]); + res->fields_mask[FIELD_x >> 6] |= 1LL << (FIELD_x & 63); + } + /* pcode: m = UInt(Vm) */ + res->fields[FIELD_m] = (res->fields[FIELD_Vm]); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + /* pcode: if esize == 16 then m = m - ((UInt(Vm) >> 3) * 8) */ + if((res->fields[FIELD_esize]) == (16)) { + res->fields[FIELD_m] = (res->fields[FIELD_m]) - ((((((res->fields[FIELD_Vm])) >> (3))) * (8))); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + } + /* pcode: fmt_idx = (op == '1') */ + res->fields[FIELD_fmt_idx] = ((res->fields[FIELD_op]) == (0x1)); + res->fields_mask[FIELD_fmt_idx >> 6] |= 1LL << (FIELD_fmt_idx & 63); + /* pcode: dt = size */ + res->fields[FIELD_dt] = res->fields[FIELD_size]; + res->fields_mask[FIELD_dt >> 6] |= 1LL << (FIELD_dt & 63); + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* Encoding T1 */ + /* pattern="111x,xx1x,1,D.1,size.2,Vn.4,Vd.4,1101,N.1,0,M.1,0,Vm.4" width=32 stringency=14 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xE2800F50)==0xE2800D00)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ADVSIMD)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_D] = (instr & 0x400000)>>22; + res->fields_mask[FIELD_D >> 6] |= 1LL << (FIELD_D & 63); + char D_width = 1; + res->fields[FIELD_size] = (instr & 0x300000)>>20; + res->fields_mask[FIELD_size >> 6] |= 1LL << (FIELD_size & 63); + char size_width = 2; + res->fields[FIELD_Vn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Vn >> 6] |= 1LL << (FIELD_Vn & 63); + char Vn_width = 4; + res->fields[FIELD_Vd] = (instr & 0xF000)>>12; + res->fields_mask[FIELD_Vd >> 6] |= 1LL << (FIELD_Vd & 63); + char Vd_width = 4; + res->fields[FIELD_N] = (instr & 0x80)>>7; + res->fields_mask[FIELD_N >> 6] |= 1LL << (FIELD_N & 63); + char N_width = 1; + res->fields[FIELD_M] = (instr & 0x20)>>5; + res->fields_mask[FIELD_M >> 6] |= 1LL << (FIELD_M & 63); + char M_width = 1; + res->fields[FIELD_Vm] = instr & 0xF; + res->fields_mask[FIELD_Vm >> 6] |= 1LL << (FIELD_Vm & 63); + char Vm_width = 4; + + static const instruction_format instr_formats[] = + { + { /* VQDMULL<c>.<dt> <Qd>,<Dn>,<Dm> */ + "vqdmull", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_VFP_DATA_SIZE, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"q","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_n,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_m,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_VQDMULL; + + /* pcode: if size == '11' then SEE advanced_simd_data_proc */ + if((res->fields[FIELD_size]) == (0x3)) { + + return advanced_simd_data_proc(req, res); + } + /* pcode: if (size == '00' || Vd<0> == '1') then UNDEFINED */ + if((((res->fields[FIELD_size]) == (0x0)) || (((res->fields[FIELD_Vd] & 1)) == (0x1)))) { + res->status |= STATUS_UNDEFINED; + } + /* pcode: d = UInt(D:Vd) */ + res->fields[FIELD_d] = ((res->fields[FIELD_D]<<Vd_width)|(res->fields[FIELD_Vd])); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: n = UInt(N:Vn) */ + res->fields[FIELD_n] = ((res->fields[FIELD_N]<<Vn_width)|(res->fields[FIELD_Vn])); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: m = UInt(M:Vm) */ + res->fields[FIELD_m] = ((res->fields[FIELD_M]<<Vm_width)|(res->fields[FIELD_Vm])); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + /* pcode: esize = 8 << UInt(size) */ + res->fields[FIELD_esize] = (8) << ((res->fields[FIELD_size])); + res->fields_mask[FIELD_esize >> 6] |= 1LL << (FIELD_esize & 63); + /* pcode: elements = 64 DIV esize */ + res->fields[FIELD_elements] = ((res->fields[FIELD_esize]) ? ((64) / (res->fields[FIELD_esize])) : 0); + res->fields_mask[FIELD_elements >> 6] |= 1LL << (FIELD_elements & 63); + /* pcode: dt = size */ + res->fields[FIELD_dt] = res->fields[FIELD_size]; + res->fields_mask[FIELD_dt >> 6] |= 1LL << (FIELD_dt & 63); + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: 44168369 +int vqmovn(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + res->group = INSN_GROUP_NEON; + /* Encoding T1 */ + /* pattern="1111,xx11,1,D.1,11,size.2,10,Vd.4,0,010,op.2,M.1,0,Vm.4" width=32 stringency=18 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xF3B30F10)==0xF3B20200)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ADVSIMD)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_D] = (instr & 0x400000)>>22; + res->fields_mask[FIELD_D >> 6] |= 1LL << (FIELD_D & 63); + char D_width = 1; + res->fields[FIELD_size] = (instr & 0xC0000)>>18; + res->fields_mask[FIELD_size >> 6] |= 1LL << (FIELD_size & 63); + char size_width = 2; + res->fields[FIELD_Vd] = (instr & 0xF000)>>12; + res->fields_mask[FIELD_Vd >> 6] |= 1LL << (FIELD_Vd & 63); + char Vd_width = 4; + res->fields[FIELD_op] = (instr & 0xC0)>>6; + res->fields_mask[FIELD_op >> 6] |= 1LL << (FIELD_op & 63); + char op_width = 2; + res->fields[FIELD_M] = (instr & 0x20)>>5; + res->fields_mask[FIELD_M >> 6] |= 1LL << (FIELD_M & 63); + char M_width = 1; + res->fields[FIELD_Vm] = instr & 0xF; + res->fields_mask[FIELD_Vm >> 6] |= 1LL << (FIELD_Vm & 63); + char Vm_width = 4; + + static const instruction_format instr_formats[] = + { + { /* VQMOVN<c>.<type><size> <Dd>,<Qm> */ + "vqmovn", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_NEON_TYPE_SIZE|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_m,FIELD_UNINIT,"q","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + { /* VQMOVUN<c>.<type><size> <Dd>,<Qm> */ + "vqmovun", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_NEON_TYPE_SIZE|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_m,FIELD_UNINIT,"q","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 2; + res->mnem = armv7::ARMV7_VQMOVN; + + /* pcode: if op == '00' then SEE vmovn */ + if((res->fields[FIELD_op]) == (0x0)) { + + return vmovn(req, res); + } + /* pcode: if (size == '11' || Vm<0> == '1') then UNDEFINED */ + if((((res->fields[FIELD_size]) == (0x3)) || (((res->fields[FIELD_Vm] & 1)) == (0x1)))) { + res->status |= STATUS_UNDEFINED; + } + /* pcode: src_unsigned = (op == '11') */ + res->fields[FIELD_src_unsigned] = ((res->fields[FIELD_op]) == (0x3)); + res->fields_mask[FIELD_src_unsigned >> 6] |= 1LL << (FIELD_src_unsigned & 63); + /* pcode: dest_unsigned = (op == '11' || op == '01') */ + res->fields[FIELD_dest_unsigned] = (((res->fields[FIELD_op]) == (0x3)) || ((res->fields[FIELD_op]) == (0x1))); + res->fields_mask[FIELD_dest_unsigned >> 6] |= 1LL << (FIELD_dest_unsigned & 63); + /* pcode: esize = 8 << UInt(size) */ + res->fields[FIELD_esize] = (8) << ((res->fields[FIELD_size])); + res->fields_mask[FIELD_esize >> 6] |= 1LL << (FIELD_esize & 63); + /* pcode: elements = 64 DIV esize */ + res->fields[FIELD_elements] = ((res->fields[FIELD_esize]) ? ((64) / (res->fields[FIELD_esize])) : 0); + res->fields_mask[FIELD_elements >> 6] |= 1LL << (FIELD_elements & 63); + /* pcode: d = UInt(D:Vd) */ + res->fields[FIELD_d] = ((res->fields[FIELD_D]<<Vd_width)|(res->fields[FIELD_Vd])); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: m = UInt(M:Vm) */ + res->fields[FIELD_m] = ((res->fields[FIELD_M]<<Vm_width)|(res->fields[FIELD_Vm])); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + /* pcode: type = op */ + res->fields[FIELD_type] = res->fields[FIELD_op]; + res->fields_mask[FIELD_type >> 6] |= 1LL << (FIELD_type & 63); + /* pcode: fmt_idx = (op == '01') */ + res->fields[FIELD_fmt_idx] = ((res->fields[FIELD_op]) == (0x1)); + res->fields_mask[FIELD_fmt_idx >> 6] |= 1LL << (FIELD_fmt_idx & 63); + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: 05DC4844 +int vqneg(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + res->group = INSN_GROUP_NEON; + /* Encoding T1 */ + /* pattern="1111,xx11,1,D.1,11,size.2,00,Vd.4,0111,1,Q.1,M.1,0,Vm.4" width=32 stringency=20 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xF3B30F90)==0xF3B00780)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ADVSIMD)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_D] = (instr & 0x400000)>>22; + res->fields_mask[FIELD_D >> 6] |= 1LL << (FIELD_D & 63); + char D_width = 1; + res->fields[FIELD_size] = (instr & 0xC0000)>>18; + res->fields_mask[FIELD_size >> 6] |= 1LL << (FIELD_size & 63); + char size_width = 2; + res->fields[FIELD_Vd] = (instr & 0xF000)>>12; + res->fields_mask[FIELD_Vd >> 6] |= 1LL << (FIELD_Vd & 63); + char Vd_width = 4; + res->fields[FIELD_Q] = (instr & 0x40)>>6; + res->fields_mask[FIELD_Q >> 6] |= 1LL << (FIELD_Q & 63); + char Q_width = 1; + res->fields[FIELD_M] = (instr & 0x20)>>5; + res->fields_mask[FIELD_M >> 6] |= 1LL << (FIELD_M & 63); + char M_width = 1; + res->fields[FIELD_Vm] = instr & 0xF; + res->fields_mask[FIELD_Vm >> 6] |= 1LL << (FIELD_Vm & 63); + char Vm_width = 4; + + static const instruction_format instr_formats[] = + { + { /* VQNEG<c>.<dt> <Dd>,<Dm> */ + "vqneg", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_VFP_DATA_SIZE, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_m,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + { /* VQNEG<c>.<dt> <Qd>,<Qm> */ + "vqneg", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_VFP_DATA_SIZE, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"q","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_m,FIELD_UNINIT,"q","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 2; + res->mnem = armv7::ARMV7_VQNEG; + + /* pcode: if size == '11' then UNDEFINED */ + if((res->fields[FIELD_size]) == (0x3)) { + res->status |= STATUS_UNDEFINED; + } + /* pcode: if (Q == '1' && (Vd<0> == '1' || Vm<0> == '1')) then UNDEFINED */ + if((((res->fields[FIELD_Q]) == (0x1)) && (((((res->fields[FIELD_Vd] & 1)) == (0x1)) || (((res->fields[FIELD_Vm] & 1)) == (0x1)))))) { + res->status |= STATUS_UNDEFINED; + } + /* pcode: esize = 8 << UInt(size) */ + res->fields[FIELD_esize] = (8) << ((res->fields[FIELD_size])); + res->fields_mask[FIELD_esize >> 6] |= 1LL << (FIELD_esize & 63); + /* pcode: elements = 64 DIV esize */ + res->fields[FIELD_elements] = ((res->fields[FIELD_esize]) ? ((64) / (res->fields[FIELD_esize])) : 0); + res->fields_mask[FIELD_elements >> 6] |= 1LL << (FIELD_elements & 63); + /* pcode: d = UInt(D:Vd) */ + res->fields[FIELD_d] = ((res->fields[FIELD_D]<<Vd_width)|(res->fields[FIELD_Vd])); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: m = UInt(M:Vm) */ + res->fields[FIELD_m] = ((res->fields[FIELD_M]<<Vm_width)|(res->fields[FIELD_Vm])); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + /* pcode: regs = if Q == '0' then 1 else 2 */ + if((res->fields[FIELD_Q]) == (0x0)) { + res->fields[FIELD_regs] = 1; + res->fields_mask[FIELD_regs >> 6] |= 1LL << (FIELD_regs & 63); + } + else { + res->fields[FIELD_regs] = 2; + res->fields_mask[FIELD_regs >> 6] |= 1LL << (FIELD_regs & 63); + } + /* pcode: fmt_idx = (Q == '1') */ + res->fields[FIELD_fmt_idx] = ((res->fields[FIELD_Q]) == (0x1)); + res->fields_mask[FIELD_fmt_idx >> 6] |= 1LL << (FIELD_fmt_idx & 63); + /* pcode: dt = size */ + res->fields[FIELD_dt] = res->fields[FIELD_size]; + res->fields_mask[FIELD_dt >> 6] |= 1LL << (FIELD_dt & 63); + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: 6622A483 +int vqrdmulh(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + res->group = INSN_GROUP_NEON; + /* Encoding T1 */ + /* pattern="111,Q.1,1111,1,D.1,size.2,Vn.4,Vd.4,1101,N.1,1,M.1,0,Vm.4" width=32 stringency=18 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xEF800F50)==0xEF800D40)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ADVSIMD)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_Q] = (instr & 0x10000000)>>28; + res->fields_mask[FIELD_Q >> 6] |= 1LL << (FIELD_Q & 63); + char Q_width = 1; + res->fields[FIELD_D] = (instr & 0x400000)>>22; + res->fields_mask[FIELD_D >> 6] |= 1LL << (FIELD_D & 63); + char D_width = 1; + res->fields[FIELD_size] = (instr & 0x300000)>>20; + res->fields_mask[FIELD_size >> 6] |= 1LL << (FIELD_size & 63); + char size_width = 2; + res->fields[FIELD_Vn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Vn >> 6] |= 1LL << (FIELD_Vn & 63); + char Vn_width = 4; + res->fields[FIELD_Vd] = (instr & 0xF000)>>12; + res->fields_mask[FIELD_Vd >> 6] |= 1LL << (FIELD_Vd & 63); + char Vd_width = 4; + res->fields[FIELD_N] = (instr & 0x80)>>7; + res->fields_mask[FIELD_N >> 6] |= 1LL << (FIELD_N & 63); + char N_width = 1; + res->fields[FIELD_M] = (instr & 0x20)>>5; + res->fields_mask[FIELD_M >> 6] |= 1LL << (FIELD_M & 63); + char M_width = 1; + res->fields[FIELD_Vm] = instr & 0xF; + res->fields_mask[FIELD_Vm >> 6] |= 1LL << (FIELD_Vm & 63); + char Vm_width = 4; + + static const instruction_format instr_formats[] = + { + { /* VQRDMULH<c>.<dt> <Dd>,<Dn>,<Dm[x]> */ + "vqrdmulh", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_VFP_DATA_SIZE, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_n,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_INDEX,FIELD_m,FIELD_x,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + { /* VQRDMULH<c>.<dt> <Qd>,<Qn>,<Dm[x]> */ + "vqrdmulh", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_VFP_DATA_SIZE, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"q","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_n,FIELD_UNINIT,"q","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_INDEX,FIELD_m,FIELD_x,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 2; + res->mnem = armv7::ARMV7_VQRDMULH; + + /* pcode: if size == '11' then SEE advanced_simd_data_proc */ + if((res->fields[FIELD_size]) == (0x3)) { + + return advanced_simd_data_proc(req, res); + } + /* pcode: if size == '00' then UNDEFINED */ + if((res->fields[FIELD_size]) == (0x0)) { + res->status |= STATUS_UNDEFINED; + } + /* pcode: if (Q == '1' && (Vd<0> == '1' || Vn<0> == '1')) then UNDEFINED */ + if((((res->fields[FIELD_Q]) == (0x1)) && (((((res->fields[FIELD_Vd] & 1)) == (0x1)) || (((res->fields[FIELD_Vn] & 1)) == (0x1)))))) { + res->status |= STATUS_UNDEFINED; + } + /* pcode: d = UInt(D:Vd) */ + res->fields[FIELD_d] = ((res->fields[FIELD_D]<<Vd_width)|(res->fields[FIELD_Vd])); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: n = UInt(N:Vn) */ + res->fields[FIELD_n] = ((res->fields[FIELD_N]<<Vn_width)|(res->fields[FIELD_Vn])); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: regs = if Q == '0' then 1 else 2 */ + if((res->fields[FIELD_Q]) == (0x0)) { + res->fields[FIELD_regs] = 1; + res->fields_mask[FIELD_regs >> 6] |= 1LL << (FIELD_regs & 63); + } + else { + res->fields[FIELD_regs] = 2; + res->fields_mask[FIELD_regs >> 6] |= 1LL << (FIELD_regs & 63); + } + /* pcode: x = (M << 1) + Vm<3> */ + res->fields[FIELD_x] = (((res->fields[FIELD_M]) << (1))) + (((res->fields[FIELD_Vm] >> 3) & 1)); + res->fields_mask[FIELD_x >> 6] |= 1LL << (FIELD_x & 63); + /* pcode: m = UInt(Vm<2:0>) */ + res->fields[FIELD_m] = ((res->fields[FIELD_Vm] & 0x7)); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + /* pcode: if size == '01' then esize = 16 */ + if((res->fields[FIELD_size]) == (0x1)) { + res->fields[FIELD_esize] = 16; + res->fields_mask[FIELD_esize >> 6] |= 1LL << (FIELD_esize & 63); + } + /* pcode: if size == '10' then esize = 32 */ + if((res->fields[FIELD_size]) == (0x2)) { + res->fields[FIELD_esize] = 32; + res->fields_mask[FIELD_esize >> 6] |= 1LL << (FIELD_esize & 63); + } + /* pcode: elements = 64 DIV esize */ + res->fields[FIELD_elements] = ((res->fields[FIELD_esize]) ? ((64) / (res->fields[FIELD_esize])) : 0); + res->fields_mask[FIELD_elements >> 6] |= 1LL << (FIELD_elements & 63); + /* pcode: if esize == 32 then m = UInt(Vm) */ + if((res->fields[FIELD_esize]) == (32)) { + res->fields[FIELD_m] = (res->fields[FIELD_Vm]); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + } + /* pcode: if esize == 32 then x = UInt(M) */ + if((res->fields[FIELD_esize]) == (32)) { + res->fields[FIELD_x] = (res->fields[FIELD_M]); + res->fields_mask[FIELD_x >> 6] |= 1LL << (FIELD_x & 63); + } + /* pcode: fmt_idx = (Q == '1') */ + res->fields[FIELD_fmt_idx] = ((res->fields[FIELD_Q]) == (0x1)); + res->fields_mask[FIELD_fmt_idx >> 6] |= 1LL << (FIELD_fmt_idx & 63); + /* pcode: dt = size */ + res->fields[FIELD_dt] = res->fields[FIELD_size]; + res->fields_mask[FIELD_dt >> 6] |= 1LL << (FIELD_dt & 63); + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* Encoding T1 */ + /* pattern="1111,xx11,0,D.1,size.2,Vn.4,Vd.4,1011,N.1,Q.1,M.1,0,Vm.4" width=32 stringency=16 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xF3800F10)==0xF3000B00)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ADVSIMD)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_D] = (instr & 0x400000)>>22; + res->fields_mask[FIELD_D >> 6] |= 1LL << (FIELD_D & 63); + char D_width = 1; + res->fields[FIELD_size] = (instr & 0x300000)>>20; + res->fields_mask[FIELD_size >> 6] |= 1LL << (FIELD_size & 63); + char size_width = 2; + res->fields[FIELD_Vn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Vn >> 6] |= 1LL << (FIELD_Vn & 63); + char Vn_width = 4; + res->fields[FIELD_Vd] = (instr & 0xF000)>>12; + res->fields_mask[FIELD_Vd >> 6] |= 1LL << (FIELD_Vd & 63); + char Vd_width = 4; + res->fields[FIELD_N] = (instr & 0x80)>>7; + res->fields_mask[FIELD_N >> 6] |= 1LL << (FIELD_N & 63); + char N_width = 1; + res->fields[FIELD_Q] = (instr & 0x40)>>6; + res->fields_mask[FIELD_Q >> 6] |= 1LL << (FIELD_Q & 63); + char Q_width = 1; + res->fields[FIELD_M] = (instr & 0x20)>>5; + res->fields_mask[FIELD_M >> 6] |= 1LL << (FIELD_M & 63); + char M_width = 1; + res->fields[FIELD_Vm] = instr & 0xF; + res->fields_mask[FIELD_Vm >> 6] |= 1LL << (FIELD_Vm & 63); + char Vm_width = 4; + + static const instruction_format instr_formats[] = + { + { /* VQRDMULH<c>.<dt> <Dd>,<Dn>,<Dm> */ + "vqrdmulh", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_VFP_DATA_SIZE, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_n,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_m,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + { /* VQRDMULH<c>.<dt> <Qd>,<Qn>,<Qm> */ + "vqrdmulh", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_VFP_DATA_SIZE, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"q","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_n,FIELD_UNINIT,"q","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_m,FIELD_UNINIT,"q","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 2; + res->mnem = armv7::ARMV7_VQRDMULH; + + /* pcode: if (Q == '1' && (Vd<0> == '1' || Vn<0> == '1' || Vm<0> == '1')) then UNDEFINED */ + if((((res->fields[FIELD_Q]) == (0x1)) && ((((((res->fields[FIELD_Vd] & 1)) == (0x1)) || (((res->fields[FIELD_Vn] & 1)) == (0x1))) || (((res->fields[FIELD_Vm] & 1)) == (0x1)))))) { + res->status |= STATUS_UNDEFINED; + } + /* pcode: if (size == '00' || size == '11') then UNDEFINED */ + if((((res->fields[FIELD_size]) == (0x0)) || ((res->fields[FIELD_size]) == (0x3)))) { + res->status |= STATUS_UNDEFINED; + } + /* pcode: esize = 8 << UInt(size) */ + res->fields[FIELD_esize] = (8) << ((res->fields[FIELD_size])); + res->fields_mask[FIELD_esize >> 6] |= 1LL << (FIELD_esize & 63); + /* pcode: elements = 64 DIV esize */ + res->fields[FIELD_elements] = ((res->fields[FIELD_esize]) ? ((64) / (res->fields[FIELD_esize])) : 0); + res->fields_mask[FIELD_elements >> 6] |= 1LL << (FIELD_elements & 63); + /* pcode: d = UInt(D:Vd) */ + res->fields[FIELD_d] = ((res->fields[FIELD_D]<<Vd_width)|(res->fields[FIELD_Vd])); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: n = UInt(N:Vn) */ + res->fields[FIELD_n] = ((res->fields[FIELD_N]<<Vn_width)|(res->fields[FIELD_Vn])); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: m = UInt(M:Vm) */ + res->fields[FIELD_m] = ((res->fields[FIELD_M]<<Vm_width)|(res->fields[FIELD_Vm])); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + /* pcode: regs = if Q == '0' then 1 else 2 */ + if((res->fields[FIELD_Q]) == (0x0)) { + res->fields[FIELD_regs] = 1; + res->fields_mask[FIELD_regs >> 6] |= 1LL << (FIELD_regs & 63); + } + else { + res->fields[FIELD_regs] = 2; + res->fields_mask[FIELD_regs >> 6] |= 1LL << (FIELD_regs & 63); + } + /* pcode: fmt_idx = (Q == '1') */ + res->fields[FIELD_fmt_idx] = ((res->fields[FIELD_Q]) == (0x1)); + res->fields_mask[FIELD_fmt_idx >> 6] |= 1LL << (FIELD_fmt_idx & 63); + /* pcode: dt = size */ + res->fields[FIELD_dt] = res->fields[FIELD_size]; + res->fields_mask[FIELD_dt >> 6] |= 1LL << (FIELD_dt & 63); + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: B8EFF218 +int vqrshl(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + res->group = INSN_GROUP_NEON; + /* Encoding T1 */ + /* pattern="111,U.1,1111,0,D.1,size.2,Vn.4,Vd.4,0101,N.1,Q.1,M.1,1,Vm.4" width=32 stringency=18 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xEF800F10)==0xEF000510)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ADVSIMD)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_U] = (instr & 0x10000000)>>28; + res->fields_mask[FIELD_U >> 6] |= 1LL << (FIELD_U & 63); + char U_width = 1; + res->fields[FIELD_D] = (instr & 0x400000)>>22; + res->fields_mask[FIELD_D >> 6] |= 1LL << (FIELD_D & 63); + char D_width = 1; + res->fields[FIELD_size] = (instr & 0x300000)>>20; + res->fields_mask[FIELD_size >> 6] |= 1LL << (FIELD_size & 63); + char size_width = 2; + res->fields[FIELD_Vn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Vn >> 6] |= 1LL << (FIELD_Vn & 63); + char Vn_width = 4; + res->fields[FIELD_Vd] = (instr & 0xF000)>>12; + res->fields_mask[FIELD_Vd >> 6] |= 1LL << (FIELD_Vd & 63); + char Vd_width = 4; + res->fields[FIELD_N] = (instr & 0x80)>>7; + res->fields_mask[FIELD_N >> 6] |= 1LL << (FIELD_N & 63); + char N_width = 1; + res->fields[FIELD_Q] = (instr & 0x40)>>6; + res->fields_mask[FIELD_Q >> 6] |= 1LL << (FIELD_Q & 63); + char Q_width = 1; + res->fields[FIELD_M] = (instr & 0x20)>>5; + res->fields_mask[FIELD_M >> 6] |= 1LL << (FIELD_M & 63); + char M_width = 1; + res->fields[FIELD_Vm] = instr & 0xF; + res->fields_mask[FIELD_Vm >> 6] |= 1LL << (FIELD_Vm & 63); + char Vm_width = 4; + + static const instruction_format instr_formats[] = + { + { /* VQRSHL<c>.<dt> <Dd>,<Dm>,<Dn> */ + "vqrshl", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_VFP_DATA_SIZE, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_m,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_n,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + { /* VQRSHL<c>.<dt> <Qd>,<Qm>,<Qn> */ + "vqrshl", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_VFP_DATA_SIZE, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"q","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_m,FIELD_UNINIT,"q","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_n,FIELD_UNINIT,"q","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 2; + res->mnem = armv7::ARMV7_VQRSHL; + + /* pcode: if (Q == '1' && (Vd<0> == '1' || Vm<0> == '1' || Vn<0> == '1')) then UNDEFINED */ + if((((res->fields[FIELD_Q]) == (0x1)) && ((((((res->fields[FIELD_Vd] & 1)) == (0x1)) || (((res->fields[FIELD_Vm] & 1)) == (0x1))) || (((res->fields[FIELD_Vn] & 1)) == (0x1)))))) { + res->status |= STATUS_UNDEFINED; + } + /* pcode: unsigned = (U == '1') */ + res->fields[FIELD_unsigned] = ((res->fields[FIELD_U]) == (0x1)); + res->fields_mask[FIELD_unsigned >> 6] |= 1LL << (FIELD_unsigned & 63); + /* pcode: esize = 8 << UInt(size) */ + res->fields[FIELD_esize] = (8) << ((res->fields[FIELD_size])); + res->fields_mask[FIELD_esize >> 6] |= 1LL << (FIELD_esize & 63); + /* pcode: elements = 64 DIV esize */ + res->fields[FIELD_elements] = ((res->fields[FIELD_esize]) ? ((64) / (res->fields[FIELD_esize])) : 0); + res->fields_mask[FIELD_elements >> 6] |= 1LL << (FIELD_elements & 63); + /* pcode: d = UInt(D:Vd) */ + res->fields[FIELD_d] = ((res->fields[FIELD_D]<<Vd_width)|(res->fields[FIELD_Vd])); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: m = UInt(M:Vm) */ + res->fields[FIELD_m] = ((res->fields[FIELD_M]<<Vm_width)|(res->fields[FIELD_Vm])); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + /* pcode: n = UInt(N:Vn) */ + res->fields[FIELD_n] = ((res->fields[FIELD_N]<<Vn_width)|(res->fields[FIELD_Vn])); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: regs = if Q == '0' then 1 else 2 */ + if((res->fields[FIELD_Q]) == (0x0)) { + res->fields[FIELD_regs] = 1; + res->fields_mask[FIELD_regs >> 6] |= 1LL << (FIELD_regs & 63); + } + else { + res->fields[FIELD_regs] = 2; + res->fields_mask[FIELD_regs >> 6] |= 1LL << (FIELD_regs & 63); + } + /* pcode: fmt_idx = (Q == '1') */ + res->fields[FIELD_fmt_idx] = ((res->fields[FIELD_Q]) == (0x1)); + res->fields_mask[FIELD_fmt_idx >> 6] |= 1LL << (FIELD_fmt_idx & 63); + /* pcode: dt = UInt(U:size) */ + res->fields[FIELD_dt] = ((res->fields[FIELD_U]<<size_width)|(res->fields[FIELD_size])); + res->fields_mask[FIELD_dt >> 6] |= 1LL << (FIELD_dt & 63); + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: 55D05E33 +int vqrshrn(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + res->group = INSN_GROUP_NEON; + /* Encoding T1 */ + /* pattern="111,U.1,1111,1,D.1,imm6.6,Vd.4,100,op.1,01,M.1,1,Vm.4" width=32 stringency=18 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xEF800ED0)==0xEF800850)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ADVSIMD)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_U] = (instr & 0x10000000)>>28; + res->fields_mask[FIELD_U >> 6] |= 1LL << (FIELD_U & 63); + char U_width = 1; + res->fields[FIELD_D] = (instr & 0x400000)>>22; + res->fields_mask[FIELD_D >> 6] |= 1LL << (FIELD_D & 63); + char D_width = 1; + res->fields[FIELD_imm6] = (instr & 0x3F0000)>>16; + res->fields_mask[FIELD_imm6 >> 6] |= 1LL << (FIELD_imm6 & 63); + char imm6_width = 6; + res->fields[FIELD_Vd] = (instr & 0xF000)>>12; + res->fields_mask[FIELD_Vd >> 6] |= 1LL << (FIELD_Vd & 63); + char Vd_width = 4; + res->fields[FIELD_op] = (instr & 0x100)>>8; + res->fields_mask[FIELD_op >> 6] |= 1LL << (FIELD_op & 63); + char op_width = 1; + res->fields[FIELD_M] = (instr & 0x20)>>5; + res->fields_mask[FIELD_M >> 6] |= 1LL << (FIELD_M & 63); + char M_width = 1; + res->fields[FIELD_Vm] = instr & 0xF; + res->fields_mask[FIELD_Vm >> 6] |= 1LL << (FIELD_Vm & 63); + char Vm_width = 4; + + static const instruction_format instr_formats[] = + { + { /* VQRSHRN<c>.<type><size> <Dd>,<Qm>,#<imm> */ + "vqrshrn", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_NEON_TYPE_SIZE|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_m,FIELD_UNINIT,"q","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_IMM,FIELD_imm,FIELD_UNINIT,"#","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + { /* VQRSHRUN<c>.<type><size> <Dd>,<Qm>,#<imm> */ + "vqrshrun", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_NEON_TYPE_SIZE|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_m,FIELD_UNINIT,"q","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_IMM,FIELD_imm,FIELD_UNINIT,"#","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 2; + res->mnem = armv7::ARMV7_VQRSHRN; + + /* pcode: if UInt(imm6) < 8 then SEE advsimd_one_reg_mod_imm */ + if(((res->fields[FIELD_imm6])) < (8)) { + + return advsimd_one_reg_mod_imm(req, res); + } + /* pcode: if (U == '0' && op == '0') then SEE vshrn */ + if((((res->fields[FIELD_U]) == (0x0)) && ((res->fields[FIELD_op]) == (0x0)))) { + + return vshrn(req, res); + } + /* pcode: if Vm<0> == '1' then UNDEFINED */ + if(((res->fields[FIELD_Vm] & 1)) == (0x1)) { + res->status |= STATUS_UNDEFINED; + } + /* pcode: esize = 32 */ + res->fields[FIELD_esize] = 32; + res->fields_mask[FIELD_esize >> 6] |= 1LL << (FIELD_esize & 63); + /* pcode: if UInt(imm6) < 32 then esize = 16 */ + if(((res->fields[FIELD_imm6])) < (32)) { + res->fields[FIELD_esize] = 16; + res->fields_mask[FIELD_esize >> 6] |= 1LL << (FIELD_esize & 63); + } + /* pcode: if UInt(imm6) < 16 then esize = 8 */ + if(((res->fields[FIELD_imm6])) < (16)) { + res->fields[FIELD_esize] = 8; + res->fields_mask[FIELD_esize >> 6] |= 1LL << (FIELD_esize & 63); + } + /* pcode: elements = 64 DIV esize */ + res->fields[FIELD_elements] = ((res->fields[FIELD_esize]) ? ((64) / (res->fields[FIELD_esize])) : 0); + res->fields_mask[FIELD_elements >> 6] |= 1LL << (FIELD_elements & 63); + /* pcode: src_unsigned = (U == '1' && op == '1') */ + res->fields[FIELD_src_unsigned] = (((res->fields[FIELD_U]) == (0x1)) && ((res->fields[FIELD_op]) == (0x1))); + res->fields_mask[FIELD_src_unsigned >> 6] |= 1LL << (FIELD_src_unsigned & 63); + /* pcode: dest_unsigned = (U == '1') */ + res->fields[FIELD_dest_unsigned] = ((res->fields[FIELD_U]) == (0x1)); + res->fields_mask[FIELD_dest_unsigned >> 6] |= 1LL << (FIELD_dest_unsigned & 63); + /* pcode: d = UInt(D:Vd) */ + res->fields[FIELD_d] = ((res->fields[FIELD_D]<<Vd_width)|(res->fields[FIELD_Vd])); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: m = UInt(M:Vm) */ + res->fields[FIELD_m] = ((res->fields[FIELD_M]<<Vm_width)|(res->fields[FIELD_Vm])); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + /* pcode: fmt_idx = (op == '0') */ + res->fields[FIELD_fmt_idx] = ((res->fields[FIELD_op]) == (0x0)); + res->fields_mask[FIELD_fmt_idx >> 6] |= 1LL << (FIELD_fmt_idx & 63); + /* pcode: imm = imm6 */ + res->fields[FIELD_imm] = res->fields[FIELD_imm6]; + res->fields_mask[FIELD_imm >> 6] |= 1LL << (FIELD_imm & 63); + /* pcode: type = UInt(U:op) */ + res->fields[FIELD_type] = ((res->fields[FIELD_U]<<op_width)|(res->fields[FIELD_op])); + res->fields_mask[FIELD_type >> 6] |= 1LL << (FIELD_type & 63); + /* pcode: if esize == 32 then size = 2 */ + if((res->fields[FIELD_esize]) == (32)) { + res->fields[FIELD_size] = 2; + res->fields_mask[FIELD_size >> 6] |= 1LL << (FIELD_size & 63); + } + /* pcode: if esize == 16 then size = 1 */ + if((res->fields[FIELD_esize]) == (16)) { + res->fields[FIELD_size] = 1; + res->fields_mask[FIELD_size >> 6] |= 1LL << (FIELD_size & 63); + } + /* pcode: if esize == 8 then size = 0 */ + if((res->fields[FIELD_esize]) == (8)) { + res->fields[FIELD_size] = 0; + res->fields_mask[FIELD_size >> 6] |= 1LL << (FIELD_size & 63); + } + /* pcode: if esize == 32 then imm = 32 - UInt(imm6<4:0>) */ + if((res->fields[FIELD_esize]) == (32)) { + res->fields[FIELD_imm] = (32) - (((res->fields[FIELD_imm6] & 0x1F))); + res->fields_mask[FIELD_imm >> 6] |= 1LL << (FIELD_imm & 63); + } + /* pcode: if esize == 16 then imm = 16 - UInt(imm6<3:0>) */ + if((res->fields[FIELD_esize]) == (16)) { + res->fields[FIELD_imm] = (16) - (((res->fields[FIELD_imm6] & 0xF))); + res->fields_mask[FIELD_imm >> 6] |= 1LL << (FIELD_imm & 63); + } + /* pcode: if esize == 8 then imm = 8 - UInt(imm6<2:0>) */ + if((res->fields[FIELD_esize]) == (8)) { + res->fields[FIELD_imm] = (8) - (((res->fields[FIELD_imm6] & 0x7))); + res->fields_mask[FIELD_imm >> 6] |= 1LL << (FIELD_imm & 63); + } + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: E097A29C +int vqshl_immediate(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + res->group = INSN_GROUP_NEON; + /* Encoding T1 */ + /* pattern="111,U.1,1111,1,D.1,imm6.6,Vd.4,011,op.1,L.1,Q.1,M.1,1,Vm.4" width=32 stringency=18 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xEF800E10)==0xEF800610)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ADVSIMD)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_U] = (instr & 0x10000000)>>28; + res->fields_mask[FIELD_U >> 6] |= 1LL << (FIELD_U & 63); + char U_width = 1; + res->fields[FIELD_D] = (instr & 0x400000)>>22; + res->fields_mask[FIELD_D >> 6] |= 1LL << (FIELD_D & 63); + char D_width = 1; + res->fields[FIELD_imm6] = (instr & 0x3F0000)>>16; + res->fields_mask[FIELD_imm6 >> 6] |= 1LL << (FIELD_imm6 & 63); + char imm6_width = 6; + res->fields[FIELD_Vd] = (instr & 0xF000)>>12; + res->fields_mask[FIELD_Vd >> 6] |= 1LL << (FIELD_Vd & 63); + char Vd_width = 4; + res->fields[FIELD_op] = (instr & 0x100)>>8; + res->fields_mask[FIELD_op >> 6] |= 1LL << (FIELD_op & 63); + char op_width = 1; + res->fields[FIELD_L] = (instr & 0x80)>>7; + res->fields_mask[FIELD_L >> 6] |= 1LL << (FIELD_L & 63); + char L_width = 1; + res->fields[FIELD_Q] = (instr & 0x40)>>6; + res->fields_mask[FIELD_Q >> 6] |= 1LL << (FIELD_Q & 63); + char Q_width = 1; + res->fields[FIELD_M] = (instr & 0x20)>>5; + res->fields_mask[FIELD_M >> 6] |= 1LL << (FIELD_M & 63); + char M_width = 1; + res->fields[FIELD_Vm] = instr & 0xF; + res->fields_mask[FIELD_Vm >> 6] |= 1LL << (FIELD_Vm & 63); + char Vm_width = 4; + + static const instruction_format instr_formats[] = + { + { /* VQSHL<c>.<type><size> <Dd>,<Dm>,#<imm> */ + "vqshl", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_NEON_TYPE_SIZE|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_m,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_IMM,FIELD_imm,FIELD_UNINIT,"#","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + { /* VQSHL<c>.<type><size> <Qd>,<Qm>,#<imm> */ + "vqshl", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_NEON_TYPE_SIZE|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"q","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_m,FIELD_UNINIT,"q","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_IMM,FIELD_imm,FIELD_UNINIT,"#","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + { /* VQSHLU<c>.<type><size> <Dd>,<Dm>,#<imm> */ + "vqshlu", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_NEON_TYPE_SIZE|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_m,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_IMM,FIELD_imm,FIELD_UNINIT,"#","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + { /* VQSHLU<c>.<type><size> <Qd>,<Qm>,#<imm> */ + "vqshlu", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_NEON_TYPE_SIZE|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"q","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_m,FIELD_UNINIT,"q","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_IMM,FIELD_imm,FIELD_UNINIT,"#","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 4; + res->mnem = armv7::ARMV7_VQSHL; + + /* pcode: if (L == '0' && UInt(imm6) < 8) then SEE advsimd_one_reg_mod_imm */ + if((((res->fields[FIELD_L]) == (0x0)) && (((res->fields[FIELD_imm6])) < (8)))) { + + return advsimd_one_reg_mod_imm(req, res); + } + /* pcode: if (U == '0' && op == '0') then UNDEFINED */ + if((((res->fields[FIELD_U]) == (0x0)) && ((res->fields[FIELD_op]) == (0x0)))) { + res->status |= STATUS_UNDEFINED; + } + /* pcode: if (Q == '1' && (Vd<0> == '1' || Vm<0> == '1')) then UNDEFINED */ + if((((res->fields[FIELD_Q]) == (0x1)) && (((((res->fields[FIELD_Vd] & 1)) == (0x1)) || (((res->fields[FIELD_Vm] & 1)) == (0x1)))))) { + res->status |= STATUS_UNDEFINED; + } + /* pcode: if UInt(L:imm6) < 128 then esize = 64 */ + if((((res->fields[FIELD_L]<<6)|(res->fields[FIELD_imm6]))) < (128)) { + res->fields[FIELD_esize] = 64; + res->fields_mask[FIELD_esize >> 6] |= 1LL << (FIELD_esize & 63); + } + /* pcode: if UInt(L:imm6) < 64 then esize = 32 */ + if((((res->fields[FIELD_L]<<6)|(res->fields[FIELD_imm6]))) < (64)) { + res->fields[FIELD_esize] = 32; + res->fields_mask[FIELD_esize >> 6] |= 1LL << (FIELD_esize & 63); + } + /* pcode: if UInt(L:imm6) < 32 then esize = 16 */ + if((((res->fields[FIELD_L]<<6)|(res->fields[FIELD_imm6]))) < (32)) { + res->fields[FIELD_esize] = 16; + res->fields_mask[FIELD_esize >> 6] |= 1LL << (FIELD_esize & 63); + } + /* pcode: if UInt(L:imm6) < 16 then esize = 8 */ + if((((res->fields[FIELD_L]<<6)|(res->fields[FIELD_imm6]))) < (16)) { + res->fields[FIELD_esize] = 8; + res->fields_mask[FIELD_esize >> 6] |= 1LL << (FIELD_esize & 63); + } + /* pcode: elements = 64 DIV esize */ + res->fields[FIELD_elements] = ((res->fields[FIELD_esize]) ? ((64) / (res->fields[FIELD_esize])) : 0); + res->fields_mask[FIELD_elements >> 6] |= 1LL << (FIELD_elements & 63); + /* pcode: src_unsigned = (U == '1' && op == '1') */ + res->fields[FIELD_src_unsigned] = (((res->fields[FIELD_U]) == (0x1)) && ((res->fields[FIELD_op]) == (0x1))); + res->fields_mask[FIELD_src_unsigned >> 6] |= 1LL << (FIELD_src_unsigned & 63); + /* pcode: dest_unsigned = (U == '1') */ + res->fields[FIELD_dest_unsigned] = ((res->fields[FIELD_U]) == (0x1)); + res->fields_mask[FIELD_dest_unsigned >> 6] |= 1LL << (FIELD_dest_unsigned & 63); + /* pcode: d = UInt(D:Vd) */ + res->fields[FIELD_d] = ((res->fields[FIELD_D]<<Vd_width)|(res->fields[FIELD_Vd])); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: m = UInt(M:Vm) */ + res->fields[FIELD_m] = ((res->fields[FIELD_M]<<Vm_width)|(res->fields[FIELD_Vm])); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + /* pcode: regs = if Q == '0' then 1 else 2 */ + if((res->fields[FIELD_Q]) == (0x0)) { + res->fields[FIELD_regs] = 1; + res->fields_mask[FIELD_regs >> 6] |= 1LL << (FIELD_regs & 63); + } + else { + res->fields[FIELD_regs] = 2; + res->fields_mask[FIELD_regs >> 6] |= 1LL << (FIELD_regs & 63); + } + /* pcode: fmt_idx = (op == '0') */ + res->fields[FIELD_fmt_idx] = ((res->fields[FIELD_op]) == (0x0)); + res->fields_mask[FIELD_fmt_idx >> 6] |= 1LL << (FIELD_fmt_idx & 63); + /* pcode: fmt_idx = fmt_idx + fmt_idx */ + res->fields[FIELD_fmt_idx] = (res->fields[FIELD_fmt_idx]) + (res->fields[FIELD_fmt_idx]); + res->fields_mask[FIELD_fmt_idx >> 6] |= 1LL << (FIELD_fmt_idx & 63); + /* pcode: fmt_idx = fmt_idx + (Q == '1') */ + res->fields[FIELD_fmt_idx] = (res->fields[FIELD_fmt_idx]) + (((res->fields[FIELD_Q]) == (0x1))); + res->fields_mask[FIELD_fmt_idx >> 6] |= 1LL << (FIELD_fmt_idx & 63); + /* pcode: imm = imm6 */ + res->fields[FIELD_imm] = res->fields[FIELD_imm6]; + res->fields_mask[FIELD_imm >> 6] |= 1LL << (FIELD_imm & 63); + /* pcode: type = UInt(U:op) */ + res->fields[FIELD_type] = ((res->fields[FIELD_U]<<op_width)|(res->fields[FIELD_op])); + res->fields_mask[FIELD_type >> 6] |= 1LL << (FIELD_type & 63); + /* pcode: if esize == 64 then size = 2 */ + if((res->fields[FIELD_esize]) == (64)) { + res->fields[FIELD_size] = 2; + res->fields_mask[FIELD_size >> 6] |= 1LL << (FIELD_size & 63); + } + /* pcode: if esize == 32 then size = 1 */ + if((res->fields[FIELD_esize]) == (32)) { + res->fields[FIELD_size] = 1; + res->fields_mask[FIELD_size >> 6] |= 1LL << (FIELD_size & 63); + } + /* pcode: if esize == 16 then size = 0 */ + if((res->fields[FIELD_esize]) == (16)) { + res->fields[FIELD_size] = 0; + res->fields_mask[FIELD_size >> 6] |= 1LL << (FIELD_size & 63); + } + /* pcode: if esize == 8 then size = 3 */ + if((res->fields[FIELD_esize]) == (8)) { + res->fields[FIELD_size] = 3; + res->fields_mask[FIELD_size >> 6] |= 1LL << (FIELD_size & 63); + } + /* pcode: if esize == 64 then imm = UInt(imm6) */ + if((res->fields[FIELD_esize]) == (64)) { + res->fields[FIELD_imm] = (res->fields[FIELD_imm6]); + res->fields_mask[FIELD_imm >> 6] |= 1LL << (FIELD_imm & 63); + } + /* pcode: if esize == 32 then imm = UInt(imm6) - 32 */ + if((res->fields[FIELD_esize]) == (32)) { + res->fields[FIELD_imm] = ((res->fields[FIELD_imm6])) - (32); + res->fields_mask[FIELD_imm >> 6] |= 1LL << (FIELD_imm & 63); + } + /* pcode: if esize == 16 then imm = UInt(imm6) - 16 */ + if((res->fields[FIELD_esize]) == (16)) { + res->fields[FIELD_imm] = ((res->fields[FIELD_imm6])) - (16); + res->fields_mask[FIELD_imm >> 6] |= 1LL << (FIELD_imm & 63); + } + /* pcode: if esize == 8 then imm = UInt(imm6) - 8 */ + if((res->fields[FIELD_esize]) == (8)) { + res->fields[FIELD_imm] = ((res->fields[FIELD_imm6])) - (8); + res->fields_mask[FIELD_imm >> 6] |= 1LL << (FIELD_imm & 63); + } + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: 56C43EAE +int vqshl_register(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + res->group = INSN_GROUP_NEON; + /* Encoding T1 */ + /* pattern="111,U.1,1111,0,D.1,size.2,Vn.4,Vd.4,0100,N.1,Q.1,M.1,1,Vm.4" width=32 stringency=18 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xEF800F10)==0xEF000410)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ADVSIMD)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_U] = (instr & 0x10000000)>>28; + res->fields_mask[FIELD_U >> 6] |= 1LL << (FIELD_U & 63); + char U_width = 1; + res->fields[FIELD_D] = (instr & 0x400000)>>22; + res->fields_mask[FIELD_D >> 6] |= 1LL << (FIELD_D & 63); + char D_width = 1; + res->fields[FIELD_size] = (instr & 0x300000)>>20; + res->fields_mask[FIELD_size >> 6] |= 1LL << (FIELD_size & 63); + char size_width = 2; + res->fields[FIELD_Vn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Vn >> 6] |= 1LL << (FIELD_Vn & 63); + char Vn_width = 4; + res->fields[FIELD_Vd] = (instr & 0xF000)>>12; + res->fields_mask[FIELD_Vd >> 6] |= 1LL << (FIELD_Vd & 63); + char Vd_width = 4; + res->fields[FIELD_N] = (instr & 0x80)>>7; + res->fields_mask[FIELD_N >> 6] |= 1LL << (FIELD_N & 63); + char N_width = 1; + res->fields[FIELD_Q] = (instr & 0x40)>>6; + res->fields_mask[FIELD_Q >> 6] |= 1LL << (FIELD_Q & 63); + char Q_width = 1; + res->fields[FIELD_M] = (instr & 0x20)>>5; + res->fields_mask[FIELD_M >> 6] |= 1LL << (FIELD_M & 63); + char M_width = 1; + res->fields[FIELD_Vm] = instr & 0xF; + res->fields_mask[FIELD_Vm >> 6] |= 1LL << (FIELD_Vm & 63); + char Vm_width = 4; + + static const instruction_format instr_formats[] = + { + { /* VQSHL<c>.<dt> <Dd>,<Dm>,<Dn> */ + "vqshl", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_VFP_DATA_SIZE, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_m,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_n,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + { /* VQSHL<c>.<dt> <Qd>,<Qm>,<Qn> */ + "vqshl", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_VFP_DATA_SIZE, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"q","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_m,FIELD_UNINIT,"q","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_n,FIELD_UNINIT,"q","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 2; + res->mnem = armv7::ARMV7_VQSHL; + + /* pcode: if (Q == '1' && (Vd<0> == '1' || Vm<0> == '1' || Vn<0> == '1')) then UNDEFINED */ + if((((res->fields[FIELD_Q]) == (0x1)) && ((((((res->fields[FIELD_Vd] & 1)) == (0x1)) || (((res->fields[FIELD_Vm] & 1)) == (0x1))) || (((res->fields[FIELD_Vn] & 1)) == (0x1)))))) { + res->status |= STATUS_UNDEFINED; + } + /* pcode: unsigned = (U == '1') */ + res->fields[FIELD_unsigned] = ((res->fields[FIELD_U]) == (0x1)); + res->fields_mask[FIELD_unsigned >> 6] |= 1LL << (FIELD_unsigned & 63); + /* pcode: esize = 8 << UInt(size) */ + res->fields[FIELD_esize] = (8) << ((res->fields[FIELD_size])); + res->fields_mask[FIELD_esize >> 6] |= 1LL << (FIELD_esize & 63); + /* pcode: elements = 64 DIV esize */ + res->fields[FIELD_elements] = ((res->fields[FIELD_esize]) ? ((64) / (res->fields[FIELD_esize])) : 0); + res->fields_mask[FIELD_elements >> 6] |= 1LL << (FIELD_elements & 63); + /* pcode: d = UInt(D:Vd) */ + res->fields[FIELD_d] = ((res->fields[FIELD_D]<<Vd_width)|(res->fields[FIELD_Vd])); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: m = UInt(M:Vm) */ + res->fields[FIELD_m] = ((res->fields[FIELD_M]<<Vm_width)|(res->fields[FIELD_Vm])); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + /* pcode: n = UInt(N:Vn) */ + res->fields[FIELD_n] = ((res->fields[FIELD_N]<<Vn_width)|(res->fields[FIELD_Vn])); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: regs = if Q == '0' then 1 else 2 */ + if((res->fields[FIELD_Q]) == (0x0)) { + res->fields[FIELD_regs] = 1; + res->fields_mask[FIELD_regs >> 6] |= 1LL << (FIELD_regs & 63); + } + else { + res->fields[FIELD_regs] = 2; + res->fields_mask[FIELD_regs >> 6] |= 1LL << (FIELD_regs & 63); + } + /* pcode: fmt_idx = (Q == '1') */ + res->fields[FIELD_fmt_idx] = ((res->fields[FIELD_Q]) == (0x1)); + res->fields_mask[FIELD_fmt_idx >> 6] |= 1LL << (FIELD_fmt_idx & 63); + /* pcode: dt = UInt(U:size) */ + res->fields[FIELD_dt] = ((res->fields[FIELD_U]<<size_width)|(res->fields[FIELD_size])); + res->fields_mask[FIELD_dt >> 6] |= 1LL << (FIELD_dt & 63); + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: A5E77269 +int vqshrn(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + res->group = INSN_GROUP_NEON; + /* Encoding T1 */ + /* pattern="111,U.1,1111,1,D.1,imm6.6,Vd.4,100,op.1,00,M.1,1,Vm.4" width=32 stringency=18 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xEF800ED0)==0xEF800810)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ADVSIMD)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_U] = (instr & 0x10000000)>>28; + res->fields_mask[FIELD_U >> 6] |= 1LL << (FIELD_U & 63); + char U_width = 1; + res->fields[FIELD_D] = (instr & 0x400000)>>22; + res->fields_mask[FIELD_D >> 6] |= 1LL << (FIELD_D & 63); + char D_width = 1; + res->fields[FIELD_imm6] = (instr & 0x3F0000)>>16; + res->fields_mask[FIELD_imm6 >> 6] |= 1LL << (FIELD_imm6 & 63); + char imm6_width = 6; + res->fields[FIELD_Vd] = (instr & 0xF000)>>12; + res->fields_mask[FIELD_Vd >> 6] |= 1LL << (FIELD_Vd & 63); + char Vd_width = 4; + res->fields[FIELD_op] = (instr & 0x100)>>8; + res->fields_mask[FIELD_op >> 6] |= 1LL << (FIELD_op & 63); + char op_width = 1; + res->fields[FIELD_M] = (instr & 0x20)>>5; + res->fields_mask[FIELD_M >> 6] |= 1LL << (FIELD_M & 63); + char M_width = 1; + res->fields[FIELD_Vm] = instr & 0xF; + res->fields_mask[FIELD_Vm >> 6] |= 1LL << (FIELD_Vm & 63); + char Vm_width = 4; + + static const instruction_format instr_formats[] = + { + { /* VQSHRN<c>.<type><size> <Dd>,<Qm>,#<imm> */ + "vqshrn", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_NEON_TYPE_SIZE|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_m,FIELD_UNINIT,"q","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_IMM,FIELD_imm,FIELD_UNINIT,"#","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + { /* VQSHRUN<c>.<type><size> <Dd>,<Qm>,#<imm> */ + "vqshrun", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_NEON_TYPE_SIZE|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_m,FIELD_UNINIT,"q","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_IMM,FIELD_imm,FIELD_UNINIT,"#","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 2; + res->mnem = armv7::ARMV7_VQSHRN; + + /* pcode: if UInt(imm6) < 8 then SEE advsimd_one_reg_mod_imm */ + if(((res->fields[FIELD_imm6])) < (8)) { + + return advsimd_one_reg_mod_imm(req, res); + } + /* pcode: if (U == '0' && op == '0') then SEE vshrn */ + if((((res->fields[FIELD_U]) == (0x0)) && ((res->fields[FIELD_op]) == (0x0)))) { + + return vshrn(req, res); + } + /* pcode: if Vm<0> == '1' then UNDEFINED */ + if(((res->fields[FIELD_Vm] & 1)) == (0x1)) { + res->status |= STATUS_UNDEFINED; + } + /* pcode: if UInt(imm6) < 64 then esize = 32 */ + if(((res->fields[FIELD_imm6])) < (64)) { + res->fields[FIELD_esize] = 32; + res->fields_mask[FIELD_esize >> 6] |= 1LL << (FIELD_esize & 63); + } + /* pcode: if UInt(imm6) < 32 then esize = 16 */ + if(((res->fields[FIELD_imm6])) < (32)) { + res->fields[FIELD_esize] = 16; + res->fields_mask[FIELD_esize >> 6] |= 1LL << (FIELD_esize & 63); + } + /* pcode: if UInt(imm6) < 16 then esize = 8 */ + if(((res->fields[FIELD_imm6])) < (16)) { + res->fields[FIELD_esize] = 8; + res->fields_mask[FIELD_esize >> 6] |= 1LL << (FIELD_esize & 63); + } + /* pcode: elements = 64 DIV esize */ + res->fields[FIELD_elements] = ((res->fields[FIELD_esize]) ? ((64) / (res->fields[FIELD_esize])) : 0); + res->fields_mask[FIELD_elements >> 6] |= 1LL << (FIELD_elements & 63); + /* pcode: src_unsigned = (U == '1' && op == '1') */ + res->fields[FIELD_src_unsigned] = (((res->fields[FIELD_U]) == (0x1)) && ((res->fields[FIELD_op]) == (0x1))); + res->fields_mask[FIELD_src_unsigned >> 6] |= 1LL << (FIELD_src_unsigned & 63); + /* pcode: dest_unsigned = (U == '1') */ + res->fields[FIELD_dest_unsigned] = ((res->fields[FIELD_U]) == (0x1)); + res->fields_mask[FIELD_dest_unsigned >> 6] |= 1LL << (FIELD_dest_unsigned & 63); + /* pcode: d = UInt(D:Vd) */ + res->fields[FIELD_d] = ((res->fields[FIELD_D]<<Vd_width)|(res->fields[FIELD_Vd])); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: m = UInt(M:Vm) */ + res->fields[FIELD_m] = ((res->fields[FIELD_M]<<Vm_width)|(res->fields[FIELD_Vm])); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + /* pcode: fmt_idx = (op == '0') */ + res->fields[FIELD_fmt_idx] = ((res->fields[FIELD_op]) == (0x0)); + res->fields_mask[FIELD_fmt_idx >> 6] |= 1LL << (FIELD_fmt_idx & 63); + /* pcode: imm = imm6 */ + res->fields[FIELD_imm] = res->fields[FIELD_imm6]; + res->fields_mask[FIELD_imm >> 6] |= 1LL << (FIELD_imm & 63); + /* pcode: type = UInt(U:op) */ + res->fields[FIELD_type] = ((res->fields[FIELD_U]<<op_width)|(res->fields[FIELD_op])); + res->fields_mask[FIELD_type >> 6] |= 1LL << (FIELD_type & 63); + /* pcode: if esize == 32 then size = 2 */ + if((res->fields[FIELD_esize]) == (32)) { + res->fields[FIELD_size] = 2; + res->fields_mask[FIELD_size >> 6] |= 1LL << (FIELD_size & 63); + } + /* pcode: if esize == 16 then size = 1 */ + if((res->fields[FIELD_esize]) == (16)) { + res->fields[FIELD_size] = 1; + res->fields_mask[FIELD_size >> 6] |= 1LL << (FIELD_size & 63); + } + /* pcode: if esize == 8 then size = 0 */ + if((res->fields[FIELD_esize]) == (8)) { + res->fields[FIELD_size] = 0; + res->fields_mask[FIELD_size >> 6] |= 1LL << (FIELD_size & 63); + } + /* pcode: if esize == 32 then imm = 32 - UInt(imm6<4:0>) */ + if((res->fields[FIELD_esize]) == (32)) { + res->fields[FIELD_imm] = (32) - (((res->fields[FIELD_imm6] & 0x1F))); + res->fields_mask[FIELD_imm >> 6] |= 1LL << (FIELD_imm & 63); + } + /* pcode: if esize == 16 then imm = 16 - UInt(imm6<3:0>) */ + if((res->fields[FIELD_esize]) == (16)) { + res->fields[FIELD_imm] = (16) - (((res->fields[FIELD_imm6] & 0xF))); + res->fields_mask[FIELD_imm >> 6] |= 1LL << (FIELD_imm & 63); + } + /* pcode: if esize == 8 then imm = 8 - UInt(imm6<2:0>) */ + if((res->fields[FIELD_esize]) == (8)) { + res->fields[FIELD_imm] = (8) - (((res->fields[FIELD_imm6] & 0x7))); + res->fields_mask[FIELD_imm >> 6] |= 1LL << (FIELD_imm & 63); + } + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: 6592C983 +int vqsub(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + res->group = INSN_GROUP_NEON; + /* Encoding T1 */ + /* pattern="111,U.1,1111,0,D.1,size.2,Vn.4,Vd.4,0010,N.1,Q.1,M.1,1,Vm.4" width=32 stringency=18 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xEF800F10)==0xEF000210)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ADVSIMD)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_U] = (instr & 0x10000000)>>28; + res->fields_mask[FIELD_U >> 6] |= 1LL << (FIELD_U & 63); + char U_width = 1; + res->fields[FIELD_D] = (instr & 0x400000)>>22; + res->fields_mask[FIELD_D >> 6] |= 1LL << (FIELD_D & 63); + char D_width = 1; + res->fields[FIELD_size] = (instr & 0x300000)>>20; + res->fields_mask[FIELD_size >> 6] |= 1LL << (FIELD_size & 63); + char size_width = 2; + res->fields[FIELD_Vn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Vn >> 6] |= 1LL << (FIELD_Vn & 63); + char Vn_width = 4; + res->fields[FIELD_Vd] = (instr & 0xF000)>>12; + res->fields_mask[FIELD_Vd >> 6] |= 1LL << (FIELD_Vd & 63); + char Vd_width = 4; + res->fields[FIELD_N] = (instr & 0x80)>>7; + res->fields_mask[FIELD_N >> 6] |= 1LL << (FIELD_N & 63); + char N_width = 1; + res->fields[FIELD_Q] = (instr & 0x40)>>6; + res->fields_mask[FIELD_Q >> 6] |= 1LL << (FIELD_Q & 63); + char Q_width = 1; + res->fields[FIELD_M] = (instr & 0x20)>>5; + res->fields_mask[FIELD_M >> 6] |= 1LL << (FIELD_M & 63); + char M_width = 1; + res->fields[FIELD_Vm] = instr & 0xF; + res->fields_mask[FIELD_Vm >> 6] |= 1LL << (FIELD_Vm & 63); + char Vm_width = 4; + + static const instruction_format instr_formats[] = + { + { /* VQSUB<c>.<dt> <Dd>,<Dn>,<Dm> */ + "vqsub", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_VFP_DATA_SIZE, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_n,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_m,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + { /* VQSUB<c>.<dt> <Qd>,<Qn>,<Qm> */ + "vqsub", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_VFP_DATA_SIZE, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"q","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_n,FIELD_UNINIT,"q","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_m,FIELD_UNINIT,"q","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 2; + res->mnem = armv7::ARMV7_VQSUB; + + /* pcode: if (Q == '1' && (Vd<0> == '1' || Vn<0> == '1' || Vm<0> == '1')) then UNDEFINED */ + if((((res->fields[FIELD_Q]) == (0x1)) && ((((((res->fields[FIELD_Vd] & 1)) == (0x1)) || (((res->fields[FIELD_Vn] & 1)) == (0x1))) || (((res->fields[FIELD_Vm] & 1)) == (0x1)))))) { + res->status |= STATUS_UNDEFINED; + } + /* pcode: unsigned = (U == '1') */ + res->fields[FIELD_unsigned] = ((res->fields[FIELD_U]) == (0x1)); + res->fields_mask[FIELD_unsigned >> 6] |= 1LL << (FIELD_unsigned & 63); + /* pcode: esize = 8 << UInt(size) */ + res->fields[FIELD_esize] = (8) << ((res->fields[FIELD_size])); + res->fields_mask[FIELD_esize >> 6] |= 1LL << (FIELD_esize & 63); + /* pcode: elements = 64 DIV esize */ + res->fields[FIELD_elements] = ((res->fields[FIELD_esize]) ? ((64) / (res->fields[FIELD_esize])) : 0); + res->fields_mask[FIELD_elements >> 6] |= 1LL << (FIELD_elements & 63); + /* pcode: d = UInt(D:Vd) */ + res->fields[FIELD_d] = ((res->fields[FIELD_D]<<Vd_width)|(res->fields[FIELD_Vd])); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: n = UInt(N:Vn) */ + res->fields[FIELD_n] = ((res->fields[FIELD_N]<<Vn_width)|(res->fields[FIELD_Vn])); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: m = UInt(M:Vm) */ + res->fields[FIELD_m] = ((res->fields[FIELD_M]<<Vm_width)|(res->fields[FIELD_Vm])); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + /* pcode: regs = if Q == '0' then 1 else 2 */ + if((res->fields[FIELD_Q]) == (0x0)) { + res->fields[FIELD_regs] = 1; + res->fields_mask[FIELD_regs >> 6] |= 1LL << (FIELD_regs & 63); + } + else { + res->fields[FIELD_regs] = 2; + res->fields_mask[FIELD_regs >> 6] |= 1LL << (FIELD_regs & 63); + } + /* pcode: fmt_idx = (Q == '1') */ + res->fields[FIELD_fmt_idx] = ((res->fields[FIELD_Q]) == (0x1)); + res->fields_mask[FIELD_fmt_idx >> 6] |= 1LL << (FIELD_fmt_idx & 63); + /* pcode: dt = UInt(U:size) */ + res->fields[FIELD_dt] = ((res->fields[FIELD_U]<<size_width)|(res->fields[FIELD_size])); + res->fields_mask[FIELD_dt >> 6] |= 1LL << (FIELD_dt & 63); + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: 3720637C +int vraddhn(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + res->group = INSN_GROUP_NEON; + /* Encoding T1 */ + /* pattern="1111,xx11,1,D.1,size.2,Vn.4,Vd.4,0100,N.1,0,M.1,0,Vm.4" width=32 stringency=16 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xF3800F50)==0xF3800400)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ADVSIMD)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_D] = (instr & 0x400000)>>22; + res->fields_mask[FIELD_D >> 6] |= 1LL << (FIELD_D & 63); + char D_width = 1; + res->fields[FIELD_size] = (instr & 0x300000)>>20; + res->fields_mask[FIELD_size >> 6] |= 1LL << (FIELD_size & 63); + char size_width = 2; + res->fields[FIELD_Vn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Vn >> 6] |= 1LL << (FIELD_Vn & 63); + char Vn_width = 4; + res->fields[FIELD_Vd] = (instr & 0xF000)>>12; + res->fields_mask[FIELD_Vd >> 6] |= 1LL << (FIELD_Vd & 63); + char Vd_width = 4; + res->fields[FIELD_N] = (instr & 0x80)>>7; + res->fields_mask[FIELD_N >> 6] |= 1LL << (FIELD_N & 63); + char N_width = 1; + res->fields[FIELD_M] = (instr & 0x20)>>5; + res->fields_mask[FIELD_M >> 6] |= 1LL << (FIELD_M & 63); + char M_width = 1; + res->fields[FIELD_Vm] = instr & 0xF; + res->fields_mask[FIELD_Vm >> 6] |= 1LL << (FIELD_Vm & 63); + char Vm_width = 4; + + static const instruction_format instr_formats[] = + { + { /* VRADDHN<c>.<dt> <Dd>,<Qn>,<Qm> */ + "vraddhn", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_VFP_DATA_SIZE, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_n,FIELD_UNINIT,"q","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_m,FIELD_UNINIT,"q","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_VRADDHN; + + /* pcode: if size == '11' then SEE "Advanced SIMD Data Proc" */ + if((res->fields[FIELD_size]) == (0x3)) { + + return advanced_simd_data_proc(req, res); + } + /* pcode: if Vn<0> == '1' || Vm<0> == '1' then UNDEFINED */ + if((((res->fields[FIELD_Vn] & 1)) == (0x1)) || (((res->fields[FIELD_Vm] & 1)) == (0x1))) { + res->status |= STATUS_UNDEFINED; + } + /* pcode: esize = 8 << UInt(size) */ + res->fields[FIELD_esize] = (8) << ((res->fields[FIELD_size])); + res->fields_mask[FIELD_esize >> 6] |= 1LL << (FIELD_esize & 63); + /* pcode: elements = 64 DIV esize */ + res->fields[FIELD_elements] = ((res->fields[FIELD_esize]) ? ((64) / (res->fields[FIELD_esize])) : 0); + res->fields_mask[FIELD_elements >> 6] |= 1LL << (FIELD_elements & 63); + /* pcode: d = UInt(D:Vd) */ + res->fields[FIELD_d] = ((res->fields[FIELD_D]<<Vd_width)|(res->fields[FIELD_Vd])); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: n = UInt(N:Vn) */ + res->fields[FIELD_n] = ((res->fields[FIELD_N]<<Vn_width)|(res->fields[FIELD_Vn])); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: m = UInt(M:Vm) */ + res->fields[FIELD_m] = ((res->fields[FIELD_M]<<Vm_width)|(res->fields[FIELD_Vm])); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + /* pcode: iword = TRUE */ + res->fields[FIELD_iword] = 1; + res->fields_mask[FIELD_iword >> 6] |= 1LL << (FIELD_iword & 63); + /* pcode: dt = UInt(size+1) */ + res->fields[FIELD_dt] = ((res->fields[FIELD_size]) + (1)); + res->fields_mask[FIELD_dt >> 6] |= 1LL << (FIELD_dt & 63); + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: 81BD0D90 +int vrecpe(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + res->group = INSN_GROUP_NEON; + /* Encoding T2 */ + /* pattern="1111,xx11,1,D.1,11,size.2,11,Vd.4,010,1,0,Q.1,M.1,0,Vm.4" width=32 stringency=20 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xF3B30F90)==0xF3B30500)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ADVSIMD)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_D] = (instr & 0x400000)>>22; + res->fields_mask[FIELD_D >> 6] |= 1LL << (FIELD_D & 63); + char D_width = 1; + res->fields[FIELD_size] = (instr & 0xC0000)>>18; + res->fields_mask[FIELD_size >> 6] |= 1LL << (FIELD_size & 63); + char size_width = 2; + res->fields[FIELD_Vd] = (instr & 0xF000)>>12; + res->fields_mask[FIELD_Vd >> 6] |= 1LL << (FIELD_Vd & 63); + char Vd_width = 4; + res->fields[FIELD_Q] = (instr & 0x40)>>6; + res->fields_mask[FIELD_Q >> 6] |= 1LL << (FIELD_Q & 63); + char Q_width = 1; + res->fields[FIELD_M] = (instr & 0x20)>>5; + res->fields_mask[FIELD_M >> 6] |= 1LL << (FIELD_M & 63); + char M_width = 1; + res->fields[FIELD_Vm] = instr & 0xF; + res->fields_mask[FIELD_Vm >> 6] |= 1LL << (FIELD_Vm & 63); + char Vm_width = 4; + + static const instruction_format instr_formats[] = + { + { /* VRECPE<c>.F32 <Dd>,<Dm> */ + "vrecpe.f32", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_F32, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_m,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + { /* VRECPE<c>.F32 <Qd>,<Qm> */ + "vrecpe.f32", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_F32, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"q","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_m,FIELD_UNINIT,"q","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 2; + res->mnem = armv7::ARMV7_VRECPE; + + /* pcode: if (Q == '1' && (Vd<0> == '1' || Vm<0> == '1')) then UNDEFINED */ + if((((res->fields[FIELD_Q]) == (0x1)) && (((((res->fields[FIELD_Vd] & 1)) == (0x1)) || (((res->fields[FIELD_Vm] & 1)) == (0x1)))))) { + res->status |= STATUS_UNDEFINED; + } + /* pcode: if size != '10' then UNDEFINED */ + if((res->fields[FIELD_size]) != (0x2)) { + res->status |= STATUS_UNDEFINED; + } + /* pcode: esize = 32 */ + res->fields[FIELD_esize] = 32; + res->fields_mask[FIELD_esize >> 6] |= 1LL << (FIELD_esize & 63); + /* pcode: elements = 2 */ + res->fields[FIELD_elements] = 2; + res->fields_mask[FIELD_elements >> 6] |= 1LL << (FIELD_elements & 63); + /* pcode: d = UInt(D:Vd) */ + res->fields[FIELD_d] = ((res->fields[FIELD_D]<<Vd_width)|(res->fields[FIELD_Vd])); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: m = UInt(M:Vm) */ + res->fields[FIELD_m] = ((res->fields[FIELD_M]<<Vm_width)|(res->fields[FIELD_Vm])); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + /* pcode: regs = if Q == '0' then 1 else 2 */ + if((res->fields[FIELD_Q]) == (0x0)) { + res->fields[FIELD_regs] = 1; + res->fields_mask[FIELD_regs >> 6] |= 1LL << (FIELD_regs & 63); + } + else { + res->fields[FIELD_regs] = 2; + res->fields_mask[FIELD_regs >> 6] |= 1LL << (FIELD_regs & 63); + } + /* pcode: fmt_idx = (Q == '1') */ + res->fields[FIELD_fmt_idx] = ((res->fields[FIELD_Q]) == (0x1)); + res->fields_mask[FIELD_fmt_idx >> 6] |= 1LL << (FIELD_fmt_idx & 63); + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* Encoding T1 */ + /* pattern="1111,xx11,1,D.1,11,size.2,11,Vd.4,010,0,0,Q.1,M.1,0,Vm.4" width=32 stringency=20 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xF3B30F90)==0xF3B30400)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ADVSIMD)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_D] = (instr & 0x400000)>>22; + res->fields_mask[FIELD_D >> 6] |= 1LL << (FIELD_D & 63); + char D_width = 1; + res->fields[FIELD_size] = (instr & 0xC0000)>>18; + res->fields_mask[FIELD_size >> 6] |= 1LL << (FIELD_size & 63); + char size_width = 2; + res->fields[FIELD_Vd] = (instr & 0xF000)>>12; + res->fields_mask[FIELD_Vd >> 6] |= 1LL << (FIELD_Vd & 63); + char Vd_width = 4; + res->fields[FIELD_Q] = (instr & 0x40)>>6; + res->fields_mask[FIELD_Q >> 6] |= 1LL << (FIELD_Q & 63); + char Q_width = 1; + res->fields[FIELD_M] = (instr & 0x20)>>5; + res->fields_mask[FIELD_M >> 6] |= 1LL << (FIELD_M & 63); + char M_width = 1; + res->fields[FIELD_Vm] = instr & 0xF; + res->fields_mask[FIELD_Vm >> 6] |= 1LL << (FIELD_Vm & 63); + char Vm_width = 4; + + static const instruction_format instr_formats[] = + { + { /* VRECPE<c>.U32 <Dd>,<Dm> */ + "vrecpe.u32", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_m,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + { /* VRECPE<c>.U32 <Qd>,<Qm> */ + "vrecpe.u32", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"q","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_m,FIELD_UNINIT,"q","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 2; + res->mnem = armv7::ARMV7_VRECPE; + + /* pcode: if (Q == '1' && (Vd<0> == '1' || Vm<0> == '1')) then UNDEFINED */ + if((((res->fields[FIELD_Q]) == (0x1)) && (((((res->fields[FIELD_Vd] & 1)) == (0x1)) || (((res->fields[FIELD_Vm] & 1)) == (0x1)))))) { + res->status |= STATUS_UNDEFINED; + } + /* pcode: if size != '10' then UNDEFINED */ + if((res->fields[FIELD_size]) != (0x2)) { + res->status |= STATUS_UNDEFINED; + } + /* pcode: esize = 32 */ + res->fields[FIELD_esize] = 32; + res->fields_mask[FIELD_esize >> 6] |= 1LL << (FIELD_esize & 63); + /* pcode: elements = 2 */ + res->fields[FIELD_elements] = 2; + res->fields_mask[FIELD_elements >> 6] |= 1LL << (FIELD_elements & 63); + /* pcode: d = UInt(D:Vd) */ + res->fields[FIELD_d] = ((res->fields[FIELD_D]<<Vd_width)|(res->fields[FIELD_Vd])); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: m = UInt(M:Vm) */ + res->fields[FIELD_m] = ((res->fields[FIELD_M]<<Vm_width)|(res->fields[FIELD_Vm])); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + /* pcode: regs = if Q == '0' then 1 else 2 */ + if((res->fields[FIELD_Q]) == (0x0)) { + res->fields[FIELD_regs] = 1; + res->fields_mask[FIELD_regs >> 6] |= 1LL << (FIELD_regs & 63); + } + else { + res->fields[FIELD_regs] = 2; + res->fields_mask[FIELD_regs >> 6] |= 1LL << (FIELD_regs & 63); + } + /* pcode: fmt_idx = (Q == '1') */ + res->fields[FIELD_fmt_idx] = ((res->fields[FIELD_Q]) == (0x1)); + res->fields_mask[FIELD_fmt_idx >> 6] |= 1LL << (FIELD_fmt_idx & 63); + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: 9E2B1CAC +int vrecps(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + res->group = INSN_GROUP_NEON; + /* Encoding T1 */ + /* pattern="111x,xx1x,0,D.1,0,sz.1,Vn.4,Vd.4,1111,N.1,Q.1,M.1,1,Vm.4" width=32 stringency=16 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xE2A00F10)==0xE2000F10)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ADVSIMD)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_D] = (instr & 0x400000)>>22; + res->fields_mask[FIELD_D >> 6] |= 1LL << (FIELD_D & 63); + char D_width = 1; + res->fields[FIELD_sz] = (instr & 0x100000)>>20; + res->fields_mask[FIELD_sz >> 6] |= 1LL << (FIELD_sz & 63); + char sz_width = 1; + res->fields[FIELD_Vn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Vn >> 6] |= 1LL << (FIELD_Vn & 63); + char Vn_width = 4; + res->fields[FIELD_Vd] = (instr & 0xF000)>>12; + res->fields_mask[FIELD_Vd >> 6] |= 1LL << (FIELD_Vd & 63); + char Vd_width = 4; + res->fields[FIELD_N] = (instr & 0x80)>>7; + res->fields_mask[FIELD_N >> 6] |= 1LL << (FIELD_N & 63); + char N_width = 1; + res->fields[FIELD_Q] = (instr & 0x40)>>6; + res->fields_mask[FIELD_Q >> 6] |= 1LL << (FIELD_Q & 63); + char Q_width = 1; + res->fields[FIELD_M] = (instr & 0x20)>>5; + res->fields_mask[FIELD_M >> 6] |= 1LL << (FIELD_M & 63); + char M_width = 1; + res->fields[FIELD_Vm] = instr & 0xF; + res->fields_mask[FIELD_Vm >> 6] |= 1LL << (FIELD_Vm & 63); + char Vm_width = 4; + + static const instruction_format instr_formats[] = + { + { /* VRECPS<c>.F32 <Dd>,<Dn>,<Dm> */ + "vrecps.f32", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_F32, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_n,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_m,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + { /* VRECPS<c>.F32 <Qd>,<Qn>,<Qm> */ + "vrecps.f32", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_F32, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"q","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_n,FIELD_UNINIT,"q","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_m,FIELD_UNINIT,"q","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 2; + res->mnem = armv7::ARMV7_VRECPS; + + /* pcode: if (Q == '1' && (Vd<0> == '1' || Vn<0> == '1' || Vm<0> == '1')) then UNDEFINED */ + if((((res->fields[FIELD_Q]) == (0x1)) && ((((((res->fields[FIELD_Vd] & 1)) == (0x1)) || (((res->fields[FIELD_Vn] & 1)) == (0x1))) || (((res->fields[FIELD_Vm] & 1)) == (0x1)))))) { + res->status |= STATUS_UNDEFINED; + } + /* pcode: if sz == '1' then UNDEFINED */ + if((res->fields[FIELD_sz]) == (0x1)) { + res->status |= STATUS_UNDEFINED; + } + /* pcode: esize = 32 */ + res->fields[FIELD_esize] = 32; + res->fields_mask[FIELD_esize >> 6] |= 1LL << (FIELD_esize & 63); + /* pcode: elements = 2 */ + res->fields[FIELD_elements] = 2; + res->fields_mask[FIELD_elements >> 6] |= 1LL << (FIELD_elements & 63); + /* pcode: d = UInt(D:Vd) */ + res->fields[FIELD_d] = ((res->fields[FIELD_D]<<Vd_width)|(res->fields[FIELD_Vd])); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: n = UInt(N:Vn) */ + res->fields[FIELD_n] = ((res->fields[FIELD_N]<<Vn_width)|(res->fields[FIELD_Vn])); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: m = UInt(M:Vm) */ + res->fields[FIELD_m] = ((res->fields[FIELD_M]<<Vm_width)|(res->fields[FIELD_Vm])); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + /* pcode: regs = if Q == '0' then 1 else 2 */ + if((res->fields[FIELD_Q]) == (0x0)) { + res->fields[FIELD_regs] = 1; + res->fields_mask[FIELD_regs >> 6] |= 1LL << (FIELD_regs & 63); + } + else { + res->fields[FIELD_regs] = 2; + res->fields_mask[FIELD_regs >> 6] |= 1LL << (FIELD_regs & 63); + } + /* pcode: fmt_idx = (Q == '1') */ + res->fields[FIELD_fmt_idx] = ((res->fields[FIELD_Q]) == (0x1)); + res->fields_mask[FIELD_fmt_idx >> 6] |= 1LL << (FIELD_fmt_idx & 63); + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: FAACE0DF +int vrev16(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + res->group = INSN_GROUP_NEON; + /* Encoding T1 */ + /* pattern="1111,1111,1,D.1,11,size.2,00,Vd.4,000,op.2,Q.1,M.1,0,Vm.4" width=32 stringency=20 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFFB30E10)==0xFFB00000)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ADVSIMD)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_D] = (instr & 0x400000)>>22; + res->fields_mask[FIELD_D >> 6] |= 1LL << (FIELD_D & 63); + char D_width = 1; + res->fields[FIELD_size] = (instr & 0xC0000)>>18; + res->fields_mask[FIELD_size >> 6] |= 1LL << (FIELD_size & 63); + char size_width = 2; + res->fields[FIELD_Vd] = (instr & 0xF000)>>12; + res->fields_mask[FIELD_Vd >> 6] |= 1LL << (FIELD_Vd & 63); + char Vd_width = 4; + res->fields[FIELD_op] = (instr & 0x180)>>7; + res->fields_mask[FIELD_op >> 6] |= 1LL << (FIELD_op & 63); + char op_width = 2; + res->fields[FIELD_Q] = (instr & 0x40)>>6; + res->fields_mask[FIELD_Q >> 6] |= 1LL << (FIELD_Q & 63); + char Q_width = 1; + res->fields[FIELD_M] = (instr & 0x20)>>5; + res->fields_mask[FIELD_M >> 6] |= 1LL << (FIELD_M & 63); + char M_width = 1; + res->fields[FIELD_Vm] = instr & 0xF; + res->fields_mask[FIELD_Vm >> 6] |= 1LL << (FIELD_Vm & 63); + char Vm_width = 4; + + static const instruction_format instr_formats[] = + { + { /* VREV16<c>.<size> <Dd>,<Dm> */ + "vrev16", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_NEON_SIZE, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_m,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + { /* VREV16<c>.<size> <Qd>,<Qm> */ + "vrev16", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_NEON_SIZE, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"q","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_m,FIELD_UNINIT,"q","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 2; + res->mnem = armv7::ARMV7_VREV16; + + /* pcode: if (Q == '1' && (Vd<0> == '1' || Vm<0> == '1')) then UNDEFINED */ + if((((res->fields[FIELD_Q]) == (0x1)) && (((((res->fields[FIELD_Vd] & 1)) == (0x1)) || (((res->fields[FIELD_Vm] & 1)) == (0x1)))))) { + res->status |= STATUS_UNDEFINED; + } + /* pcode: esize = 8 << UInt(size) */ + res->fields[FIELD_esize] = (8) << ((res->fields[FIELD_size])); + res->fields_mask[FIELD_esize >> 6] |= 1LL << (FIELD_esize & 63); + /* pcode: elements = 64 DIV esize */ + res->fields[FIELD_elements] = ((res->fields[FIELD_esize]) ? ((64) / (res->fields[FIELD_esize])) : 0); + res->fields_mask[FIELD_elements >> 6] |= 1LL << (FIELD_elements & 63); + /* pcode: d = UInt(D:Vd) */ + res->fields[FIELD_d] = ((res->fields[FIELD_D]<<Vd_width)|(res->fields[FIELD_Vd])); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: m = UInt(M:Vm) */ + res->fields[FIELD_m] = ((res->fields[FIELD_M]<<Vm_width)|(res->fields[FIELD_Vm])); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + /* pcode: regs = if Q == '0' then 1 else 2 */ + if((res->fields[FIELD_Q]) == (0x0)) { + res->fields[FIELD_regs] = 1; + res->fields_mask[FIELD_regs >> 6] |= 1LL << (FIELD_regs & 63); + } + else { + res->fields[FIELD_regs] = 2; + res->fields_mask[FIELD_regs >> 6] |= 1LL << (FIELD_regs & 63); + } + /* pcode: fmt_idx = (Q == '1') */ + res->fields[FIELD_fmt_idx] = ((res->fields[FIELD_Q]) == (0x1)); + res->fields_mask[FIELD_fmt_idx >> 6] |= 1LL << (FIELD_fmt_idx & 63); + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: 7D044D72 +int vrev32(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + res->group = INSN_GROUP_NEON; + /* Encoding T1 */ + /* pattern="1111,1111,1,D.1,11,size.2,00,Vd.4,000,op.2,Q.1,M.1,0,Vm.4" width=32 stringency=20 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFFB30E10)==0xFFB00000)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ADVSIMD)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_D] = (instr & 0x400000)>>22; + res->fields_mask[FIELD_D >> 6] |= 1LL << (FIELD_D & 63); + char D_width = 1; + res->fields[FIELD_size] = (instr & 0xC0000)>>18; + res->fields_mask[FIELD_size >> 6] |= 1LL << (FIELD_size & 63); + char size_width = 2; + res->fields[FIELD_Vd] = (instr & 0xF000)>>12; + res->fields_mask[FIELD_Vd >> 6] |= 1LL << (FIELD_Vd & 63); + char Vd_width = 4; + res->fields[FIELD_op] = (instr & 0x180)>>7; + res->fields_mask[FIELD_op >> 6] |= 1LL << (FIELD_op & 63); + char op_width = 2; + res->fields[FIELD_Q] = (instr & 0x40)>>6; + res->fields_mask[FIELD_Q >> 6] |= 1LL << (FIELD_Q & 63); + char Q_width = 1; + res->fields[FIELD_M] = (instr & 0x20)>>5; + res->fields_mask[FIELD_M >> 6] |= 1LL << (FIELD_M & 63); + char M_width = 1; + res->fields[FIELD_Vm] = instr & 0xF; + res->fields_mask[FIELD_Vm >> 6] |= 1LL << (FIELD_Vm & 63); + char Vm_width = 4; + + static const instruction_format instr_formats[] = + { + { /* VREV32<c>.<size> <Dd>,<Dm> */ + "vrev32", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_NEON_SIZE, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_m,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + { /* VREV32<c>.<size> <Qd>,<Qm> */ + "vrev32", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_NEON_SIZE, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"q","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_m,FIELD_UNINIT,"q","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 2; + res->mnem = armv7::ARMV7_VREV32; + + /* pcode: if (Q == '1' && (Vd<0> == '1' || Vm<0> == '1')) then UNDEFINED */ + if((((res->fields[FIELD_Q]) == (0x1)) && (((((res->fields[FIELD_Vd] & 1)) == (0x1)) || (((res->fields[FIELD_Vm] & 1)) == (0x1)))))) { + res->status |= STATUS_UNDEFINED; + } + /* pcode: esize = 8 << UInt(size) */ + res->fields[FIELD_esize] = (8) << ((res->fields[FIELD_size])); + res->fields_mask[FIELD_esize >> 6] |= 1LL << (FIELD_esize & 63); + /* pcode: elements = 64 DIV esize */ + res->fields[FIELD_elements] = ((res->fields[FIELD_esize]) ? ((64) / (res->fields[FIELD_esize])) : 0); + res->fields_mask[FIELD_elements >> 6] |= 1LL << (FIELD_elements & 63); + /* pcode: d = UInt(D:Vd) */ + res->fields[FIELD_d] = ((res->fields[FIELD_D]<<Vd_width)|(res->fields[FIELD_Vd])); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: m = UInt(M:Vm) */ + res->fields[FIELD_m] = ((res->fields[FIELD_M]<<Vm_width)|(res->fields[FIELD_Vm])); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + /* pcode: regs = if Q == '0' then 1 else 2 */ + if((res->fields[FIELD_Q]) == (0x0)) { + res->fields[FIELD_regs] = 1; + res->fields_mask[FIELD_regs >> 6] |= 1LL << (FIELD_regs & 63); + } + else { + res->fields[FIELD_regs] = 2; + res->fields_mask[FIELD_regs >> 6] |= 1LL << (FIELD_regs & 63); + } + /* pcode: fmt_idx = (Q == '1') */ + res->fields[FIELD_fmt_idx] = ((res->fields[FIELD_Q]) == (0x1)); + res->fields_mask[FIELD_fmt_idx >> 6] |= 1LL << (FIELD_fmt_idx & 63); + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: 692F9355 +int vrev64(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + res->group = INSN_GROUP_NEON; + /* Encoding T1 */ + /* pattern="1111,1111,1,D.1,11,size.2,00,Vd.4,000,op.2,Q.1,M.1,0,Vm.4" width=32 stringency=20 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFFB30E10)==0xFFB00000)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ADVSIMD)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_D] = (instr & 0x400000)>>22; + res->fields_mask[FIELD_D >> 6] |= 1LL << (FIELD_D & 63); + char D_width = 1; + res->fields[FIELD_size] = (instr & 0xC0000)>>18; + res->fields_mask[FIELD_size >> 6] |= 1LL << (FIELD_size & 63); + char size_width = 2; + res->fields[FIELD_Vd] = (instr & 0xF000)>>12; + res->fields_mask[FIELD_Vd >> 6] |= 1LL << (FIELD_Vd & 63); + char Vd_width = 4; + res->fields[FIELD_op] = (instr & 0x180)>>7; + res->fields_mask[FIELD_op >> 6] |= 1LL << (FIELD_op & 63); + char op_width = 2; + res->fields[FIELD_Q] = (instr & 0x40)>>6; + res->fields_mask[FIELD_Q >> 6] |= 1LL << (FIELD_Q & 63); + char Q_width = 1; + res->fields[FIELD_M] = (instr & 0x20)>>5; + res->fields_mask[FIELD_M >> 6] |= 1LL << (FIELD_M & 63); + char M_width = 1; + res->fields[FIELD_Vm] = instr & 0xF; + res->fields_mask[FIELD_Vm >> 6] |= 1LL << (FIELD_Vm & 63); + char Vm_width = 4; + + static const instruction_format instr_formats[] = + { + { /* VREV64<c>.<size> <Dd>,<Dm> */ + "vrev64", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_NEON_SIZE, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_m,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + { /* VREV64<c>.<size> <Qd>,<Qm> */ + "vrev64", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_NEON_SIZE, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"q","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_m,FIELD_UNINIT,"q","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 2; + res->mnem = armv7::ARMV7_VREV64; + + /* pcode: if (Q == '1' && (Vd<0> == '1' || Vm<0> == '1')) then UNDEFINED */ + if((((res->fields[FIELD_Q]) == (0x1)) && (((((res->fields[FIELD_Vd] & 1)) == (0x1)) || (((res->fields[FIELD_Vm] & 1)) == (0x1)))))) { + res->status |= STATUS_UNDEFINED; + } + /* pcode: esize = 8 << UInt(size) */ + res->fields[FIELD_esize] = (8) << ((res->fields[FIELD_size])); + res->fields_mask[FIELD_esize >> 6] |= 1LL << (FIELD_esize & 63); + /* pcode: elements = 64 DIV esize */ + res->fields[FIELD_elements] = ((res->fields[FIELD_esize]) ? ((64) / (res->fields[FIELD_esize])) : 0); + res->fields_mask[FIELD_elements >> 6] |= 1LL << (FIELD_elements & 63); + /* pcode: d = UInt(D:Vd) */ + res->fields[FIELD_d] = ((res->fields[FIELD_D]<<Vd_width)|(res->fields[FIELD_Vd])); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: m = UInt(M:Vm) */ + res->fields[FIELD_m] = ((res->fields[FIELD_M]<<Vm_width)|(res->fields[FIELD_Vm])); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + /* pcode: regs = if Q == '0' then 1 else 2 */ + if((res->fields[FIELD_Q]) == (0x0)) { + res->fields[FIELD_regs] = 1; + res->fields_mask[FIELD_regs >> 6] |= 1LL << (FIELD_regs & 63); + } + else { + res->fields[FIELD_regs] = 2; + res->fields_mask[FIELD_regs >> 6] |= 1LL << (FIELD_regs & 63); + } + /* pcode: fmt_idx = (Q == '1') */ + res->fields[FIELD_fmt_idx] = ((res->fields[FIELD_Q]) == (0x1)); + res->fields_mask[FIELD_fmt_idx >> 6] |= 1LL << (FIELD_fmt_idx & 63); + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: 74DFA3B4 +int vrhadd(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + res->group = INSN_GROUP_NEON; + /* Encoding T1 */ + /* pattern="111,U.1,1111,0,D.1,size.2,Vn.4,Vd.4,0001,N.1,Q.1,M.1,0,Vm.4" width=32 stringency=18 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xEF800F10)==0xEF000100)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ADVSIMD)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_U] = (instr & 0x10000000)>>28; + res->fields_mask[FIELD_U >> 6] |= 1LL << (FIELD_U & 63); + char U_width = 1; + res->fields[FIELD_D] = (instr & 0x400000)>>22; + res->fields_mask[FIELD_D >> 6] |= 1LL << (FIELD_D & 63); + char D_width = 1; + res->fields[FIELD_size] = (instr & 0x300000)>>20; + res->fields_mask[FIELD_size >> 6] |= 1LL << (FIELD_size & 63); + char size_width = 2; + res->fields[FIELD_Vn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Vn >> 6] |= 1LL << (FIELD_Vn & 63); + char Vn_width = 4; + res->fields[FIELD_Vd] = (instr & 0xF000)>>12; + res->fields_mask[FIELD_Vd >> 6] |= 1LL << (FIELD_Vd & 63); + char Vd_width = 4; + res->fields[FIELD_N] = (instr & 0x80)>>7; + res->fields_mask[FIELD_N >> 6] |= 1LL << (FIELD_N & 63); + char N_width = 1; + res->fields[FIELD_Q] = (instr & 0x40)>>6; + res->fields_mask[FIELD_Q >> 6] |= 1LL << (FIELD_Q & 63); + char Q_width = 1; + res->fields[FIELD_M] = (instr & 0x20)>>5; + res->fields_mask[FIELD_M >> 6] |= 1LL << (FIELD_M & 63); + char M_width = 1; + res->fields[FIELD_Vm] = instr & 0xF; + res->fields_mask[FIELD_Vm >> 6] |= 1LL << (FIELD_Vm & 63); + char Vm_width = 4; + + static const instruction_format instr_formats[] = + { + { /* VRHADD<c>.<dt> <Dd>,<Dn>,<Dm> */ + "vrhadd", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_VFP_DATA_SIZE, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_n,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_m,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + { /* VRHADD<c>.<dt> <Qd>,<Qn>,<Qm> */ + "vrhadd", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_VFP_DATA_SIZE, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"q","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_n,FIELD_UNINIT,"q","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_m,FIELD_UNINIT,"q","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 2; + res->mnem = armv7::ARMV7_VRHADD; + + /* pcode: if Q == '1' && (Vd<0> == '1' || Vn<0> == '1' || Vm<0> == '1') then UNDEFINED */ + if(((res->fields[FIELD_Q]) == (0x1)) && ((((((res->fields[FIELD_Vd] & 1)) == (0x1)) || (((res->fields[FIELD_Vn] & 1)) == (0x1))) || (((res->fields[FIELD_Vm] & 1)) == (0x1))))) { + res->status |= STATUS_UNDEFINED; + } + /* pcode: if size == '11' then UNDEFINED */ + if((res->fields[FIELD_size]) == (0x3)) { + res->status |= STATUS_UNDEFINED; + } + /* pcode: unsigned = (U == '1') */ + res->fields[FIELD_unsigned] = ((res->fields[FIELD_U]) == (0x1)); + res->fields_mask[FIELD_unsigned >> 6] |= 1LL << (FIELD_unsigned & 63); + /* pcode: esize = 8 << UInt(size) */ + res->fields[FIELD_esize] = (8) << ((res->fields[FIELD_size])); + res->fields_mask[FIELD_esize >> 6] |= 1LL << (FIELD_esize & 63); + /* pcode: elements = 64 DIV esize */ + res->fields[FIELD_elements] = ((res->fields[FIELD_esize]) ? ((64) / (res->fields[FIELD_esize])) : 0); + res->fields_mask[FIELD_elements >> 6] |= 1LL << (FIELD_elements & 63); + /* pcode: d = UInt(D:Vd) */ + res->fields[FIELD_d] = ((res->fields[FIELD_D]<<Vd_width)|(res->fields[FIELD_Vd])); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: n = UInt(N:Vn) */ + res->fields[FIELD_n] = ((res->fields[FIELD_N]<<Vn_width)|(res->fields[FIELD_Vn])); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: m = UInt(M:Vm) */ + res->fields[FIELD_m] = ((res->fields[FIELD_M]<<Vm_width)|(res->fields[FIELD_Vm])); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + /* pcode: fmt_idx = (Q == '1') */ + res->fields[FIELD_fmt_idx] = ((res->fields[FIELD_Q]) == (0x1)); + res->fields_mask[FIELD_fmt_idx >> 6] |= 1LL << (FIELD_fmt_idx & 63); + /* pcode: regs = if Q == '0' then 1 else 2 */ + if((res->fields[FIELD_Q]) == (0x0)) { + res->fields[FIELD_regs] = 1; + res->fields_mask[FIELD_regs >> 6] |= 1LL << (FIELD_regs & 63); + } + else { + res->fields[FIELD_regs] = 2; + res->fields_mask[FIELD_regs >> 6] |= 1LL << (FIELD_regs & 63); + } + /* pcode: dt = UInt(U:size) */ + res->fields[FIELD_dt] = ((res->fields[FIELD_U]<<size_width)|(res->fields[FIELD_size])); + res->fields_mask[FIELD_dt >> 6] |= 1LL << (FIELD_dt & 63); + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: FBDAA31C +int vrinta(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + res->group = INSN_GROUP_NEON; + /* Encoding T1 */ + /* pattern="1111,11101,D.1,1110,RM.2,Vd.4,101,sz.1,0,1,M.1,0,Vm.4" width=32 stringency=22 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFFBC0ED0)==0xFEB80A40)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ADVSIMD)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_D] = (instr & 0x400000)>>22; + res->fields_mask[FIELD_D >> 6] |= 1LL << (FIELD_D & 63); + char D_width = 1; + res->fields[FIELD_RM] = (instr & 0x30000)>>16; + res->fields_mask[FIELD_RM >> 6] |= 1LL << (FIELD_RM & 63); + char RM_width = 2; + res->fields[FIELD_Vd] = (instr & 0xF000)>>12; + res->fields_mask[FIELD_Vd >> 6] |= 1LL << (FIELD_Vd & 63); + char Vd_width = 4; + res->fields[FIELD_sz] = (instr & 0x100)>>8; + res->fields_mask[FIELD_sz >> 6] |= 1LL << (FIELD_sz & 63); + char sz_width = 1; + res->fields[FIELD_M] = (instr & 0x20)>>5; + res->fields_mask[FIELD_M >> 6] |= 1LL << (FIELD_M & 63); + char M_width = 1; + res->fields[FIELD_Vm] = instr & 0xF; + res->fields_mask[FIELD_Vm >> 6] |= 1LL << (FIELD_Vm & 63); + char Vm_width = 4; + + static const instruction_format instr_formats[] = + { + { /* VRINTA<c>.F32 <Sd>,<Sm> */ + "vrinta.f32", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_F32, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"s","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_m,FIELD_UNINIT,"s","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + { /* VRINTA<c>.F64 <Dd>,<Dm> */ + "vrinta.f64", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_F64, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_m,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + { /* VRINTN<c>.F32 <Sd>,<Sm> */ + "vrintn.f32", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_F32, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"s","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_m,FIELD_UNINIT,"s","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + { /* VRINTN<c>.F64 <Dd>,<Dm> */ + "vrintn.f64", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_F64, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_m,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + { /* VRINTP<c>.F32 <Sd>,<Sm> */ + "vrintp.f32", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_F32, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"s","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_m,FIELD_UNINIT,"s","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + { /* VRINTP<c>.F64 <Dd>,<Dm> */ + "vrintp.f64", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_F64, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_m,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + { /* VRINTM<c>.F32 <Sd>,<Sm> */ + "vrintm.f32", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_F32, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"s","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_m,FIELD_UNINIT,"s","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + { /* VRINTM<c>.F64 <Dd>,<Dm> */ + "vrintm.f64", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_F64, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_m,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 8; + res->mnem = armv7::ARMV7_VRINTA; + + /* pcode: dp_operation = (sz == '1') */ + res->fields[FIELD_dp_operation] = ((res->fields[FIELD_sz]) == (0x1)); + res->fields_mask[FIELD_dp_operation >> 6] |= 1LL << (FIELD_dp_operation & 63); + /* pcode: d = if dp_operation then UInt(D:Vd) else UInt(Vd:D) */ + if(res->fields[FIELD_dp_operation]) { + res->fields[FIELD_d] = ((res->fields[FIELD_D]<<Vd_width)|(res->fields[FIELD_Vd])); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + } + else { + res->fields[FIELD_d] = ((res->fields[FIELD_Vd]<<D_width)|(res->fields[FIELD_D])); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + } + /* pcode: m = if dp_operation then UInt(M:Vm) else UInt(Vm:M) */ + if(res->fields[FIELD_dp_operation]) { + res->fields[FIELD_m] = ((res->fields[FIELD_M]<<Vm_width)|(res->fields[FIELD_Vm])); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + } + else { + res->fields[FIELD_m] = ((res->fields[FIELD_Vm]<<M_width)|(res->fields[FIELD_M])); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + } + /* pcode: fmt_idx = (RM * 2) + dp_operation */ + res->fields[FIELD_fmt_idx] = (((res->fields[FIELD_RM]) * (2))) + (res->fields[FIELD_dp_operation]); + res->fields_mask[FIELD_fmt_idx >> 6] |= 1LL << (FIELD_fmt_idx & 63); + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: 8ACE2B02 +int vrintx(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + res->group = INSN_GROUP_NEON; + /* Encoding T1 */ + /* pattern="1110,11101,D.1,11011,1,Vd.4,101,sz.1,0,1,M.1,0,Vm.4" width=32 stringency=24 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFFBF0ED0)==0xEEB70A40)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ADVSIMD)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_D] = (instr & 0x400000)>>22; + res->fields_mask[FIELD_D >> 6] |= 1LL << (FIELD_D & 63); + char D_width = 1; + res->fields[FIELD_Vd] = (instr & 0xF000)>>12; + res->fields_mask[FIELD_Vd >> 6] |= 1LL << (FIELD_Vd & 63); + char Vd_width = 4; + res->fields[FIELD_sz] = (instr & 0x100)>>8; + res->fields_mask[FIELD_sz >> 6] |= 1LL << (FIELD_sz & 63); + char sz_width = 1; + res->fields[FIELD_M] = (instr & 0x20)>>5; + res->fields_mask[FIELD_M >> 6] |= 1LL << (FIELD_M & 63); + char M_width = 1; + res->fields[FIELD_Vm] = instr & 0xF; + res->fields_mask[FIELD_Vm >> 6] |= 1LL << (FIELD_Vm & 63); + char Vm_width = 4; + + static const instruction_format instr_formats[] = + { + { /* VRINTX<c>.F32 <Sd>,<Sm> */ + "vrintx.f32", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_F32, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"s","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_m,FIELD_UNINIT,"s","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + { /* VRINTX<c>.F64 <Dd>,<Dm> */ + "vrintx.f64", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_F64, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_m,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 2; + res->mnem = armv7::ARMV7_VRINTX; + + /* pcode: dp_operation = (sz == '1') */ + res->fields[FIELD_dp_operation] = ((res->fields[FIELD_sz]) == (0x1)); + res->fields_mask[FIELD_dp_operation >> 6] |= 1LL << (FIELD_dp_operation & 63); + /* pcode: d = if dp_operation then UInt(D:Vd) else UInt(Vd:D) */ + if(res->fields[FIELD_dp_operation]) { + res->fields[FIELD_d] = ((res->fields[FIELD_D]<<Vd_width)|(res->fields[FIELD_Vd])); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + } + else { + res->fields[FIELD_d] = ((res->fields[FIELD_Vd]<<D_width)|(res->fields[FIELD_D])); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + } + /* pcode: m = if dp_operation then UInt(M:Vm) else UInt(Vm:M) */ + if(res->fields[FIELD_dp_operation]) { + res->fields[FIELD_m] = ((res->fields[FIELD_M]<<Vm_width)|(res->fields[FIELD_Vm])); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + } + else { + res->fields[FIELD_m] = ((res->fields[FIELD_Vm]<<M_width)|(res->fields[FIELD_M])); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + } + /* pcode: fmt_idx = dp_operation */ + res->fields[FIELD_fmt_idx] = res->fields[FIELD_dp_operation]; + res->fields_mask[FIELD_fmt_idx >> 6] |= 1LL << (FIELD_fmt_idx & 63); + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: 95E3FBB2 +int vrintz(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + res->group = INSN_GROUP_NEON; + /* Encoding T1 */ + /* pattern="1110,11101,D.1,11011,0,Vd.4,101,sz.1,op.1,1,M.1,0,Vm.4" width=32 stringency=24 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFFBF0E50)==0xEEB60A40)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ADVSIMD)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_D] = (instr & 0x400000)>>22; + res->fields_mask[FIELD_D >> 6] |= 1LL << (FIELD_D & 63); + char D_width = 1; + res->fields[FIELD_Vd] = (instr & 0xF000)>>12; + res->fields_mask[FIELD_Vd >> 6] |= 1LL << (FIELD_Vd & 63); + char Vd_width = 4; + res->fields[FIELD_sz] = (instr & 0x100)>>8; + res->fields_mask[FIELD_sz >> 6] |= 1LL << (FIELD_sz & 63); + char sz_width = 1; + res->fields[FIELD_op] = (instr & 0x80)>>7; + res->fields_mask[FIELD_op >> 6] |= 1LL << (FIELD_op & 63); + char op_width = 1; + res->fields[FIELD_M] = (instr & 0x20)>>5; + res->fields_mask[FIELD_M >> 6] |= 1LL << (FIELD_M & 63); + char M_width = 1; + res->fields[FIELD_Vm] = instr & 0xF; + res->fields_mask[FIELD_Vm >> 6] |= 1LL << (FIELD_Vm & 63); + char Vm_width = 4; + + static const instruction_format instr_formats[] = + { + { /* VRINTR<c>.F32 <Sd>,<Sm> */ + "vrintr.f32", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_F32, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"s","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_m,FIELD_UNINIT,"s","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + { /* VRINTR<c>.F64 <Dd>,<Dm> */ + "vrintr.f64", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_F64, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_m,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + { /* VRINTZ<c>.F32 <Sd>,<Sm> */ + "vrintz.f32", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_F32, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"s","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_m,FIELD_UNINIT,"s","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + { /* VRINTZ<c>.F64 <Dd>,<Dm> */ + "vrintz.f64", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_F64, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_m,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 4; + res->mnem = armv7::ARMV7_VRINTR; + + /* pcode: dp_operation = (sz == '1') */ + res->fields[FIELD_dp_operation] = ((res->fields[FIELD_sz]) == (0x1)); + res->fields_mask[FIELD_dp_operation >> 6] |= 1LL << (FIELD_dp_operation & 63); + /* pcode: d = if dp_operation then UInt(D:Vd) else UInt(Vd:D) */ + if(res->fields[FIELD_dp_operation]) { + res->fields[FIELD_d] = ((res->fields[FIELD_D]<<Vd_width)|(res->fields[FIELD_Vd])); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + } + else { + res->fields[FIELD_d] = ((res->fields[FIELD_Vd]<<D_width)|(res->fields[FIELD_D])); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + } + /* pcode: m = if dp_operation then UInt(M:Vm) else UInt(Vm:M) */ + if(res->fields[FIELD_dp_operation]) { + res->fields[FIELD_m] = ((res->fields[FIELD_M]<<Vm_width)|(res->fields[FIELD_Vm])); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + } + else { + res->fields[FIELD_m] = ((res->fields[FIELD_Vm]<<M_width)|(res->fields[FIELD_M])); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + } + /* pcode: fmt_idx = (op * 2) + dp_operation */ + res->fields[FIELD_fmt_idx] = (((res->fields[FIELD_op]) * (2))) + (res->fields[FIELD_dp_operation]); + res->fields_mask[FIELD_fmt_idx >> 6] |= 1LL << (FIELD_fmt_idx & 63); + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: C0F5C9FC +int vrshl(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + res->group = INSN_GROUP_NEON; + /* Encoding T1 */ + /* pattern="111,U.1,1111,0,D.1,size.2,Vn.4,Vd.4,0101,N.1,Q.1,M.1,0,Vm.4" width=32 stringency=18 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xEF800F10)==0xEF000500)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ADVSIMD)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_U] = (instr & 0x10000000)>>28; + res->fields_mask[FIELD_U >> 6] |= 1LL << (FIELD_U & 63); + char U_width = 1; + res->fields[FIELD_D] = (instr & 0x400000)>>22; + res->fields_mask[FIELD_D >> 6] |= 1LL << (FIELD_D & 63); + char D_width = 1; + res->fields[FIELD_size] = (instr & 0x300000)>>20; + res->fields_mask[FIELD_size >> 6] |= 1LL << (FIELD_size & 63); + char size_width = 2; + res->fields[FIELD_Vn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Vn >> 6] |= 1LL << (FIELD_Vn & 63); + char Vn_width = 4; + res->fields[FIELD_Vd] = (instr & 0xF000)>>12; + res->fields_mask[FIELD_Vd >> 6] |= 1LL << (FIELD_Vd & 63); + char Vd_width = 4; + res->fields[FIELD_N] = (instr & 0x80)>>7; + res->fields_mask[FIELD_N >> 6] |= 1LL << (FIELD_N & 63); + char N_width = 1; + res->fields[FIELD_Q] = (instr & 0x40)>>6; + res->fields_mask[FIELD_Q >> 6] |= 1LL << (FIELD_Q & 63); + char Q_width = 1; + res->fields[FIELD_M] = (instr & 0x20)>>5; + res->fields_mask[FIELD_M >> 6] |= 1LL << (FIELD_M & 63); + char M_width = 1; + res->fields[FIELD_Vm] = instr & 0xF; + res->fields_mask[FIELD_Vm >> 6] |= 1LL << (FIELD_Vm & 63); + char Vm_width = 4; + + static const instruction_format instr_formats[] = + { + { /* VRSHL<c>.<type><size> <Dd>,<Dm>,<Dn> */ + "vrshl", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_NEON_TYPE_SIZE|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_m,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_n,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + { /* VRSHL<c>.<type><size> <Qd>,<Qm>,<Qn> */ + "vrshl", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_NEON_TYPE_SIZE|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"q","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_m,FIELD_UNINIT,"q","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_n,FIELD_UNINIT,"q","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 2; + res->mnem = armv7::ARMV7_VRSHL; + + /* pcode: if (Q == '1' && (Vd<0> == '1' || Vm<0> == '1' || Vn<0> == '1')) then UNDEFINED */ + if((((res->fields[FIELD_Q]) == (0x1)) && ((((((res->fields[FIELD_Vd] & 1)) == (0x1)) || (((res->fields[FIELD_Vm] & 1)) == (0x1))) || (((res->fields[FIELD_Vn] & 1)) == (0x1)))))) { + res->status |= STATUS_UNDEFINED; + } + /* pcode: unsigned = (U == '1') */ + res->fields[FIELD_unsigned] = ((res->fields[FIELD_U]) == (0x1)); + res->fields_mask[FIELD_unsigned >> 6] |= 1LL << (FIELD_unsigned & 63); + /* pcode: esize = 8 << UInt(size) */ + res->fields[FIELD_esize] = (8) << ((res->fields[FIELD_size])); + res->fields_mask[FIELD_esize >> 6] |= 1LL << (FIELD_esize & 63); + /* pcode: elements = 64 DIV esize */ + res->fields[FIELD_elements] = ((res->fields[FIELD_esize]) ? ((64) / (res->fields[FIELD_esize])) : 0); + res->fields_mask[FIELD_elements >> 6] |= 1LL << (FIELD_elements & 63); + /* pcode: d = UInt(D:Vd) */ + res->fields[FIELD_d] = ((res->fields[FIELD_D]<<Vd_width)|(res->fields[FIELD_Vd])); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: m = UInt(M:Vm) */ + res->fields[FIELD_m] = ((res->fields[FIELD_M]<<Vm_width)|(res->fields[FIELD_Vm])); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + /* pcode: n = UInt(N:Vn) */ + res->fields[FIELD_n] = ((res->fields[FIELD_N]<<Vn_width)|(res->fields[FIELD_Vn])); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: regs = if Q == '0' then 1 else 2 */ + if((res->fields[FIELD_Q]) == (0x0)) { + res->fields[FIELD_regs] = 1; + res->fields_mask[FIELD_regs >> 6] |= 1LL << (FIELD_regs & 63); + } + else { + res->fields[FIELD_regs] = 2; + res->fields_mask[FIELD_regs >> 6] |= 1LL << (FIELD_regs & 63); + } + /* pcode: fmt_idx = (Q == '1') */ + res->fields[FIELD_fmt_idx] = ((res->fields[FIELD_Q]) == (0x1)); + res->fields_mask[FIELD_fmt_idx >> 6] |= 1LL << (FIELD_fmt_idx & 63); + /* pcode: type = UInt(U) + 2 */ + res->fields[FIELD_type] = ((res->fields[FIELD_U])) + (2); + res->fields_mask[FIELD_type >> 6] |= 1LL << (FIELD_type & 63); + /* pcode: size = if size == '00' then 3 else UInt(size) - 1 */ + if((res->fields[FIELD_size]) == (0x0)) { + res->fields[FIELD_size] = 3; + res->fields_mask[FIELD_size >> 6] |= 1LL << (FIELD_size & 63); + } + else { + res->fields[FIELD_size] = ((res->fields[FIELD_size])) - (1); + res->fields_mask[FIELD_size >> 6] |= 1LL << (FIELD_size & 63); + } + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: 2A3768A7 +int vrshr(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + res->group = INSN_GROUP_NEON; + /* Encoding T1 */ + /* pattern="111,U.1,1111,1,D.1,imm6.6,Vd.4,0010,L.1,Q.1,M.1,1,Vm.4" width=32 stringency=18 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xEF800F10)==0xEF800210)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ADVSIMD)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_U] = (instr & 0x10000000)>>28; + res->fields_mask[FIELD_U >> 6] |= 1LL << (FIELD_U & 63); + char U_width = 1; + res->fields[FIELD_D] = (instr & 0x400000)>>22; + res->fields_mask[FIELD_D >> 6] |= 1LL << (FIELD_D & 63); + char D_width = 1; + res->fields[FIELD_imm6] = (instr & 0x3F0000)>>16; + res->fields_mask[FIELD_imm6 >> 6] |= 1LL << (FIELD_imm6 & 63); + char imm6_width = 6; + res->fields[FIELD_Vd] = (instr & 0xF000)>>12; + res->fields_mask[FIELD_Vd >> 6] |= 1LL << (FIELD_Vd & 63); + char Vd_width = 4; + res->fields[FIELD_L] = (instr & 0x80)>>7; + res->fields_mask[FIELD_L >> 6] |= 1LL << (FIELD_L & 63); + char L_width = 1; + res->fields[FIELD_Q] = (instr & 0x40)>>6; + res->fields_mask[FIELD_Q >> 6] |= 1LL << (FIELD_Q & 63); + char Q_width = 1; + res->fields[FIELD_M] = (instr & 0x20)>>5; + res->fields_mask[FIELD_M >> 6] |= 1LL << (FIELD_M & 63); + char M_width = 1; + res->fields[FIELD_Vm] = instr & 0xF; + res->fields_mask[FIELD_Vm >> 6] |= 1LL << (FIELD_Vm & 63); + char Vm_width = 4; + + static const instruction_format instr_formats[] = + { + { /* VRSHR<c>.<type><size> <Dd>,<Dm>,#<imm> */ + "vrshr", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_NEON_TYPE_SIZE|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_m,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_IMM,FIELD_imm,FIELD_UNINIT,"#","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + { /* VRSHR<c>.<type><size> <Qd>,<Qm>,#<imm> */ + "vrshr", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_NEON_TYPE_SIZE|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"q","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_m,FIELD_UNINIT,"q","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_IMM,FIELD_imm,FIELD_UNINIT,"#","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 2; + res->mnem = armv7::ARMV7_VRSHR; + + /* pcode: if (L == '0' && UInt(imm6) < 8) then SEE advsimd_one_reg_mod_imm */ + if((((res->fields[FIELD_L]) == (0x0)) && (((res->fields[FIELD_imm6])) < (8)))) { + + return advsimd_one_reg_mod_imm(req, res); + } + /* pcode: if (Q == '1' && (Vd<0> == '1' || Vm<0> == '1')) then UNDEFINED */ + if((((res->fields[FIELD_Q]) == (0x1)) && (((((res->fields[FIELD_Vd] & 1)) == (0x1)) || (((res->fields[FIELD_Vm] & 1)) == (0x1)))))) { + res->status |= STATUS_UNDEFINED; + } + /* pcode: if UInt(L:imm6) < 128 then esize = 64 */ + if((((res->fields[FIELD_L]<<6)|(res->fields[FIELD_imm6]))) < (128)) { + res->fields[FIELD_esize] = 64; + res->fields_mask[FIELD_esize >> 6] |= 1LL << (FIELD_esize & 63); + } + /* pcode: if UInt(L:imm6) < 64 then esize = 32 */ + if((((res->fields[FIELD_L]<<6)|(res->fields[FIELD_imm6]))) < (64)) { + res->fields[FIELD_esize] = 32; + res->fields_mask[FIELD_esize >> 6] |= 1LL << (FIELD_esize & 63); + } + /* pcode: if UInt(L:imm6) < 32 then esize = 16 */ + if((((res->fields[FIELD_L]<<6)|(res->fields[FIELD_imm6]))) < (32)) { + res->fields[FIELD_esize] = 16; + res->fields_mask[FIELD_esize >> 6] |= 1LL << (FIELD_esize & 63); + } + /* pcode: if UInt(L:imm6) < 16 then esize = 8 */ + if((((res->fields[FIELD_L]<<6)|(res->fields[FIELD_imm6]))) < (16)) { + res->fields[FIELD_esize] = 8; + res->fields_mask[FIELD_esize >> 6] |= 1LL << (FIELD_esize & 63); + } + /* pcode: elements = 64 DIV esize */ + res->fields[FIELD_elements] = ((res->fields[FIELD_esize]) ? ((64) / (res->fields[FIELD_esize])) : 0); + res->fields_mask[FIELD_elements >> 6] |= 1LL << (FIELD_elements & 63); + /* pcode: d = UInt(D:Vd) */ + res->fields[FIELD_d] = ((res->fields[FIELD_D]<<Vd_width)|(res->fields[FIELD_Vd])); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: m = UInt(M:Vm) */ + res->fields[FIELD_m] = ((res->fields[FIELD_M]<<Vm_width)|(res->fields[FIELD_Vm])); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + /* pcode: regs = if Q == '0' then 1 else 2 */ + if((res->fields[FIELD_Q]) == (0x0)) { + res->fields[FIELD_regs] = 1; + res->fields_mask[FIELD_regs >> 6] |= 1LL << (FIELD_regs & 63); + } + else { + res->fields[FIELD_regs] = 2; + res->fields_mask[FIELD_regs >> 6] |= 1LL << (FIELD_regs & 63); + } + /* pcode: fmt_idx = (Q == '1') */ + res->fields[FIELD_fmt_idx] = ((res->fields[FIELD_Q]) == (0x1)); + res->fields_mask[FIELD_fmt_idx >> 6] |= 1LL << (FIELD_fmt_idx & 63); + /* pcode: imm = imm6 */ + res->fields[FIELD_imm] = res->fields[FIELD_imm6]; + res->fields_mask[FIELD_imm >> 6] |= 1LL << (FIELD_imm & 63); + /* pcode: type = UInt(U) + 2 */ + res->fields[FIELD_type] = ((res->fields[FIELD_U])) + (2); + res->fields_mask[FIELD_type >> 6] |= 1LL << (FIELD_type & 63); + /* pcode: if esize == 64 then size = 2 */ + if((res->fields[FIELD_esize]) == (64)) { + res->fields[FIELD_size] = 2; + res->fields_mask[FIELD_size >> 6] |= 1LL << (FIELD_size & 63); + } + /* pcode: if esize == 32 then size = 1 */ + if((res->fields[FIELD_esize]) == (32)) { + res->fields[FIELD_size] = 1; + res->fields_mask[FIELD_size >> 6] |= 1LL << (FIELD_size & 63); + } + /* pcode: if esize == 16 then size = 0 */ + if((res->fields[FIELD_esize]) == (16)) { + res->fields[FIELD_size] = 0; + res->fields_mask[FIELD_size >> 6] |= 1LL << (FIELD_size & 63); + } + /* pcode: if esize == 8 then size = 3 */ + if((res->fields[FIELD_esize]) == (8)) { + res->fields[FIELD_size] = 3; + res->fields_mask[FIELD_size >> 6] |= 1LL << (FIELD_size & 63); + } + /* pcode: imm = UInt(imm6) */ + res->fields[FIELD_imm] = (res->fields[FIELD_imm6]); + res->fields_mask[FIELD_imm >> 6] |= 1LL << (FIELD_imm & 63); + /* pcode: if esize == 64 then imm = 64 - UInt(imm6) */ + if((res->fields[FIELD_esize]) == (64)) { + res->fields[FIELD_imm] = (64) - ((res->fields[FIELD_imm6])); + res->fields_mask[FIELD_imm >> 6] |= 1LL << (FIELD_imm & 63); + } + /* pcode: if esize == 32 then imm = 32 - UInt(imm6<4:0>) */ + if((res->fields[FIELD_esize]) == (32)) { + res->fields[FIELD_imm] = (32) - (((res->fields[FIELD_imm6] & 0x1F))); + res->fields_mask[FIELD_imm >> 6] |= 1LL << (FIELD_imm & 63); + } + /* pcode: if esize == 16 then imm = 16 - UInt(imm6<3:0>) */ + if((res->fields[FIELD_esize]) == (16)) { + res->fields[FIELD_imm] = (16) - (((res->fields[FIELD_imm6] & 0xF))); + res->fields_mask[FIELD_imm >> 6] |= 1LL << (FIELD_imm & 63); + } + /* pcode: if esize == 8 then imm = 8 - UInt(imm6<2:0>) */ + if((res->fields[FIELD_esize]) == (8)) { + res->fields[FIELD_imm] = (8) - (((res->fields[FIELD_imm6] & 0x7))); + res->fields_mask[FIELD_imm >> 6] |= 1LL << (FIELD_imm & 63); + } + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: 25E22C52 +int vrshrn(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + res->group = INSN_GROUP_NEON; + /* Encoding T1 */ + /* pattern="1110,xx1x,1,D.1,imm6.6,Vd.4,1000,0,1,M.1,1,Vm.4" width=32 stringency=15 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xF2800FD0)==0xE2800850)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ADVSIMD)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_D] = (instr & 0x400000)>>22; + res->fields_mask[FIELD_D >> 6] |= 1LL << (FIELD_D & 63); + char D_width = 1; + res->fields[FIELD_imm6] = (instr & 0x3F0000)>>16; + res->fields_mask[FIELD_imm6 >> 6] |= 1LL << (FIELD_imm6 & 63); + char imm6_width = 6; + res->fields[FIELD_Vd] = (instr & 0xF000)>>12; + res->fields_mask[FIELD_Vd >> 6] |= 1LL << (FIELD_Vd & 63); + char Vd_width = 4; + res->fields[FIELD_M] = (instr & 0x20)>>5; + res->fields_mask[FIELD_M >> 6] |= 1LL << (FIELD_M & 63); + char M_width = 1; + res->fields[FIELD_Vm] = instr & 0xF; + res->fields_mask[FIELD_Vm >> 6] |= 1LL << (FIELD_Vm & 63); + char Vm_width = 4; + + static const instruction_format instr_formats[] = + { + { /* VRSHRN<c>.I<size> <Dd>,<Qm>,#<imm> */ + "vrshrn.i", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_NEON_SINGLE_SIZE|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_m,FIELD_UNINIT,"q","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_IMM,FIELD_imm,FIELD_UNINIT,"#","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_VRSHRN; + + /* pcode: if UInt(imm6) < 8 then SEE advsimd_one_reg_mod_imm */ + if(((res->fields[FIELD_imm6])) < (8)) { + + return advsimd_one_reg_mod_imm(req, res); + } + /* pcode: if Vm<0> == '1' then UNDEFINED */ + if(((res->fields[FIELD_Vm] & 1)) == (0x1)) { + res->status |= STATUS_UNDEFINED; + } + /* pcode: if UInt(imm6) < 64 then esize = 32 */ + if(((res->fields[FIELD_imm6])) < (64)) { + res->fields[FIELD_esize] = 32; + res->fields_mask[FIELD_esize >> 6] |= 1LL << (FIELD_esize & 63); + } + /* pcode: if UInt(imm6) < 32 then esize = 16 */ + if(((res->fields[FIELD_imm6])) < (32)) { + res->fields[FIELD_esize] = 16; + res->fields_mask[FIELD_esize >> 6] |= 1LL << (FIELD_esize & 63); + } + /* pcode: if UInt(imm6) < 16 then esize = 8 */ + if(((res->fields[FIELD_imm6])) < (16)) { + res->fields[FIELD_esize] = 8; + res->fields_mask[FIELD_esize >> 6] |= 1LL << (FIELD_esize & 63); + } + /* pcode: elements = 64 DIV esize */ + res->fields[FIELD_elements] = ((res->fields[FIELD_esize]) ? ((64) / (res->fields[FIELD_esize])) : 0); + res->fields_mask[FIELD_elements >> 6] |= 1LL << (FIELD_elements & 63); + /* pcode: d = UInt(D:Vd) */ + res->fields[FIELD_d] = ((res->fields[FIELD_D]<<Vd_width)|(res->fields[FIELD_Vd])); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: m = UInt(M:Vm) */ + res->fields[FIELD_m] = ((res->fields[FIELD_M]<<Vm_width)|(res->fields[FIELD_Vm])); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + /* pcode: regs = if Q == '0' then 1 else 2 */ + if((res->fields[FIELD_Q]) == (0x0)) { + res->fields[FIELD_regs] = 1; + res->fields_mask[FIELD_regs >> 6] |= 1LL << (FIELD_regs & 63); + } + else { + res->fields[FIELD_regs] = 2; + res->fields_mask[FIELD_regs >> 6] |= 1LL << (FIELD_regs & 63); + } + /* pcode: imm = imm6 */ + res->fields[FIELD_imm] = res->fields[FIELD_imm6]; + res->fields_mask[FIELD_imm >> 6] |= 1LL << (FIELD_imm & 63); + /* pcode: if esize == 32 then size = 3 */ + if((res->fields[FIELD_esize]) == (32)) { + res->fields[FIELD_size] = 3; + res->fields_mask[FIELD_size >> 6] |= 1LL << (FIELD_size & 63); + } + /* pcode: if esize == 16 then size = 2 */ + if((res->fields[FIELD_esize]) == (16)) { + res->fields[FIELD_size] = 2; + res->fields_mask[FIELD_size >> 6] |= 1LL << (FIELD_size & 63); + } + /* pcode: if esize == 8 then size = 1 */ + if((res->fields[FIELD_esize]) == (8)) { + res->fields[FIELD_size] = 1; + res->fields_mask[FIELD_size >> 6] |= 1LL << (FIELD_size & 63); + } + /* pcode: imm = UInt(imm6) */ + res->fields[FIELD_imm] = (res->fields[FIELD_imm6]); + res->fields_mask[FIELD_imm >> 6] |= 1LL << (FIELD_imm & 63); + /* pcode: if esize == 32 then imm = 32 - UInt(imm6<4:0>) */ + if((res->fields[FIELD_esize]) == (32)) { + res->fields[FIELD_imm] = (32) - (((res->fields[FIELD_imm6] & 0x1F))); + res->fields_mask[FIELD_imm >> 6] |= 1LL << (FIELD_imm & 63); + } + /* pcode: if esize == 16 then imm = 16 - UInt(imm6<3:0>) */ + if((res->fields[FIELD_esize]) == (16)) { + res->fields[FIELD_imm] = (16) - (((res->fields[FIELD_imm6] & 0xF))); + res->fields_mask[FIELD_imm >> 6] |= 1LL << (FIELD_imm & 63); + } + /* pcode: if esize == 8 then imm = 8 - UInt(imm6<2:0>) */ + if((res->fields[FIELD_esize]) == (8)) { + res->fields[FIELD_imm] = (8) - (((res->fields[FIELD_imm6] & 0x7))); + res->fields_mask[FIELD_imm >> 6] |= 1LL << (FIELD_imm & 63); + } + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: A8C1E8E8 +int vrsqrte(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + res->group = INSN_GROUP_NEON; + /* Encoding T2 */ + /* pattern="1111,xx11,1,D.1,11,size.2,11,Vd.4,010,1,1,Q.1,M.1,0,Vm.4" width=32 stringency=20 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xF3B30F90)==0xF3B30580)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ADVSIMD)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_D] = (instr & 0x400000)>>22; + res->fields_mask[FIELD_D >> 6] |= 1LL << (FIELD_D & 63); + char D_width = 1; + res->fields[FIELD_size] = (instr & 0xC0000)>>18; + res->fields_mask[FIELD_size >> 6] |= 1LL << (FIELD_size & 63); + char size_width = 2; + res->fields[FIELD_Vd] = (instr & 0xF000)>>12; + res->fields_mask[FIELD_Vd >> 6] |= 1LL << (FIELD_Vd & 63); + char Vd_width = 4; + res->fields[FIELD_Q] = (instr & 0x40)>>6; + res->fields_mask[FIELD_Q >> 6] |= 1LL << (FIELD_Q & 63); + char Q_width = 1; + res->fields[FIELD_M] = (instr & 0x20)>>5; + res->fields_mask[FIELD_M >> 6] |= 1LL << (FIELD_M & 63); + char M_width = 1; + res->fields[FIELD_Vm] = instr & 0xF; + res->fields_mask[FIELD_Vm >> 6] |= 1LL << (FIELD_Vm & 63); + char Vm_width = 4; + + static const instruction_format instr_formats[] = + { + { /* VRSQRTE<c>.F32 <Dd>,<Dm> */ + "vrsqrte.f32", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_F32, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_m,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + { /* VRSQRTE<c>.F32 <Qd>,<Qm> */ + "vrsqrte.f32", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_F32, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"q","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_m,FIELD_UNINIT,"q","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 2; + res->mnem = armv7::ARMV7_VRSQRTE; + + /* pcode: if (Q == '1' && (Vd<0> == '1' || Vm<0> == '1')) then UNDEFINED */ + if((((res->fields[FIELD_Q]) == (0x1)) && (((((res->fields[FIELD_Vd] & 1)) == (0x1)) || (((res->fields[FIELD_Vm] & 1)) == (0x1)))))) { + res->status |= STATUS_UNDEFINED; + } + /* pcode: if size != '10' then UNDEFINED */ + if((res->fields[FIELD_size]) != (0x2)) { + res->status |= STATUS_UNDEFINED; + } + /* pcode: esize = 32 */ + res->fields[FIELD_esize] = 32; + res->fields_mask[FIELD_esize >> 6] |= 1LL << (FIELD_esize & 63); + /* pcode: elements = 2 */ + res->fields[FIELD_elements] = 2; + res->fields_mask[FIELD_elements >> 6] |= 1LL << (FIELD_elements & 63); + /* pcode: d = UInt(D:Vd) */ + res->fields[FIELD_d] = ((res->fields[FIELD_D]<<Vd_width)|(res->fields[FIELD_Vd])); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: m = UInt(M:Vm) */ + res->fields[FIELD_m] = ((res->fields[FIELD_M]<<Vm_width)|(res->fields[FIELD_Vm])); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + /* pcode: regs = if Q == '0' then 1 else 2 */ + if((res->fields[FIELD_Q]) == (0x0)) { + res->fields[FIELD_regs] = 1; + res->fields_mask[FIELD_regs >> 6] |= 1LL << (FIELD_regs & 63); + } + else { + res->fields[FIELD_regs] = 2; + res->fields_mask[FIELD_regs >> 6] |= 1LL << (FIELD_regs & 63); + } + /* pcode: fmt_idx = (Q == '1') */ + res->fields[FIELD_fmt_idx] = ((res->fields[FIELD_Q]) == (0x1)); + res->fields_mask[FIELD_fmt_idx >> 6] |= 1LL << (FIELD_fmt_idx & 63); + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* Encoding T1 */ + /* pattern="1111,xx11,1,D.1,11,size.2,11,Vd.4,010,0,1,Q.1,M.1,0,Vm.4" width=32 stringency=20 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xF3B30F90)==0xF3B30480)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ADVSIMD)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_D] = (instr & 0x400000)>>22; + res->fields_mask[FIELD_D >> 6] |= 1LL << (FIELD_D & 63); + char D_width = 1; + res->fields[FIELD_size] = (instr & 0xC0000)>>18; + res->fields_mask[FIELD_size >> 6] |= 1LL << (FIELD_size & 63); + char size_width = 2; + res->fields[FIELD_Vd] = (instr & 0xF000)>>12; + res->fields_mask[FIELD_Vd >> 6] |= 1LL << (FIELD_Vd & 63); + char Vd_width = 4; + res->fields[FIELD_Q] = (instr & 0x40)>>6; + res->fields_mask[FIELD_Q >> 6] |= 1LL << (FIELD_Q & 63); + char Q_width = 1; + res->fields[FIELD_M] = (instr & 0x20)>>5; + res->fields_mask[FIELD_M >> 6] |= 1LL << (FIELD_M & 63); + char M_width = 1; + res->fields[FIELD_Vm] = instr & 0xF; + res->fields_mask[FIELD_Vm >> 6] |= 1LL << (FIELD_Vm & 63); + char Vm_width = 4; + + static const instruction_format instr_formats[] = + { + { /* VRSQRTE<c>.U32 <Dd>,<Dm> */ + "vrsqrte.u32", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_m,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + { /* VRSQRTE<c>.U32 <Qd>,<Qm> */ + "vrsqrte.u32", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"q","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_m,FIELD_UNINIT,"q","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 2; + res->mnem = armv7::ARMV7_VRSQRTE; + + /* pcode: if (Q == '1' && (Vd<0> == '1' || Vm<0> == '1')) then UNDEFINED */ + if((((res->fields[FIELD_Q]) == (0x1)) && (((((res->fields[FIELD_Vd] & 1)) == (0x1)) || (((res->fields[FIELD_Vm] & 1)) == (0x1)))))) { + res->status |= STATUS_UNDEFINED; + } + /* pcode: if size != '10' then UNDEFINED */ + if((res->fields[FIELD_size]) != (0x2)) { + res->status |= STATUS_UNDEFINED; + } + /* pcode: esize = 32 */ + res->fields[FIELD_esize] = 32; + res->fields_mask[FIELD_esize >> 6] |= 1LL << (FIELD_esize & 63); + /* pcode: elements = 2 */ + res->fields[FIELD_elements] = 2; + res->fields_mask[FIELD_elements >> 6] |= 1LL << (FIELD_elements & 63); + /* pcode: d = UInt(D:Vd) */ + res->fields[FIELD_d] = ((res->fields[FIELD_D]<<Vd_width)|(res->fields[FIELD_Vd])); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: m = UInt(M:Vm) */ + res->fields[FIELD_m] = ((res->fields[FIELD_M]<<Vm_width)|(res->fields[FIELD_Vm])); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + /* pcode: regs = if Q == '0' then 1 else 2 */ + if((res->fields[FIELD_Q]) == (0x0)) { + res->fields[FIELD_regs] = 1; + res->fields_mask[FIELD_regs >> 6] |= 1LL << (FIELD_regs & 63); + } + else { + res->fields[FIELD_regs] = 2; + res->fields_mask[FIELD_regs >> 6] |= 1LL << (FIELD_regs & 63); + } + /* pcode: fmt_idx = (Q == '1') */ + res->fields[FIELD_fmt_idx] = ((res->fields[FIELD_Q]) == (0x1)); + res->fields_mask[FIELD_fmt_idx >> 6] |= 1LL << (FIELD_fmt_idx & 63); + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: A3B34607 +int vrsqrts(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + res->group = INSN_GROUP_NEON; + /* Encoding T1 */ + /* pattern="111x,xx1x,0,D.1,1,sz.1,Vn.4,Vd.4,1111,N.1,Q.1,M.1,1,Vm.4" width=32 stringency=16 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xE2A00F10)==0xE2200F10)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ADVSIMD)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_D] = (instr & 0x400000)>>22; + res->fields_mask[FIELD_D >> 6] |= 1LL << (FIELD_D & 63); + char D_width = 1; + res->fields[FIELD_sz] = (instr & 0x100000)>>20; + res->fields_mask[FIELD_sz >> 6] |= 1LL << (FIELD_sz & 63); + char sz_width = 1; + res->fields[FIELD_Vn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Vn >> 6] |= 1LL << (FIELD_Vn & 63); + char Vn_width = 4; + res->fields[FIELD_Vd] = (instr & 0xF000)>>12; + res->fields_mask[FIELD_Vd >> 6] |= 1LL << (FIELD_Vd & 63); + char Vd_width = 4; + res->fields[FIELD_N] = (instr & 0x80)>>7; + res->fields_mask[FIELD_N >> 6] |= 1LL << (FIELD_N & 63); + char N_width = 1; + res->fields[FIELD_Q] = (instr & 0x40)>>6; + res->fields_mask[FIELD_Q >> 6] |= 1LL << (FIELD_Q & 63); + char Q_width = 1; + res->fields[FIELD_M] = (instr & 0x20)>>5; + res->fields_mask[FIELD_M >> 6] |= 1LL << (FIELD_M & 63); + char M_width = 1; + res->fields[FIELD_Vm] = instr & 0xF; + res->fields_mask[FIELD_Vm >> 6] |= 1LL << (FIELD_Vm & 63); + char Vm_width = 4; + + static const instruction_format instr_formats[] = + { + { /* VRSQRTS<c>.F32 <Dd>,<Dn>,<Dm> */ + "vrsqrts.f32", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_F32, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_n,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_m,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + { /* VRSQRTS<c>.F32 <Qd>,<Qn>,<Qm> */ + "vrsqrts.f32", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_F32, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"q","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_n,FIELD_UNINIT,"q","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_m,FIELD_UNINIT,"q","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 2; + res->mnem = armv7::ARMV7_VRSQRTS; + + /* pcode: if (Q == '1' && (Vd<0> == '1' || Vn<0> == '1' || Vm<0> == '1')) then UNDEFINED */ + if((((res->fields[FIELD_Q]) == (0x1)) && ((((((res->fields[FIELD_Vd] & 1)) == (0x1)) || (((res->fields[FIELD_Vn] & 1)) == (0x1))) || (((res->fields[FIELD_Vm] & 1)) == (0x1)))))) { + res->status |= STATUS_UNDEFINED; + } + /* pcode: if sz == '1' then UNDEFINED */ + if((res->fields[FIELD_sz]) == (0x1)) { + res->status |= STATUS_UNDEFINED; + } + /* pcode: esize = 32 */ + res->fields[FIELD_esize] = 32; + res->fields_mask[FIELD_esize >> 6] |= 1LL << (FIELD_esize & 63); + /* pcode: elements = 2 */ + res->fields[FIELD_elements] = 2; + res->fields_mask[FIELD_elements >> 6] |= 1LL << (FIELD_elements & 63); + /* pcode: d = UInt(D:Vd) */ + res->fields[FIELD_d] = ((res->fields[FIELD_D]<<Vd_width)|(res->fields[FIELD_Vd])); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: n = UInt(N:Vn) */ + res->fields[FIELD_n] = ((res->fields[FIELD_N]<<Vn_width)|(res->fields[FIELD_Vn])); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: m = UInt(M:Vm) */ + res->fields[FIELD_m] = ((res->fields[FIELD_M]<<Vm_width)|(res->fields[FIELD_Vm])); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + /* pcode: regs = if Q == '0' then 1 else 2 */ + if((res->fields[FIELD_Q]) == (0x0)) { + res->fields[FIELD_regs] = 1; + res->fields_mask[FIELD_regs >> 6] |= 1LL << (FIELD_regs & 63); + } + else { + res->fields[FIELD_regs] = 2; + res->fields_mask[FIELD_regs >> 6] |= 1LL << (FIELD_regs & 63); + } + /* pcode: fmt_idx = (Q == '1') */ + res->fields[FIELD_fmt_idx] = ((res->fields[FIELD_Q]) == (0x1)); + res->fields_mask[FIELD_fmt_idx >> 6] |= 1LL << (FIELD_fmt_idx & 63); + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: D772853C +int vrsra(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + res->group = INSN_GROUP_NEON; + /* Encoding T1 */ + /* pattern="111,U.1,1111,1,D.1,imm6.6,Vd.4,0011,L.1,Q.1,M.1,1,Vm.4" width=32 stringency=18 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xEF800F10)==0xEF800310)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ADVSIMD)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_U] = (instr & 0x10000000)>>28; + res->fields_mask[FIELD_U >> 6] |= 1LL << (FIELD_U & 63); + char U_width = 1; + res->fields[FIELD_D] = (instr & 0x400000)>>22; + res->fields_mask[FIELD_D >> 6] |= 1LL << (FIELD_D & 63); + char D_width = 1; + res->fields[FIELD_imm6] = (instr & 0x3F0000)>>16; + res->fields_mask[FIELD_imm6 >> 6] |= 1LL << (FIELD_imm6 & 63); + char imm6_width = 6; + res->fields[FIELD_Vd] = (instr & 0xF000)>>12; + res->fields_mask[FIELD_Vd >> 6] |= 1LL << (FIELD_Vd & 63); + char Vd_width = 4; + res->fields[FIELD_L] = (instr & 0x80)>>7; + res->fields_mask[FIELD_L >> 6] |= 1LL << (FIELD_L & 63); + char L_width = 1; + res->fields[FIELD_Q] = (instr & 0x40)>>6; + res->fields_mask[FIELD_Q >> 6] |= 1LL << (FIELD_Q & 63); + char Q_width = 1; + res->fields[FIELD_M] = (instr & 0x20)>>5; + res->fields_mask[FIELD_M >> 6] |= 1LL << (FIELD_M & 63); + char M_width = 1; + res->fields[FIELD_Vm] = instr & 0xF; + res->fields_mask[FIELD_Vm >> 6] |= 1LL << (FIELD_Vm & 63); + char Vm_width = 4; + + static const instruction_format instr_formats[] = + { + { /* VRSRA<c>.<type><size> <Dd>,<Dm>,#<imm> */ + "vrsra", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_NEON_TYPE_SIZE|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_m,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_IMM,FIELD_imm,FIELD_UNINIT,"#","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + { /* VRSRA<c>.<type><size> <Qd>,<Qm>,#<imm> */ + "vrsra", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_NEON_TYPE_SIZE|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"q","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_m,FIELD_UNINIT,"q","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_IMM,FIELD_imm,FIELD_UNINIT,"#","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 2; + res->mnem = armv7::ARMV7_VRSRA; + + /* pcode: if (L == '0' && UInt(imm6) < 8) then SEE advsimd_one_reg_mod_imm */ + if((((res->fields[FIELD_L]) == (0x0)) && (((res->fields[FIELD_imm6])) < (8)))) { + + return advsimd_one_reg_mod_imm(req, res); + } + /* pcode: if (Q == '1' && (Vd<0> == '1' || Vm<0> == '1')) then UNDEFINED */ + if((((res->fields[FIELD_Q]) == (0x1)) && (((((res->fields[FIELD_Vd] & 1)) == (0x1)) || (((res->fields[FIELD_Vm] & 1)) == (0x1)))))) { + res->status |= STATUS_UNDEFINED; + } + /* pcode: if UInt(L:imm6) < 128 then esize = 64 */ + if((((res->fields[FIELD_L]<<6)|(res->fields[FIELD_imm6]))) < (128)) { + res->fields[FIELD_esize] = 64; + res->fields_mask[FIELD_esize >> 6] |= 1LL << (FIELD_esize & 63); + } + /* pcode: if UInt(L:imm6) < 64 then esize = 32 */ + if((((res->fields[FIELD_L]<<6)|(res->fields[FIELD_imm6]))) < (64)) { + res->fields[FIELD_esize] = 32; + res->fields_mask[FIELD_esize >> 6] |= 1LL << (FIELD_esize & 63); + } + /* pcode: if UInt(L:imm6) < 32 then esize = 16 */ + if((((res->fields[FIELD_L]<<6)|(res->fields[FIELD_imm6]))) < (32)) { + res->fields[FIELD_esize] = 16; + res->fields_mask[FIELD_esize >> 6] |= 1LL << (FIELD_esize & 63); + } + /* pcode: if UInt(L:imm6) < 16 then esize = 8 */ + if((((res->fields[FIELD_L]<<6)|(res->fields[FIELD_imm6]))) < (16)) { + res->fields[FIELD_esize] = 8; + res->fields_mask[FIELD_esize >> 6] |= 1LL << (FIELD_esize & 63); + } + /* pcode: elements = 64 DIV esize */ + res->fields[FIELD_elements] = ((res->fields[FIELD_esize]) ? ((64) / (res->fields[FIELD_esize])) : 0); + res->fields_mask[FIELD_elements >> 6] |= 1LL << (FIELD_elements & 63); + /* pcode: d = UInt(D:Vd) */ + res->fields[FIELD_d] = ((res->fields[FIELD_D]<<Vd_width)|(res->fields[FIELD_Vd])); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: m = UInt(M:Vm) */ + res->fields[FIELD_m] = ((res->fields[FIELD_M]<<Vm_width)|(res->fields[FIELD_Vm])); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + /* pcode: regs = if Q == '0' then 1 else 2 */ + if((res->fields[FIELD_Q]) == (0x0)) { + res->fields[FIELD_regs] = 1; + res->fields_mask[FIELD_regs >> 6] |= 1LL << (FIELD_regs & 63); + } + else { + res->fields[FIELD_regs] = 2; + res->fields_mask[FIELD_regs >> 6] |= 1LL << (FIELD_regs & 63); + } + /* pcode: imm = imm6 */ + res->fields[FIELD_imm] = res->fields[FIELD_imm6]; + res->fields_mask[FIELD_imm >> 6] |= 1LL << (FIELD_imm & 63); + /* pcode: type = UInt(U) + 2 */ + res->fields[FIELD_type] = ((res->fields[FIELD_U])) + (2); + res->fields_mask[FIELD_type >> 6] |= 1LL << (FIELD_type & 63); + /* pcode: if esize == 64 then size = 2 */ + if((res->fields[FIELD_esize]) == (64)) { + res->fields[FIELD_size] = 2; + res->fields_mask[FIELD_size >> 6] |= 1LL << (FIELD_size & 63); + } + /* pcode: if esize == 32 then size = 1 */ + if((res->fields[FIELD_esize]) == (32)) { + res->fields[FIELD_size] = 1; + res->fields_mask[FIELD_size >> 6] |= 1LL << (FIELD_size & 63); + } + /* pcode: if esize == 16 then size = 0 */ + if((res->fields[FIELD_esize]) == (16)) { + res->fields[FIELD_size] = 0; + res->fields_mask[FIELD_size >> 6] |= 1LL << (FIELD_size & 63); + } + /* pcode: if esize == 8 then size = 3 */ + if((res->fields[FIELD_esize]) == (8)) { + res->fields[FIELD_size] = 3; + res->fields_mask[FIELD_size >> 6] |= 1LL << (FIELD_size & 63); + } + /* pcode: imm = UInt(imm6) */ + res->fields[FIELD_imm] = (res->fields[FIELD_imm6]); + res->fields_mask[FIELD_imm >> 6] |= 1LL << (FIELD_imm & 63); + /* pcode: if esize == 64 then imm = 64 - UInt(imm6) */ + if((res->fields[FIELD_esize]) == (64)) { + res->fields[FIELD_imm] = (64) - ((res->fields[FIELD_imm6])); + res->fields_mask[FIELD_imm >> 6] |= 1LL << (FIELD_imm & 63); + } + /* pcode: if esize == 32 then imm = 64 - UInt(imm6) */ + if((res->fields[FIELD_esize]) == (32)) { + res->fields[FIELD_imm] = (64) - ((res->fields[FIELD_imm6])); + res->fields_mask[FIELD_imm >> 6] |= 1LL << (FIELD_imm & 63); + } + /* pcode: if esize == 16 then imm = 32 - UInt(imm6) */ + if((res->fields[FIELD_esize]) == (16)) { + res->fields[FIELD_imm] = (32) - ((res->fields[FIELD_imm6])); + res->fields_mask[FIELD_imm >> 6] |= 1LL << (FIELD_imm & 63); + } + /* pcode: if esize == 8 then imm = 16 - UInt(imm6) */ + if((res->fields[FIELD_esize]) == (8)) { + res->fields[FIELD_imm] = (16) - ((res->fields[FIELD_imm6])); + res->fields_mask[FIELD_imm >> 6] |= 1LL << (FIELD_imm & 63); + } + /* pcode: fmt_idx = (Q == '1') */ + res->fields[FIELD_fmt_idx] = ((res->fields[FIELD_Q]) == (0x1)); + res->fields_mask[FIELD_fmt_idx >> 6] |= 1LL << (FIELD_fmt_idx & 63); + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: DC3FBFD9 +int vrsubhn(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + res->group = INSN_GROUP_NEON; + /* Encoding T1 */ + /* pattern="1111,1111,1,D.1,size.2,Vn.4,Vd.4,0110,N.1,0,M.1,0,Vm.4" width=32 stringency=18 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFF800F50)==0xFF800600)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ADVSIMD)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_D] = (instr & 0x400000)>>22; + res->fields_mask[FIELD_D >> 6] |= 1LL << (FIELD_D & 63); + char D_width = 1; + res->fields[FIELD_size] = (instr & 0x300000)>>20; + res->fields_mask[FIELD_size >> 6] |= 1LL << (FIELD_size & 63); + char size_width = 2; + res->fields[FIELD_Vn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Vn >> 6] |= 1LL << (FIELD_Vn & 63); + char Vn_width = 4; + res->fields[FIELD_Vd] = (instr & 0xF000)>>12; + res->fields_mask[FIELD_Vd >> 6] |= 1LL << (FIELD_Vd & 63); + char Vd_width = 4; + res->fields[FIELD_N] = (instr & 0x80)>>7; + res->fields_mask[FIELD_N >> 6] |= 1LL << (FIELD_N & 63); + char N_width = 1; + res->fields[FIELD_M] = (instr & 0x20)>>5; + res->fields_mask[FIELD_M >> 6] |= 1LL << (FIELD_M & 63); + char M_width = 1; + res->fields[FIELD_Vm] = instr & 0xF; + res->fields_mask[FIELD_Vm >> 6] |= 1LL << (FIELD_Vm & 63); + char Vm_width = 4; + + static const instruction_format instr_formats[] = + { + { /* VRSUBHN<c>.<dt> <Dd>,<Qn>,<Qm> */ + "vrsubhn", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_VFP_DATA_SIZE, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_n,FIELD_UNINIT,"q","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_m,FIELD_UNINIT,"q","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_VRSUBHN; + + /* pcode: if size == '11' then SEE advanced_simd_data_proc */ + if((res->fields[FIELD_size]) == (0x3)) { + + return advanced_simd_data_proc(req, res); + } + /* pcode: if (Vn<0> == '1' || Vm<0> == '1') then UNDEFINED */ + if(((((res->fields[FIELD_Vn] & 1)) == (0x1)) || (((res->fields[FIELD_Vm] & 1)) == (0x1)))) { + res->status |= STATUS_UNDEFINED; + } + /* pcode: esize = 8 << UInt(size) */ + res->fields[FIELD_esize] = (8) << ((res->fields[FIELD_size])); + res->fields_mask[FIELD_esize >> 6] |= 1LL << (FIELD_esize & 63); + /* pcode: elements = 64 DIV esize */ + res->fields[FIELD_elements] = ((res->fields[FIELD_esize]) ? ((64) / (res->fields[FIELD_esize])) : 0); + res->fields_mask[FIELD_elements >> 6] |= 1LL << (FIELD_elements & 63); + /* pcode: d = UInt(D:Vd) */ + res->fields[FIELD_d] = ((res->fields[FIELD_D]<<Vd_width)|(res->fields[FIELD_Vd])); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: n = UInt(N:Vn) */ + res->fields[FIELD_n] = ((res->fields[FIELD_N]<<Vn_width)|(res->fields[FIELD_Vn])); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: m = UInt(M:Vm) */ + res->fields[FIELD_m] = ((res->fields[FIELD_M]<<Vm_width)|(res->fields[FIELD_Vm])); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + /* pcode: iword = TRUE */ + res->fields[FIELD_iword] = 1; + res->fields_mask[FIELD_iword >> 6] |= 1LL << (FIELD_iword & 63); + /* pcode: dt = size + 1 */ + res->fields[FIELD_dt] = (res->fields[FIELD_size]) + (1); + res->fields_mask[FIELD_dt >> 6] |= 1LL << (FIELD_dt & 63); + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: 8850819A +int vsel(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + res->group = INSN_GROUP_NEON; + /* Encoding T1 */ + /* pattern="1111,11100,D.1,cc.2,Vn.4,Vd.4,101,sz.1,N.1,0,M.1,0,Vm.4" width=32 stringency=18 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFF800E50)==0xFE000A00)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ADVSIMD)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_D] = (instr & 0x400000)>>22; + res->fields_mask[FIELD_D >> 6] |= 1LL << (FIELD_D & 63); + char D_width = 1; + res->fields[FIELD_cc] = (instr & 0x300000)>>20; + res->fields_mask[FIELD_cc >> 6] |= 1LL << (FIELD_cc & 63); + char cc_width = 2; + res->fields[FIELD_Vn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Vn >> 6] |= 1LL << (FIELD_Vn & 63); + char Vn_width = 4; + res->fields[FIELD_Vd] = (instr & 0xF000)>>12; + res->fields_mask[FIELD_Vd >> 6] |= 1LL << (FIELD_Vd & 63); + char Vd_width = 4; + res->fields[FIELD_sz] = (instr & 0x100)>>8; + res->fields_mask[FIELD_sz >> 6] |= 1LL << (FIELD_sz & 63); + char sz_width = 1; + res->fields[FIELD_N] = (instr & 0x80)>>7; + res->fields_mask[FIELD_N >> 6] |= 1LL << (FIELD_N & 63); + char N_width = 1; + res->fields[FIELD_M] = (instr & 0x20)>>5; + res->fields_mask[FIELD_M >> 6] |= 1LL << (FIELD_M & 63); + char M_width = 1; + res->fields[FIELD_Vm] = instr & 0xF; + res->fields_mask[FIELD_Vm >> 6] |= 1LL << (FIELD_Vm & 63); + char Vm_width = 4; + + static const instruction_format instr_formats[] = + { + { /* VSEL<c>.<dt> <Sd>,<Sn>,<Sm> */ + "vsel", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_VFP_DATA_SIZE, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"s","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_n,FIELD_UNINIT,"s","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_m,FIELD_UNINIT,"s","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + { /* VSEL<c>.<dt> <Dd>,<Dn>,<Dm> */ + "vsel", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_VFP_DATA_SIZE, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_n,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_m,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 2; + res->mnem = armv7::ARMV7_VSEL; + + /* pcode: dp_operation = (sz == '1') */ + res->fields[FIELD_dp_operation] = ((res->fields[FIELD_sz]) == (0x1)); + res->fields_mask[FIELD_dp_operation >> 6] |= 1LL << (FIELD_dp_operation & 63); + /* pcode: cond = ((cc * 2) + (cc<1> XOR cc<0>)) * 2 */ + res->fields[FIELD_cond] = (((((res->fields[FIELD_cc]) * (2))) + (((((res->fields[FIELD_cc] >> 1) & 1)) ^ ((res->fields[FIELD_cc] & 1)))))) * (2); + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + /* pcode: d = if dp_operation then UInt(D:Vd) else UInt(Vd:D) */ + if(res->fields[FIELD_dp_operation]) { + res->fields[FIELD_d] = ((res->fields[FIELD_D]<<Vd_width)|(res->fields[FIELD_Vd])); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + } + else { + res->fields[FIELD_d] = ((res->fields[FIELD_Vd]<<D_width)|(res->fields[FIELD_D])); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + } + /* pcode: n = if dp_operation then UInt(N:Vn) else UInt(Vn:N) */ + if(res->fields[FIELD_dp_operation]) { + res->fields[FIELD_n] = ((res->fields[FIELD_N]<<Vn_width)|(res->fields[FIELD_Vn])); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + } + else { + res->fields[FIELD_n] = ((res->fields[FIELD_Vn]<<N_width)|(res->fields[FIELD_N])); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + } + /* pcode: m = if dp_operation then UInt(M:Vm) else UInt(Vm:M) */ + if(res->fields[FIELD_dp_operation]) { + res->fields[FIELD_m] = ((res->fields[FIELD_M]<<Vm_width)|(res->fields[FIELD_Vm])); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + } + else { + res->fields[FIELD_m] = ((res->fields[FIELD_Vm]<<M_width)|(res->fields[FIELD_M])); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + } + /* pcode: fmt_idx = dp_operation */ + res->fields[FIELD_fmt_idx] = res->fields[FIELD_dp_operation]; + res->fields_mask[FIELD_fmt_idx >> 6] |= 1LL << (FIELD_fmt_idx & 63); + /* pcode: dt = 3 + dp_operation */ + res->fields[FIELD_dt] = (3) + (res->fields[FIELD_dp_operation]); + res->fields_mask[FIELD_dt >> 6] |= 1LL << (FIELD_dt & 63); + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: FF4636B8 +int vshl_immediate(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + res->group = INSN_GROUP_NEON; + /* Encoding T1 */ + /* pattern="111x,xx1x,1,D.1,imm6.6,Vd.4,0101,L.1,Q.1,M.1,1,Vm.4" width=32 stringency=14 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xE2800F10)==0xE2800510)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ADVSIMD)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_D] = (instr & 0x400000)>>22; + res->fields_mask[FIELD_D >> 6] |= 1LL << (FIELD_D & 63); + char D_width = 1; + res->fields[FIELD_imm6] = (instr & 0x3F0000)>>16; + res->fields_mask[FIELD_imm6 >> 6] |= 1LL << (FIELD_imm6 & 63); + char imm6_width = 6; + res->fields[FIELD_Vd] = (instr & 0xF000)>>12; + res->fields_mask[FIELD_Vd >> 6] |= 1LL << (FIELD_Vd & 63); + char Vd_width = 4; + res->fields[FIELD_L] = (instr & 0x80)>>7; + res->fields_mask[FIELD_L >> 6] |= 1LL << (FIELD_L & 63); + char L_width = 1; + res->fields[FIELD_Q] = (instr & 0x40)>>6; + res->fields_mask[FIELD_Q >> 6] |= 1LL << (FIELD_Q & 63); + char Q_width = 1; + res->fields[FIELD_M] = (instr & 0x20)>>5; + res->fields_mask[FIELD_M >> 6] |= 1LL << (FIELD_M & 63); + char M_width = 1; + res->fields[FIELD_Vm] = instr & 0xF; + res->fields_mask[FIELD_Vm >> 6] |= 1LL << (FIELD_Vm & 63); + char Vm_width = 4; + + static const instruction_format instr_formats[] = + { + { /* VSHL<c>.I<size> <Dd>,<Dm>,#<imm> */ + "vshl.i", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_NEON_SINGLE_SIZE|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_m,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_IMM,FIELD_imm,FIELD_UNINIT,"#","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + { /* VSHL<c>.I<size> <Qd>,<Qm>,#<imm> */ + "vshl.i", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_NEON_SINGLE_SIZE|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"q","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_m,FIELD_UNINIT,"q","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_IMM,FIELD_imm,FIELD_UNINIT,"#","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 2; + res->mnem = armv7::ARMV7_VSHL; + + /* pcode: if (L == '0' && UInt(imm6) < 8) then SEE advsimd_one_reg_mod_imm */ + if((((res->fields[FIELD_L]) == (0x0)) && (((res->fields[FIELD_imm6])) < (8)))) { + + return advsimd_one_reg_mod_imm(req, res); + } + /* pcode: if (Q == '1' && (Vd<0> == '1' || Vm<0> == '1')) then UNDEFINED */ + if((((res->fields[FIELD_Q]) == (0x1)) && (((((res->fields[FIELD_Vd] & 1)) == (0x1)) || (((res->fields[FIELD_Vm] & 1)) == (0x1)))))) { + res->status |= STATUS_UNDEFINED; + } + /* pcode: if UInt(L:imm6) < 128 then esize = 64 */ + if((((res->fields[FIELD_L]<<6)|(res->fields[FIELD_imm6]))) < (128)) { + res->fields[FIELD_esize] = 64; + res->fields_mask[FIELD_esize >> 6] |= 1LL << (FIELD_esize & 63); + } + /* pcode: if UInt(L:imm6) < 64 then esize = 32 */ + if((((res->fields[FIELD_L]<<6)|(res->fields[FIELD_imm6]))) < (64)) { + res->fields[FIELD_esize] = 32; + res->fields_mask[FIELD_esize >> 6] |= 1LL << (FIELD_esize & 63); + } + /* pcode: if UInt(L:imm6) < 32 then esize = 16 */ + if((((res->fields[FIELD_L]<<6)|(res->fields[FIELD_imm6]))) < (32)) { + res->fields[FIELD_esize] = 16; + res->fields_mask[FIELD_esize >> 6] |= 1LL << (FIELD_esize & 63); + } + /* pcode: if UInt(L:imm6) < 16 then esize = 8 */ + if((((res->fields[FIELD_L]<<6)|(res->fields[FIELD_imm6]))) < (16)) { + res->fields[FIELD_esize] = 8; + res->fields_mask[FIELD_esize >> 6] |= 1LL << (FIELD_esize & 63); + } + /* pcode: elements = 64 DIV esize */ + res->fields[FIELD_elements] = ((res->fields[FIELD_esize]) ? ((64) / (res->fields[FIELD_esize])) : 0); + res->fields_mask[FIELD_elements >> 6] |= 1LL << (FIELD_elements & 63); + /* pcode: d = UInt(D:Vd) */ + res->fields[FIELD_d] = ((res->fields[FIELD_D]<<Vd_width)|(res->fields[FIELD_Vd])); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: m = UInt(M:Vm) */ + res->fields[FIELD_m] = ((res->fields[FIELD_M]<<Vm_width)|(res->fields[FIELD_Vm])); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + /* pcode: regs = if Q == '0' then 1 else 2 */ + if((res->fields[FIELD_Q]) == (0x0)) { + res->fields[FIELD_regs] = 1; + res->fields_mask[FIELD_regs >> 6] |= 1LL << (FIELD_regs & 63); + } + else { + res->fields[FIELD_regs] = 2; + res->fields_mask[FIELD_regs >> 6] |= 1LL << (FIELD_regs & 63); + } + /* pcode: fmt_idx = (Q == '1') */ + res->fields[FIELD_fmt_idx] = ((res->fields[FIELD_Q]) == (0x1)); + res->fields_mask[FIELD_fmt_idx >> 6] |= 1LL << (FIELD_fmt_idx & 63); + /* pcode: imm = imm6 */ + res->fields[FIELD_imm] = res->fields[FIELD_imm6]; + res->fields_mask[FIELD_imm >> 6] |= 1LL << (FIELD_imm & 63); + /* pcode: if esize == 64 then size = 3 */ + if((res->fields[FIELD_esize]) == (64)) { + res->fields[FIELD_size] = 3; + res->fields_mask[FIELD_size >> 6] |= 1LL << (FIELD_size & 63); + } + /* pcode: if esize == 32 then size = 2 */ + if((res->fields[FIELD_esize]) == (32)) { + res->fields[FIELD_size] = 2; + res->fields_mask[FIELD_size >> 6] |= 1LL << (FIELD_size & 63); + } + /* pcode: if esize == 16 then size = 1 */ + if((res->fields[FIELD_esize]) == (16)) { + res->fields[FIELD_size] = 1; + res->fields_mask[FIELD_size >> 6] |= 1LL << (FIELD_size & 63); + } + /* pcode: if esize == 8 then size = 0 */ + if((res->fields[FIELD_esize]) == (8)) { + res->fields[FIELD_size] = 0; + res->fields_mask[FIELD_size >> 6] |= 1LL << (FIELD_size & 63); + } + /* pcode: if esize == 64 then imm = UInt(imm6) */ + if((res->fields[FIELD_esize]) == (64)) { + res->fields[FIELD_imm] = (res->fields[FIELD_imm6]); + res->fields_mask[FIELD_imm >> 6] |= 1LL << (FIELD_imm & 63); + } + /* pcode: if esize == 32 then imm = UInt(imm6) - 32 */ + if((res->fields[FIELD_esize]) == (32)) { + res->fields[FIELD_imm] = ((res->fields[FIELD_imm6])) - (32); + res->fields_mask[FIELD_imm >> 6] |= 1LL << (FIELD_imm & 63); + } + /* pcode: if esize == 16 then imm = UInt(imm6) - 16 */ + if((res->fields[FIELD_esize]) == (16)) { + res->fields[FIELD_imm] = ((res->fields[FIELD_imm6])) - (16); + res->fields_mask[FIELD_imm >> 6] |= 1LL << (FIELD_imm & 63); + } + /* pcode: if esize == 8 then imm = UInt(imm6) - 8 */ + if((res->fields[FIELD_esize]) == (8)) { + res->fields[FIELD_imm] = ((res->fields[FIELD_imm6])) - (8); + res->fields_mask[FIELD_imm >> 6] |= 1LL << (FIELD_imm & 63); + } + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: 5D4BCB7F +int vshl_register(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + res->group = INSN_GROUP_NEON; + /* Encoding T1 */ + /* pattern="111,U.1,1111,0,D.1,size.2,Vn.4,Vd.4,0100,N.1,Q.1,M.1,0,Vm.4" width=32 stringency=18 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xEF800F10)==0xEF000400)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ADVSIMD)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_U] = (instr & 0x10000000)>>28; + res->fields_mask[FIELD_U >> 6] |= 1LL << (FIELD_U & 63); + char U_width = 1; + res->fields[FIELD_D] = (instr & 0x400000)>>22; + res->fields_mask[FIELD_D >> 6] |= 1LL << (FIELD_D & 63); + char D_width = 1; + res->fields[FIELD_size] = (instr & 0x300000)>>20; + res->fields_mask[FIELD_size >> 6] |= 1LL << (FIELD_size & 63); + char size_width = 2; + res->fields[FIELD_Vn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Vn >> 6] |= 1LL << (FIELD_Vn & 63); + char Vn_width = 4; + res->fields[FIELD_Vd] = (instr & 0xF000)>>12; + res->fields_mask[FIELD_Vd >> 6] |= 1LL << (FIELD_Vd & 63); + char Vd_width = 4; + res->fields[FIELD_N] = (instr & 0x80)>>7; + res->fields_mask[FIELD_N >> 6] |= 1LL << (FIELD_N & 63); + char N_width = 1; + res->fields[FIELD_Q] = (instr & 0x40)>>6; + res->fields_mask[FIELD_Q >> 6] |= 1LL << (FIELD_Q & 63); + char Q_width = 1; + res->fields[FIELD_M] = (instr & 0x20)>>5; + res->fields_mask[FIELD_M >> 6] |= 1LL << (FIELD_M & 63); + char M_width = 1; + res->fields[FIELD_Vm] = instr & 0xF; + res->fields_mask[FIELD_Vm >> 6] |= 1LL << (FIELD_Vm & 63); + char Vm_width = 4; + + static const instruction_format instr_formats[] = + { + { /* VSHL<c>.<dt> <Dd>,<Dm>,<Dn> */ + "vshl", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_VFP_DATA_SIZE, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_m,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_n,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + { /* VSHL<c>.<dt> <Qd>,<Qm>,<Qn> */ + "vshl", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_VFP_DATA_SIZE, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"q","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_m,FIELD_UNINIT,"q","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_n,FIELD_UNINIT,"q","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 2; + res->mnem = armv7::ARMV7_VSHL; + + /* pcode: if (Q == '1' && (Vd<0> == '1' || Vm<0> == '1' || Vn<0> == '1')) then UNDEFINED */ + if((((res->fields[FIELD_Q]) == (0x1)) && ((((((res->fields[FIELD_Vd] & 1)) == (0x1)) || (((res->fields[FIELD_Vm] & 1)) == (0x1))) || (((res->fields[FIELD_Vn] & 1)) == (0x1)))))) { + res->status |= STATUS_UNDEFINED; + } + /* pcode: unsigned = (U == '1') */ + res->fields[FIELD_unsigned] = ((res->fields[FIELD_U]) == (0x1)); + res->fields_mask[FIELD_unsigned >> 6] |= 1LL << (FIELD_unsigned & 63); + /* pcode: esize = 8 << UInt(size) */ + res->fields[FIELD_esize] = (8) << ((res->fields[FIELD_size])); + res->fields_mask[FIELD_esize >> 6] |= 1LL << (FIELD_esize & 63); + /* pcode: elements = 64 DIV esize */ + res->fields[FIELD_elements] = ((res->fields[FIELD_esize]) ? ((64) / (res->fields[FIELD_esize])) : 0); + res->fields_mask[FIELD_elements >> 6] |= 1LL << (FIELD_elements & 63); + /* pcode: d = UInt(D:Vd) */ + res->fields[FIELD_d] = ((res->fields[FIELD_D]<<Vd_width)|(res->fields[FIELD_Vd])); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: m = UInt(M:Vm) */ + res->fields[FIELD_m] = ((res->fields[FIELD_M]<<Vm_width)|(res->fields[FIELD_Vm])); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + /* pcode: n = UInt(N:Vn) */ + res->fields[FIELD_n] = ((res->fields[FIELD_N]<<Vn_width)|(res->fields[FIELD_Vn])); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: regs = if Q == '0' then 1 else 2 */ + if((res->fields[FIELD_Q]) == (0x0)) { + res->fields[FIELD_regs] = 1; + res->fields_mask[FIELD_regs >> 6] |= 1LL << (FIELD_regs & 63); + } + else { + res->fields[FIELD_regs] = 2; + res->fields_mask[FIELD_regs >> 6] |= 1LL << (FIELD_regs & 63); + } + /* pcode: fmt_idx = (Q == '1') */ + res->fields[FIELD_fmt_idx] = ((res->fields[FIELD_Q]) == (0x1)); + res->fields_mask[FIELD_fmt_idx >> 6] |= 1LL << (FIELD_fmt_idx & 63); + /* pcode: dt = UInt(U:size) */ + res->fields[FIELD_dt] = ((res->fields[FIELD_U]<<size_width)|(res->fields[FIELD_size])); + res->fields_mask[FIELD_dt >> 6] |= 1LL << (FIELD_dt & 63); + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: 7DACCA6C +int vshll(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + res->group = INSN_GROUP_NEON; + /* Encoding T2 */ + /* pattern="1111,xx11,1,D.1,11,size.2,10,Vd.4,0011,0,0,M.1,0,Vm.4" width=32 stringency=20 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xF3B30FD0)==0xF3B20300)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ADVSIMD)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_D] = (instr & 0x400000)>>22; + res->fields_mask[FIELD_D >> 6] |= 1LL << (FIELD_D & 63); + char D_width = 1; + res->fields[FIELD_size] = (instr & 0xC0000)>>18; + res->fields_mask[FIELD_size >> 6] |= 1LL << (FIELD_size & 63); + char size_width = 2; + res->fields[FIELD_Vd] = (instr & 0xF000)>>12; + res->fields_mask[FIELD_Vd >> 6] |= 1LL << (FIELD_Vd & 63); + char Vd_width = 4; + res->fields[FIELD_M] = (instr & 0x20)>>5; + res->fields_mask[FIELD_M >> 6] |= 1LL << (FIELD_M & 63); + char M_width = 1; + res->fields[FIELD_Vm] = instr & 0xF; + res->fields_mask[FIELD_Vm >> 6] |= 1LL << (FIELD_Vm & 63); + char Vm_width = 4; + + static const instruction_format instr_formats[] = + { + { /* VSHLL<c>.I<size> <Qd>,<Dm>,#<imm> */ + "vshll.i", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_NEON_SINGLE_SIZE|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"q","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_m,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_IMM,FIELD_imm,FIELD_UNINIT,"#","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_VSHLL; + + /* pcode: if (size == '11' || Vd<0> == '1') then UNDEFINED */ + if((((res->fields[FIELD_size]) == (0x3)) || (((res->fields[FIELD_Vd] & 1)) == (0x1)))) { + res->status |= STATUS_UNDEFINED; + } + /* pcode: esize = 8 << UInt(size) */ + res->fields[FIELD_esize] = (8) << ((res->fields[FIELD_size])); + res->fields_mask[FIELD_esize >> 6] |= 1LL << (FIELD_esize & 63); + /* pcode: unsigned = FALSE */ + res->fields[FIELD_unsigned] = 0; + res->fields_mask[FIELD_unsigned >> 6] |= 1LL << (FIELD_unsigned & 63); + /* pcode: d = UInt(D:Vd) */ + res->fields[FIELD_d] = ((res->fields[FIELD_D]<<Vd_width)|(res->fields[FIELD_Vd])); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: m = UInt(M:Vm) */ + res->fields[FIELD_m] = ((res->fields[FIELD_M]<<Vm_width)|(res->fields[FIELD_Vm])); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + /* pcode: if size == '00' then imm = 8 */ + if((res->fields[FIELD_size]) == (0x0)) { + res->fields[FIELD_imm] = 8; + res->fields_mask[FIELD_imm >> 6] |= 1LL << (FIELD_imm & 63); + } + /* pcode: if size == '01' then imm = 16 */ + if((res->fields[FIELD_size]) == (0x1)) { + res->fields[FIELD_imm] = 16; + res->fields_mask[FIELD_imm >> 6] |= 1LL << (FIELD_imm & 63); + } + /* pcode: if size == '10' then imm = 32 */ + if((res->fields[FIELD_size]) == (0x2)) { + res->fields[FIELD_imm] = 32; + res->fields_mask[FIELD_imm >> 6] |= 1LL << (FIELD_imm & 63); + } + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* Encoding T1 */ + /* pattern="111,U.1,1111,1,D.1,imm6.6,Vd.4,1010,0,0,M.1,1,Vm.4" width=32 stringency=18 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xEF800FD0)==0xEF800A10)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ADVSIMD)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_U] = (instr & 0x10000000)>>28; + res->fields_mask[FIELD_U >> 6] |= 1LL << (FIELD_U & 63); + char U_width = 1; + res->fields[FIELD_D] = (instr & 0x400000)>>22; + res->fields_mask[FIELD_D >> 6] |= 1LL << (FIELD_D & 63); + char D_width = 1; + res->fields[FIELD_imm6] = (instr & 0x3F0000)>>16; + res->fields_mask[FIELD_imm6 >> 6] |= 1LL << (FIELD_imm6 & 63); + char imm6_width = 6; + res->fields[FIELD_Vd] = (instr & 0xF000)>>12; + res->fields_mask[FIELD_Vd >> 6] |= 1LL << (FIELD_Vd & 63); + char Vd_width = 4; + res->fields[FIELD_M] = (instr & 0x20)>>5; + res->fields_mask[FIELD_M >> 6] |= 1LL << (FIELD_M & 63); + char M_width = 1; + res->fields[FIELD_Vm] = instr & 0xF; + res->fields_mask[FIELD_Vm >> 6] |= 1LL << (FIELD_Vm & 63); + char Vm_width = 4; + + static const instruction_format instr_formats[] = + { + { /* VSHLL<c>.<type><size> <Qd>,<Dm>,#<imm> */ + "vshll", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_NEON_TYPE_SIZE|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"q","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_m,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_IMM,FIELD_imm,FIELD_UNINIT,"#","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_VSHLL; + + /* pcode: if UInt(imm6) < 8 then SEE advsimd_one_reg_mod_imm */ + if(((res->fields[FIELD_imm6])) < (8)) { + + return advsimd_one_reg_mod_imm(req, res); + } + /* pcode: if (UInt(imm6) == 8 || UInt(imm6) == 16 || UInt(imm6) == 32) then SEE vmovl */ + if((((((res->fields[FIELD_imm6])) == (8)) || (((res->fields[FIELD_imm6])) == (16))) || (((res->fields[FIELD_imm6])) == (32)))) { + + return vmovl(req, res); + } + /* pcode: unsigned = (U == '1') */ + res->fields[FIELD_unsigned] = ((res->fields[FIELD_U]) == (0x1)); + res->fields_mask[FIELD_unsigned >> 6] |= 1LL << (FIELD_unsigned & 63); + /* pcode: d = UInt(D:Vd) */ + res->fields[FIELD_d] = ((res->fields[FIELD_D]<<Vd_width)|(res->fields[FIELD_Vd])); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: m = UInt(M:Vm) */ + res->fields[FIELD_m] = ((res->fields[FIELD_M]<<Vm_width)|(res->fields[FIELD_Vm])); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + /* pcode: esize = 32 */ + res->fields[FIELD_esize] = 32; + res->fields_mask[FIELD_esize >> 6] |= 1LL << (FIELD_esize & 63); + /* pcode: if UInt(imm6) < 32 then esize = 16 */ + if(((res->fields[FIELD_imm6])) < (32)) { + res->fields[FIELD_esize] = 16; + res->fields_mask[FIELD_esize >> 6] |= 1LL << (FIELD_esize & 63); + } + /* pcode: if UInt(imm6) < 16 then esize = 8 */ + if(((res->fields[FIELD_imm6])) < (16)) { + res->fields[FIELD_esize] = 8; + res->fields_mask[FIELD_esize >> 6] |= 1LL << (FIELD_esize & 63); + } + /* pcode: elements = 64 DIV esize */ + res->fields[FIELD_elements] = ((res->fields[FIELD_esize]) ? ((64) / (res->fields[FIELD_esize])) : 0); + res->fields_mask[FIELD_elements >> 6] |= 1LL << (FIELD_elements & 63); + /* pcode: type = UInt(U) + 2 */ + res->fields[FIELD_type] = ((res->fields[FIELD_U])) + (2); + res->fields_mask[FIELD_type >> 6] |= 1LL << (FIELD_type & 63); + /* pcode: if esize == 32 then size = 1 */ + if((res->fields[FIELD_esize]) == (32)) { + res->fields[FIELD_size] = 1; + res->fields_mask[FIELD_size >> 6] |= 1LL << (FIELD_size & 63); + } + /* pcode: if esize == 16 then size = 0 */ + if((res->fields[FIELD_esize]) == (16)) { + res->fields[FIELD_size] = 0; + res->fields_mask[FIELD_size >> 6] |= 1LL << (FIELD_size & 63); + } + /* pcode: if esize == 8 then size = 3 */ + if((res->fields[FIELD_esize]) == (8)) { + res->fields[FIELD_size] = 3; + res->fields_mask[FIELD_size >> 6] |= 1LL << (FIELD_size & 63); + } + /* pcode: if esize == 32 then imm = UInt(imm6) - 32 */ + if((res->fields[FIELD_esize]) == (32)) { + res->fields[FIELD_imm] = ((res->fields[FIELD_imm6])) - (32); + res->fields_mask[FIELD_imm >> 6] |= 1LL << (FIELD_imm & 63); + } + /* pcode: if esize == 16 then imm = UInt(imm6) - 16 */ + if((res->fields[FIELD_esize]) == (16)) { + res->fields[FIELD_imm] = ((res->fields[FIELD_imm6])) - (16); + res->fields_mask[FIELD_imm >> 6] |= 1LL << (FIELD_imm & 63); + } + /* pcode: if esize == 8 then imm = UInt(imm6) - 8 */ + if((res->fields[FIELD_esize]) == (8)) { + res->fields[FIELD_imm] = ((res->fields[FIELD_imm6])) - (8); + res->fields_mask[FIELD_imm >> 6] |= 1LL << (FIELD_imm & 63); + } + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: 9E798478 +int vshr(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + res->group = INSN_GROUP_NEON; + /* Encoding T1 */ + /* pattern="111,U.1,1111,1,D.1,imm6.6,Vd.4,0000,L.1,Q.1,M.1,1,Vm.4" width=32 stringency=18 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xEF800F10)==0xEF800010)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ADVSIMD)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_U] = (instr & 0x10000000)>>28; + res->fields_mask[FIELD_U >> 6] |= 1LL << (FIELD_U & 63); + char U_width = 1; + res->fields[FIELD_D] = (instr & 0x400000)>>22; + res->fields_mask[FIELD_D >> 6] |= 1LL << (FIELD_D & 63); + char D_width = 1; + res->fields[FIELD_imm6] = (instr & 0x3F0000)>>16; + res->fields_mask[FIELD_imm6 >> 6] |= 1LL << (FIELD_imm6 & 63); + char imm6_width = 6; + res->fields[FIELD_Vd] = (instr & 0xF000)>>12; + res->fields_mask[FIELD_Vd >> 6] |= 1LL << (FIELD_Vd & 63); + char Vd_width = 4; + res->fields[FIELD_L] = (instr & 0x80)>>7; + res->fields_mask[FIELD_L >> 6] |= 1LL << (FIELD_L & 63); + char L_width = 1; + res->fields[FIELD_Q] = (instr & 0x40)>>6; + res->fields_mask[FIELD_Q >> 6] |= 1LL << (FIELD_Q & 63); + char Q_width = 1; + res->fields[FIELD_M] = (instr & 0x20)>>5; + res->fields_mask[FIELD_M >> 6] |= 1LL << (FIELD_M & 63); + char M_width = 1; + res->fields[FIELD_Vm] = instr & 0xF; + res->fields_mask[FIELD_Vm >> 6] |= 1LL << (FIELD_Vm & 63); + char Vm_width = 4; + + static const instruction_format instr_formats[] = + { + { /* VSHR<c>.<type><size> <Dd>,<Dm>,#<imm> */ + "vshr", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_NEON_TYPE_SIZE|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_m,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_IMM,FIELD_imm,FIELD_UNINIT,"#","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + { /* VSHR<c>.<type><size> <Qd>,<Qm>,#<imm> */ + "vshr", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_NEON_TYPE_SIZE|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"q","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_m,FIELD_UNINIT,"q","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_IMM,FIELD_imm,FIELD_UNINIT,"#","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 2; + res->mnem = armv7::ARMV7_VSHR; + + /* pcode: if (L == '0' && UInt(imm6) < 8) then SEE advsimd_one_reg_mod_imm */ + if((((res->fields[FIELD_L]) == (0x0)) && (((res->fields[FIELD_imm6])) < (8)))) { + + return advsimd_one_reg_mod_imm(req, res); + } + /* pcode: if (Q == '1' && (Vd<0> == '1' || Vm<0> == '1')) then UNDEFINED */ + if((((res->fields[FIELD_Q]) == (0x1)) && (((((res->fields[FIELD_Vd] & 1)) == (0x1)) || (((res->fields[FIELD_Vm] & 1)) == (0x1)))))) { + res->status |= STATUS_UNDEFINED; + } + /* pcode: if UInt(L:imm6) < 128 then esize = 64 */ + if((((res->fields[FIELD_L]<<6)|(res->fields[FIELD_imm6]))) < (128)) { + res->fields[FIELD_esize] = 64; + res->fields_mask[FIELD_esize >> 6] |= 1LL << (FIELD_esize & 63); + } + /* pcode: if UInt(L:imm6) < 64 then esize = 32 */ + if((((res->fields[FIELD_L]<<6)|(res->fields[FIELD_imm6]))) < (64)) { + res->fields[FIELD_esize] = 32; + res->fields_mask[FIELD_esize >> 6] |= 1LL << (FIELD_esize & 63); + } + /* pcode: if UInt(L:imm6) < 32 then esize = 16 */ + if((((res->fields[FIELD_L]<<6)|(res->fields[FIELD_imm6]))) < (32)) { + res->fields[FIELD_esize] = 16; + res->fields_mask[FIELD_esize >> 6] |= 1LL << (FIELD_esize & 63); + } + /* pcode: if UInt(L:imm6) < 16 then esize = 8 */ + if((((res->fields[FIELD_L]<<6)|(res->fields[FIELD_imm6]))) < (16)) { + res->fields[FIELD_esize] = 8; + res->fields_mask[FIELD_esize >> 6] |= 1LL << (FIELD_esize & 63); + } + /* pcode: elements = 64 DIV esize */ + res->fields[FIELD_elements] = ((res->fields[FIELD_esize]) ? ((64) / (res->fields[FIELD_esize])) : 0); + res->fields_mask[FIELD_elements >> 6] |= 1LL << (FIELD_elements & 63); + /* pcode: d = UInt(D:Vd) */ + res->fields[FIELD_d] = ((res->fields[FIELD_D]<<Vd_width)|(res->fields[FIELD_Vd])); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: m = UInt(M:Vm) */ + res->fields[FIELD_m] = ((res->fields[FIELD_M]<<Vm_width)|(res->fields[FIELD_Vm])); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + /* pcode: regs = if Q == '0' then 1 else 2 */ + if((res->fields[FIELD_Q]) == (0x0)) { + res->fields[FIELD_regs] = 1; + res->fields_mask[FIELD_regs >> 6] |= 1LL << (FIELD_regs & 63); + } + else { + res->fields[FIELD_regs] = 2; + res->fields_mask[FIELD_regs >> 6] |= 1LL << (FIELD_regs & 63); + } + /* pcode: fmt_idx = (Q == '1') */ + res->fields[FIELD_fmt_idx] = ((res->fields[FIELD_Q]) == (0x1)); + res->fields_mask[FIELD_fmt_idx >> 6] |= 1LL << (FIELD_fmt_idx & 63); + /* pcode: imm = imm6 */ + res->fields[FIELD_imm] = res->fields[FIELD_imm6]; + res->fields_mask[FIELD_imm >> 6] |= 1LL << (FIELD_imm & 63); + /* pcode: type = UInt(U) + 2 */ + res->fields[FIELD_type] = ((res->fields[FIELD_U])) + (2); + res->fields_mask[FIELD_type >> 6] |= 1LL << (FIELD_type & 63); + /* pcode: if esize == 64 then size = 2 */ + if((res->fields[FIELD_esize]) == (64)) { + res->fields[FIELD_size] = 2; + res->fields_mask[FIELD_size >> 6] |= 1LL << (FIELD_size & 63); + } + /* pcode: if esize == 32 then size = 1 */ + if((res->fields[FIELD_esize]) == (32)) { + res->fields[FIELD_size] = 1; + res->fields_mask[FIELD_size >> 6] |= 1LL << (FIELD_size & 63); + } + /* pcode: if esize == 16 then size = 0 */ + if((res->fields[FIELD_esize]) == (16)) { + res->fields[FIELD_size] = 0; + res->fields_mask[FIELD_size >> 6] |= 1LL << (FIELD_size & 63); + } + /* pcode: if esize == 8 then size = 3 */ + if((res->fields[FIELD_esize]) == (8)) { + res->fields[FIELD_size] = 3; + res->fields_mask[FIELD_size >> 6] |= 1LL << (FIELD_size & 63); + } + /* pcode: imm = UInt(imm6) */ + res->fields[FIELD_imm] = (res->fields[FIELD_imm6]); + res->fields_mask[FIELD_imm >> 6] |= 1LL << (FIELD_imm & 63); + /* pcode: if esize == 64 then imm = 64 - UInt(imm6) */ + if((res->fields[FIELD_esize]) == (64)) { + res->fields[FIELD_imm] = (64) - ((res->fields[FIELD_imm6])); + res->fields_mask[FIELD_imm >> 6] |= 1LL << (FIELD_imm & 63); + } + /* pcode: if esize == 32 then imm = 32 - UInt(imm6<4:0>) */ + if((res->fields[FIELD_esize]) == (32)) { + res->fields[FIELD_imm] = (32) - (((res->fields[FIELD_imm6] & 0x1F))); + res->fields_mask[FIELD_imm >> 6] |= 1LL << (FIELD_imm & 63); + } + /* pcode: if esize == 16 then imm = 16 - UInt(imm6<3:0>) */ + if((res->fields[FIELD_esize]) == (16)) { + res->fields[FIELD_imm] = (16) - (((res->fields[FIELD_imm6] & 0xF))); + res->fields_mask[FIELD_imm >> 6] |= 1LL << (FIELD_imm & 63); + } + /* pcode: if esize == 8 then imm = 8 - UInt(imm6<2:0>) */ + if((res->fields[FIELD_esize]) == (8)) { + res->fields[FIELD_imm] = (8) - (((res->fields[FIELD_imm6] & 0x7))); + res->fields_mask[FIELD_imm >> 6] |= 1LL << (FIELD_imm & 63); + } + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: C59A1ED5 +int vshrn(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + res->group = INSN_GROUP_NEON; + /* Encoding T1 */ + /* pattern="111x,xx1x,1,D.1,imm6.6,Vd.4,1000,0,0,M.1,1,Vm.4" width=32 stringency=14 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xE2800FD0)==0xE2800810)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ADVSIMD)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_D] = (instr & 0x400000)>>22; + res->fields_mask[FIELD_D >> 6] |= 1LL << (FIELD_D & 63); + char D_width = 1; + res->fields[FIELD_imm6] = (instr & 0x3F0000)>>16; + res->fields_mask[FIELD_imm6 >> 6] |= 1LL << (FIELD_imm6 & 63); + char imm6_width = 6; + res->fields[FIELD_Vd] = (instr & 0xF000)>>12; + res->fields_mask[FIELD_Vd >> 6] |= 1LL << (FIELD_Vd & 63); + char Vd_width = 4; + res->fields[FIELD_M] = (instr & 0x20)>>5; + res->fields_mask[FIELD_M >> 6] |= 1LL << (FIELD_M & 63); + char M_width = 1; + res->fields[FIELD_Vm] = instr & 0xF; + res->fields_mask[FIELD_Vm >> 6] |= 1LL << (FIELD_Vm & 63); + char Vm_width = 4; + + static const instruction_format instr_formats[] = + { + { /* VSHRN<c>.I<size> <Dd>,<Qm>,#<imm> */ + "vshrn.i", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_NEON_SINGLE_SIZE|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_m,FIELD_UNINIT,"q","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_IMM,FIELD_imm,FIELD_UNINIT,"#","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_VSHRN; + + /* pcode: if UInt(imm6) < 8 then SEE advsimd_one_reg_mod_imm */ + if(((res->fields[FIELD_imm6])) < (8)) { + + return advsimd_one_reg_mod_imm(req, res); + } + /* pcode: if Vm<0> == '1' then UNDEFINED */ + if(((res->fields[FIELD_Vm] & 1)) == (0x1)) { + res->status |= STATUS_UNDEFINED; + } + /* pcode: esize = 32 */ + res->fields[FIELD_esize] = 32; + res->fields_mask[FIELD_esize >> 6] |= 1LL << (FIELD_esize & 63); + /* pcode: if UInt(imm6) < 32 then esize = 16 */ + if(((res->fields[FIELD_imm6])) < (32)) { + res->fields[FIELD_esize] = 16; + res->fields_mask[FIELD_esize >> 6] |= 1LL << (FIELD_esize & 63); + } + /* pcode: if UInt(imm6) < 16 then esize = 8 */ + if(((res->fields[FIELD_imm6])) < (16)) { + res->fields[FIELD_esize] = 8; + res->fields_mask[FIELD_esize >> 6] |= 1LL << (FIELD_esize & 63); + } + /* pcode: elements = 64 DIV esize */ + res->fields[FIELD_elements] = ((res->fields[FIELD_esize]) ? ((64) / (res->fields[FIELD_esize])) : 0); + res->fields_mask[FIELD_elements >> 6] |= 1LL << (FIELD_elements & 63); + /* pcode: if esize == 32 then size = 3 */ + if((res->fields[FIELD_esize]) == (32)) { + res->fields[FIELD_size] = 3; + res->fields_mask[FIELD_size >> 6] |= 1LL << (FIELD_size & 63); + } + /* pcode: if esize == 16 then size = 2 */ + if((res->fields[FIELD_esize]) == (16)) { + res->fields[FIELD_size] = 2; + res->fields_mask[FIELD_size >> 6] |= 1LL << (FIELD_size & 63); + } + /* pcode: if esize == 8 then size = 1 */ + if((res->fields[FIELD_esize]) == (8)) { + res->fields[FIELD_size] = 1; + res->fields_mask[FIELD_size >> 6] |= 1LL << (FIELD_size & 63); + } + /* pcode: imm = UInt(imm6) */ + res->fields[FIELD_imm] = (res->fields[FIELD_imm6]); + res->fields_mask[FIELD_imm >> 6] |= 1LL << (FIELD_imm & 63); + /* pcode: d = UInt(D:Vd) */ + res->fields[FIELD_d] = ((res->fields[FIELD_D]<<Vd_width)|(res->fields[FIELD_Vd])); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: m = UInt(M:Vm) */ + res->fields[FIELD_m] = ((res->fields[FIELD_M]<<Vm_width)|(res->fields[FIELD_Vm])); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + /* pcode: if esize == 32 then imm = 32 - UInt(imm6<4:0>) */ + if((res->fields[FIELD_esize]) == (32)) { + res->fields[FIELD_imm] = (32) - (((res->fields[FIELD_imm6] & 0x1F))); + res->fields_mask[FIELD_imm >> 6] |= 1LL << (FIELD_imm & 63); + } + /* pcode: if esize == 16 then imm = 16 - UInt(imm6<3:0>) */ + if((res->fields[FIELD_esize]) == (16)) { + res->fields[FIELD_imm] = (16) - (((res->fields[FIELD_imm6] & 0xF))); + res->fields_mask[FIELD_imm >> 6] |= 1LL << (FIELD_imm & 63); + } + /* pcode: if esize == 8 then imm = 8 - UInt(imm6<2:0>) */ + if((res->fields[FIELD_esize]) == (8)) { + res->fields[FIELD_imm] = (8) - (((res->fields[FIELD_imm6] & 0x7))); + res->fields_mask[FIELD_imm >> 6] |= 1LL << (FIELD_imm & 63); + } + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: CEB59E8C +int vsli(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + res->group = INSN_GROUP_NEON; + /* Encoding T1 */ + /* pattern="1111,1111,1,D.1,imm6.6,Vd.4,0101,L.1,Q.1,M.1,1,Vm.4" width=32 stringency=18 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFF800F10)==0xFF800510)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ADVSIMD)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_D] = (instr & 0x400000)>>22; + res->fields_mask[FIELD_D >> 6] |= 1LL << (FIELD_D & 63); + char D_width = 1; + res->fields[FIELD_imm6] = (instr & 0x3F0000)>>16; + res->fields_mask[FIELD_imm6 >> 6] |= 1LL << (FIELD_imm6 & 63); + char imm6_width = 6; + res->fields[FIELD_Vd] = (instr & 0xF000)>>12; + res->fields_mask[FIELD_Vd >> 6] |= 1LL << (FIELD_Vd & 63); + char Vd_width = 4; + res->fields[FIELD_L] = (instr & 0x80)>>7; + res->fields_mask[FIELD_L >> 6] |= 1LL << (FIELD_L & 63); + char L_width = 1; + res->fields[FIELD_Q] = (instr & 0x40)>>6; + res->fields_mask[FIELD_Q >> 6] |= 1LL << (FIELD_Q & 63); + char Q_width = 1; + res->fields[FIELD_M] = (instr & 0x20)>>5; + res->fields_mask[FIELD_M >> 6] |= 1LL << (FIELD_M & 63); + char M_width = 1; + res->fields[FIELD_Vm] = instr & 0xF; + res->fields_mask[FIELD_Vm >> 6] |= 1LL << (FIELD_Vm & 63); + char Vm_width = 4; + + static const instruction_format instr_formats[] = + { + { /* VSLI<c>.<size> <Dd>,<Dm>,#<imm> */ + "vsli", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_NEON_SIZE, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_m,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_IMM,FIELD_imm,FIELD_UNINIT,"#","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + { /* VSLI<c>.<size> <Qd>,<Qm>,#<imm> */ + "vsli", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_NEON_SIZE, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"q","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_m,FIELD_UNINIT,"q","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_IMM,FIELD_imm,FIELD_UNINIT,"#","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 2; + res->mnem = armv7::ARMV7_VSLI; + + /* pcode: if (L == '0' && UInt(imm6) < 8) then SEE advsimd_one_reg_mod_imm */ + if((((res->fields[FIELD_L]) == (0x0)) && (((res->fields[FIELD_imm6])) < (8)))) { + + return advsimd_one_reg_mod_imm(req, res); + } + /* pcode: if (Q == '1' && (Vd<0> == '1' || Vm<0> == '1')) then UNDEFINED */ + if((((res->fields[FIELD_Q]) == (0x1)) && (((((res->fields[FIELD_Vd] & 1)) == (0x1)) || (((res->fields[FIELD_Vm] & 1)) == (0x1)))))) { + res->status |= STATUS_UNDEFINED; + } + /* pcode: if UInt(L:imm6) < 128 then esize = 64 */ + if((((res->fields[FIELD_L]<<6)|(res->fields[FIELD_imm6]))) < (128)) { + res->fields[FIELD_esize] = 64; + res->fields_mask[FIELD_esize >> 6] |= 1LL << (FIELD_esize & 63); + } + /* pcode: if UInt(L:imm6) < 64 then esize = 32 */ + if((((res->fields[FIELD_L]<<6)|(res->fields[FIELD_imm6]))) < (64)) { + res->fields[FIELD_esize] = 32; + res->fields_mask[FIELD_esize >> 6] |= 1LL << (FIELD_esize & 63); + } + /* pcode: if UInt(L:imm6) < 32 then esize = 16 */ + if((((res->fields[FIELD_L]<<6)|(res->fields[FIELD_imm6]))) < (32)) { + res->fields[FIELD_esize] = 16; + res->fields_mask[FIELD_esize >> 6] |= 1LL << (FIELD_esize & 63); + } + /* pcode: if UInt(L:imm6) < 16 then esize = 8 */ + if((((res->fields[FIELD_L]<<6)|(res->fields[FIELD_imm6]))) < (16)) { + res->fields[FIELD_esize] = 8; + res->fields_mask[FIELD_esize >> 6] |= 1LL << (FIELD_esize & 63); + } + /* pcode: elements = 64 DIV esize */ + res->fields[FIELD_elements] = ((res->fields[FIELD_esize]) ? ((64) / (res->fields[FIELD_esize])) : 0); + res->fields_mask[FIELD_elements >> 6] |= 1LL << (FIELD_elements & 63); + /* pcode: d = UInt(D:Vd) */ + res->fields[FIELD_d] = ((res->fields[FIELD_D]<<Vd_width)|(res->fields[FIELD_Vd])); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: m = UInt(M:Vm) */ + res->fields[FIELD_m] = ((res->fields[FIELD_M]<<Vm_width)|(res->fields[FIELD_Vm])); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + /* pcode: regs = if Q == '0' then 1 else 2 */ + if((res->fields[FIELD_Q]) == (0x0)) { + res->fields[FIELD_regs] = 1; + res->fields_mask[FIELD_regs >> 6] |= 1LL << (FIELD_regs & 63); + } + else { + res->fields[FIELD_regs] = 2; + res->fields_mask[FIELD_regs >> 6] |= 1LL << (FIELD_regs & 63); + } + /* pcode: imm = imm6 */ + res->fields[FIELD_imm] = res->fields[FIELD_imm6]; + res->fields_mask[FIELD_imm >> 6] |= 1LL << (FIELD_imm & 63); + /* pcode: if esize == 64 then size = 3 */ + if((res->fields[FIELD_esize]) == (64)) { + res->fields[FIELD_size] = 3; + res->fields_mask[FIELD_size >> 6] |= 1LL << (FIELD_size & 63); + } + /* pcode: if esize == 32 then size = 2 */ + if((res->fields[FIELD_esize]) == (32)) { + res->fields[FIELD_size] = 2; + res->fields_mask[FIELD_size >> 6] |= 1LL << (FIELD_size & 63); + } + /* pcode: if esize == 16 then size = 1 */ + if((res->fields[FIELD_esize]) == (16)) { + res->fields[FIELD_size] = 1; + res->fields_mask[FIELD_size >> 6] |= 1LL << (FIELD_size & 63); + } + /* pcode: if esize == 8 then size = 0 */ + if((res->fields[FIELD_esize]) == (8)) { + res->fields[FIELD_size] = 0; + res->fields_mask[FIELD_size >> 6] |= 1LL << (FIELD_size & 63); + } + /* pcode: imm = UInt(imm6) */ + res->fields[FIELD_imm] = (res->fields[FIELD_imm6]); + res->fields_mask[FIELD_imm >> 6] |= 1LL << (FIELD_imm & 63); + /* pcode: if esize == 32 then imm = UInt(imm6) - 32 */ + if((res->fields[FIELD_esize]) == (32)) { + res->fields[FIELD_imm] = ((res->fields[FIELD_imm6])) - (32); + res->fields_mask[FIELD_imm >> 6] |= 1LL << (FIELD_imm & 63); + } + /* pcode: if esize == 16 then imm = UInt(imm6) - 16 */ + if((res->fields[FIELD_esize]) == (16)) { + res->fields[FIELD_imm] = ((res->fields[FIELD_imm6])) - (16); + res->fields_mask[FIELD_imm >> 6] |= 1LL << (FIELD_imm & 63); + } + /* pcode: if esize == 8 then imm = UInt(imm6) - 8 */ + if((res->fields[FIELD_esize]) == (8)) { + res->fields[FIELD_imm] = ((res->fields[FIELD_imm6])) - (8); + res->fields_mask[FIELD_imm >> 6] |= 1LL << (FIELD_imm & 63); + } + /* pcode: fmt_idx = (Q == '1') */ + res->fields[FIELD_fmt_idx] = ((res->fields[FIELD_Q]) == (0x1)); + res->fields_mask[FIELD_fmt_idx >> 6] |= 1LL << (FIELD_fmt_idx & 63); + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: 42AE79E2 +int vsqrt(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + res->group = INSN_GROUP_NEON; + /* Encoding T1 */ + /* pattern="1110,11101,D.1,11,0001,Vd.4,101,sz.1,1,1,M.1,0,Vm.4" width=32 stringency=24 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFFBF0ED0)==0xEEB10AC0)) { + res->instrSize = 32; + if(!(req->arch & ARCH_VFPv2) && !(req->arch & ARCH_VFPv3)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_D] = (instr & 0x400000)>>22; + res->fields_mask[FIELD_D >> 6] |= 1LL << (FIELD_D & 63); + char D_width = 1; + res->fields[FIELD_Vd] = (instr & 0xF000)>>12; + res->fields_mask[FIELD_Vd >> 6] |= 1LL << (FIELD_Vd & 63); + char Vd_width = 4; + res->fields[FIELD_sz] = (instr & 0x100)>>8; + res->fields_mask[FIELD_sz >> 6] |= 1LL << (FIELD_sz & 63); + char sz_width = 1; + res->fields[FIELD_M] = (instr & 0x20)>>5; + res->fields_mask[FIELD_M >> 6] |= 1LL << (FIELD_M & 63); + char M_width = 1; + res->fields[FIELD_Vm] = instr & 0xF; + res->fields_mask[FIELD_Vm >> 6] |= 1LL << (FIELD_Vm & 63); + char Vm_width = 4; + + static const instruction_format instr_formats[] = + { + { /* VSQRT<c>.F32 <Sd>,<Sm> */ + "vsqrt.f32", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_F32, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"s","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_m,FIELD_UNINIT,"s","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + { /* VSQRT<c>.F64 <Dd>,<Dm> */ + "vsqrt.f64", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_F64, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_m,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 2; + res->mnem = armv7::ARMV7_VSQRT; + + /* pcode: dp_operation = (sz == '1') */ + res->fields[FIELD_dp_operation] = ((res->fields[FIELD_sz]) == (0x1)); + res->fields_mask[FIELD_dp_operation >> 6] |= 1LL << (FIELD_dp_operation & 63); + /* pcode: d = if dp_operation then UInt(D:Vd) else UInt(Vd:D) */ + if(res->fields[FIELD_dp_operation]) { + res->fields[FIELD_d] = ((res->fields[FIELD_D]<<Vd_width)|(res->fields[FIELD_Vd])); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + } + else { + res->fields[FIELD_d] = ((res->fields[FIELD_Vd]<<D_width)|(res->fields[FIELD_D])); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + } + /* pcode: m = if dp_operation then UInt(M:Vm) else UInt(Vm:M) */ + if(res->fields[FIELD_dp_operation]) { + res->fields[FIELD_m] = ((res->fields[FIELD_M]<<Vm_width)|(res->fields[FIELD_Vm])); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + } + else { + res->fields[FIELD_m] = ((res->fields[FIELD_Vm]<<M_width)|(res->fields[FIELD_M])); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + } + /* pcode: fmt_idx = dp_operation */ + res->fields[FIELD_fmt_idx] = res->fields[FIELD_dp_operation]; + res->fields_mask[FIELD_fmt_idx >> 6] |= 1LL << (FIELD_fmt_idx & 63); + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: C0CB618D +int vsra(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + res->group = INSN_GROUP_NEON; + /* Encoding T1 */ + /* pattern="111,U.1,1111,1,D.1,imm6.6,Vd.4,0001,L.1,Q.1,M.1,1,Vm.4" width=32 stringency=18 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xEF800F10)==0xEF800110)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ADVSIMD)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_U] = (instr & 0x10000000)>>28; + res->fields_mask[FIELD_U >> 6] |= 1LL << (FIELD_U & 63); + char U_width = 1; + res->fields[FIELD_D] = (instr & 0x400000)>>22; + res->fields_mask[FIELD_D >> 6] |= 1LL << (FIELD_D & 63); + char D_width = 1; + res->fields[FIELD_imm6] = (instr & 0x3F0000)>>16; + res->fields_mask[FIELD_imm6 >> 6] |= 1LL << (FIELD_imm6 & 63); + char imm6_width = 6; + res->fields[FIELD_Vd] = (instr & 0xF000)>>12; + res->fields_mask[FIELD_Vd >> 6] |= 1LL << (FIELD_Vd & 63); + char Vd_width = 4; + res->fields[FIELD_L] = (instr & 0x80)>>7; + res->fields_mask[FIELD_L >> 6] |= 1LL << (FIELD_L & 63); + char L_width = 1; + res->fields[FIELD_Q] = (instr & 0x40)>>6; + res->fields_mask[FIELD_Q >> 6] |= 1LL << (FIELD_Q & 63); + char Q_width = 1; + res->fields[FIELD_M] = (instr & 0x20)>>5; + res->fields_mask[FIELD_M >> 6] |= 1LL << (FIELD_M & 63); + char M_width = 1; + res->fields[FIELD_Vm] = instr & 0xF; + res->fields_mask[FIELD_Vm >> 6] |= 1LL << (FIELD_Vm & 63); + char Vm_width = 4; + + static const instruction_format instr_formats[] = + { + { /* VSRA<c>.<type><size> <Dd>,<Dm>,#<imm> */ + "vsra", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_NEON_TYPE_SIZE|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_m,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_IMM,FIELD_imm,FIELD_UNINIT,"#","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + { /* VSRA<c>.<type><size> <Qd>,<Qm>,#<imm> */ + "vsra", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_NEON_TYPE_SIZE|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"q","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_m,FIELD_UNINIT,"q","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_IMM,FIELD_imm,FIELD_UNINIT,"#","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 2; + res->mnem = armv7::ARMV7_VSRA; + + /* pcode: if (L == '0' && UInt(imm6) < 8) then SEE advsimd_one_reg_mod_imm */ + if((((res->fields[FIELD_L]) == (0x0)) && (((res->fields[FIELD_imm6])) < (8)))) { + + return advsimd_one_reg_mod_imm(req, res); + } + /* pcode: if (Q == '1' && (Vd<0> == '1' || Vm<0> == '1')) then UNDEFINED */ + if((((res->fields[FIELD_Q]) == (0x1)) && (((((res->fields[FIELD_Vd] & 1)) == (0x1)) || (((res->fields[FIELD_Vm] & 1)) == (0x1)))))) { + res->status |= STATUS_UNDEFINED; + } + /* pcode: if UInt(L:imm6) < 128 then esize = 64 */ + if((((res->fields[FIELD_L]<<6)|(res->fields[FIELD_imm6]))) < (128)) { + res->fields[FIELD_esize] = 64; + res->fields_mask[FIELD_esize >> 6] |= 1LL << (FIELD_esize & 63); + } + /* pcode: if UInt(L:imm6) < 64 then esize = 32 */ + if((((res->fields[FIELD_L]<<6)|(res->fields[FIELD_imm6]))) < (64)) { + res->fields[FIELD_esize] = 32; + res->fields_mask[FIELD_esize >> 6] |= 1LL << (FIELD_esize & 63); + } + /* pcode: if UInt(L:imm6) < 32 then esize = 16 */ + if((((res->fields[FIELD_L]<<6)|(res->fields[FIELD_imm6]))) < (32)) { + res->fields[FIELD_esize] = 16; + res->fields_mask[FIELD_esize >> 6] |= 1LL << (FIELD_esize & 63); + } + /* pcode: if UInt(L:imm6) < 16 then esize = 8 */ + if((((res->fields[FIELD_L]<<6)|(res->fields[FIELD_imm6]))) < (16)) { + res->fields[FIELD_esize] = 8; + res->fields_mask[FIELD_esize >> 6] |= 1LL << (FIELD_esize & 63); + } + /* pcode: elements = 64 DIV esize */ + res->fields[FIELD_elements] = ((res->fields[FIELD_esize]) ? ((64) / (res->fields[FIELD_esize])) : 0); + res->fields_mask[FIELD_elements >> 6] |= 1LL << (FIELD_elements & 63); + /* pcode: d = UInt(D:Vd) */ + res->fields[FIELD_d] = ((res->fields[FIELD_D]<<Vd_width)|(res->fields[FIELD_Vd])); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: m = UInt(M:Vm) */ + res->fields[FIELD_m] = ((res->fields[FIELD_M]<<Vm_width)|(res->fields[FIELD_Vm])); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + /* pcode: regs = if Q == '0' then 1 else 2 */ + if((res->fields[FIELD_Q]) == (0x0)) { + res->fields[FIELD_regs] = 1; + res->fields_mask[FIELD_regs >> 6] |= 1LL << (FIELD_regs & 63); + } + else { + res->fields[FIELD_regs] = 2; + res->fields_mask[FIELD_regs >> 6] |= 1LL << (FIELD_regs & 63); + } + /* pcode: imm = imm6 */ + res->fields[FIELD_imm] = res->fields[FIELD_imm6]; + res->fields_mask[FIELD_imm >> 6] |= 1LL << (FIELD_imm & 63); + /* pcode: type = UInt(U) + 2 */ + res->fields[FIELD_type] = ((res->fields[FIELD_U])) + (2); + res->fields_mask[FIELD_type >> 6] |= 1LL << (FIELD_type & 63); + /* pcode: if esize == 64 then size = 2 */ + if((res->fields[FIELD_esize]) == (64)) { + res->fields[FIELD_size] = 2; + res->fields_mask[FIELD_size >> 6] |= 1LL << (FIELD_size & 63); + } + /* pcode: if esize == 32 then size = 1 */ + if((res->fields[FIELD_esize]) == (32)) { + res->fields[FIELD_size] = 1; + res->fields_mask[FIELD_size >> 6] |= 1LL << (FIELD_size & 63); + } + /* pcode: if esize == 16 then size = 0 */ + if((res->fields[FIELD_esize]) == (16)) { + res->fields[FIELD_size] = 0; + res->fields_mask[FIELD_size >> 6] |= 1LL << (FIELD_size & 63); + } + /* pcode: if esize == 8 then size = 3 */ + if((res->fields[FIELD_esize]) == (8)) { + res->fields[FIELD_size] = 3; + res->fields_mask[FIELD_size >> 6] |= 1LL << (FIELD_size & 63); + } + /* pcode: imm = UInt(imm6) */ + res->fields[FIELD_imm] = (res->fields[FIELD_imm6]); + res->fields_mask[FIELD_imm >> 6] |= 1LL << (FIELD_imm & 63); + /* pcode: if esize == 64 then imm = 64 - UInt(imm6) */ + if((res->fields[FIELD_esize]) == (64)) { + res->fields[FIELD_imm] = (64) - ((res->fields[FIELD_imm6])); + res->fields_mask[FIELD_imm >> 6] |= 1LL << (FIELD_imm & 63); + } + /* pcode: if esize == 32 then imm = 64 - UInt(imm6) */ + if((res->fields[FIELD_esize]) == (32)) { + res->fields[FIELD_imm] = (64) - ((res->fields[FIELD_imm6])); + res->fields_mask[FIELD_imm >> 6] |= 1LL << (FIELD_imm & 63); + } + /* pcode: if esize == 16 then imm = 32 - UInt(imm6) */ + if((res->fields[FIELD_esize]) == (16)) { + res->fields[FIELD_imm] = (32) - ((res->fields[FIELD_imm6])); + res->fields_mask[FIELD_imm >> 6] |= 1LL << (FIELD_imm & 63); + } + /* pcode: if esize == 8 then imm = 16 - UInt(imm6) */ + if((res->fields[FIELD_esize]) == (8)) { + res->fields[FIELD_imm] = (16) - ((res->fields[FIELD_imm6])); + res->fields_mask[FIELD_imm >> 6] |= 1LL << (FIELD_imm & 63); + } + /* pcode: fmt_idx = (Q == '1') */ + res->fields[FIELD_fmt_idx] = ((res->fields[FIELD_Q]) == (0x1)); + res->fields_mask[FIELD_fmt_idx >> 6] |= 1LL << (FIELD_fmt_idx & 63); + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: 191E29CF +int vsri(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + res->group = INSN_GROUP_NEON; + /* Encoding T1 */ + /* pattern="1111,xx11,1,D.1,imm6.6,Vd.4,0100,L.1,Q.1,M.1,1,Vm.4" width=32 stringency=16 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xF3800F10)==0xF3800410)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ADVSIMD)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_D] = (instr & 0x400000)>>22; + res->fields_mask[FIELD_D >> 6] |= 1LL << (FIELD_D & 63); + char D_width = 1; + res->fields[FIELD_imm6] = (instr & 0x3F0000)>>16; + res->fields_mask[FIELD_imm6 >> 6] |= 1LL << (FIELD_imm6 & 63); + char imm6_width = 6; + res->fields[FIELD_Vd] = (instr & 0xF000)>>12; + res->fields_mask[FIELD_Vd >> 6] |= 1LL << (FIELD_Vd & 63); + char Vd_width = 4; + res->fields[FIELD_L] = (instr & 0x80)>>7; + res->fields_mask[FIELD_L >> 6] |= 1LL << (FIELD_L & 63); + char L_width = 1; + res->fields[FIELD_Q] = (instr & 0x40)>>6; + res->fields_mask[FIELD_Q >> 6] |= 1LL << (FIELD_Q & 63); + char Q_width = 1; + res->fields[FIELD_M] = (instr & 0x20)>>5; + res->fields_mask[FIELD_M >> 6] |= 1LL << (FIELD_M & 63); + char M_width = 1; + res->fields[FIELD_Vm] = instr & 0xF; + res->fields_mask[FIELD_Vm >> 6] |= 1LL << (FIELD_Vm & 63); + char Vm_width = 4; + + static const instruction_format instr_formats[] = + { + { /* VSRI<c>.<size> <Dd>,<Dm>,#<imm> */ + "vsri", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_NEON_SIZE, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_m,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_IMM,FIELD_imm,FIELD_UNINIT,"#","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + { /* VSRI<c>.<size> <Qd>,<Qm>,#<imm> */ + "vsri", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_NEON_SIZE, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"q","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_m,FIELD_UNINIT,"q","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_IMM,FIELD_imm,FIELD_UNINIT,"#","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 2; + res->mnem = armv7::ARMV7_VSRI; + + /* pcode: if (L == '0' && UInt(imm6) < 8) then SEE advsimd_one_reg_mod_imm */ + if((((res->fields[FIELD_L]) == (0x0)) && (((res->fields[FIELD_imm6])) < (8)))) { + + return advsimd_one_reg_mod_imm(req, res); + } + /* pcode: if (Q == '1' && (Vd<0> == '1' || Vm<0> == '1')) then UNDEFINED */ + if((((res->fields[FIELD_Q]) == (0x1)) && (((((res->fields[FIELD_Vd] & 1)) == (0x1)) || (((res->fields[FIELD_Vm] & 1)) == (0x1)))))) { + res->status |= STATUS_UNDEFINED; + } + /* pcode: if UInt(L:imm6) < 128 then esize = 64 */ + if((((res->fields[FIELD_L]<<6)|(res->fields[FIELD_imm6]))) < (128)) { + res->fields[FIELD_esize] = 64; + res->fields_mask[FIELD_esize >> 6] |= 1LL << (FIELD_esize & 63); + } + /* pcode: if UInt(L:imm6) < 64 then esize = 32 */ + if((((res->fields[FIELD_L]<<6)|(res->fields[FIELD_imm6]))) < (64)) { + res->fields[FIELD_esize] = 32; + res->fields_mask[FIELD_esize >> 6] |= 1LL << (FIELD_esize & 63); + } + /* pcode: if UInt(L:imm6) < 32 then esize = 16 */ + if((((res->fields[FIELD_L]<<6)|(res->fields[FIELD_imm6]))) < (32)) { + res->fields[FIELD_esize] = 16; + res->fields_mask[FIELD_esize >> 6] |= 1LL << (FIELD_esize & 63); + } + /* pcode: if UInt(L:imm6) < 16 then esize = 8 */ + if((((res->fields[FIELD_L]<<6)|(res->fields[FIELD_imm6]))) < (16)) { + res->fields[FIELD_esize] = 8; + res->fields_mask[FIELD_esize >> 6] |= 1LL << (FIELD_esize & 63); + } + /* pcode: elements = 64 DIV esize */ + res->fields[FIELD_elements] = ((res->fields[FIELD_esize]) ? ((64) / (res->fields[FIELD_esize])) : 0); + res->fields_mask[FIELD_elements >> 6] |= 1LL << (FIELD_elements & 63); + /* pcode: d = UInt(D:Vd) */ + res->fields[FIELD_d] = ((res->fields[FIELD_D]<<Vd_width)|(res->fields[FIELD_Vd])); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: m = UInt(M:Vm) */ + res->fields[FIELD_m] = ((res->fields[FIELD_M]<<Vm_width)|(res->fields[FIELD_Vm])); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + /* pcode: regs = if Q == '0' then 1 else 2 */ + if((res->fields[FIELD_Q]) == (0x0)) { + res->fields[FIELD_regs] = 1; + res->fields_mask[FIELD_regs >> 6] |= 1LL << (FIELD_regs & 63); + } + else { + res->fields[FIELD_regs] = 2; + res->fields_mask[FIELD_regs >> 6] |= 1LL << (FIELD_regs & 63); + } + /* pcode: imm = imm6 */ + res->fields[FIELD_imm] = res->fields[FIELD_imm6]; + res->fields_mask[FIELD_imm >> 6] |= 1LL << (FIELD_imm & 63); + /* pcode: if esize == 64 then size = 3 */ + if((res->fields[FIELD_esize]) == (64)) { + res->fields[FIELD_size] = 3; + res->fields_mask[FIELD_size >> 6] |= 1LL << (FIELD_size & 63); + } + /* pcode: if esize == 32 then size = 2 */ + if((res->fields[FIELD_esize]) == (32)) { + res->fields[FIELD_size] = 2; + res->fields_mask[FIELD_size >> 6] |= 1LL << (FIELD_size & 63); + } + /* pcode: if esize == 16 then size = 1 */ + if((res->fields[FIELD_esize]) == (16)) { + res->fields[FIELD_size] = 1; + res->fields_mask[FIELD_size >> 6] |= 1LL << (FIELD_size & 63); + } + /* pcode: if esize == 8 then size = 0 */ + if((res->fields[FIELD_esize]) == (8)) { + res->fields[FIELD_size] = 0; + res->fields_mask[FIELD_size >> 6] |= 1LL << (FIELD_size & 63); + } + /* pcode: imm = UInt(imm6) */ + res->fields[FIELD_imm] = (res->fields[FIELD_imm6]); + res->fields_mask[FIELD_imm >> 6] |= 1LL << (FIELD_imm & 63); + /* pcode: if esize == 64 then imm = 64 - UInt(imm6) */ + if((res->fields[FIELD_esize]) == (64)) { + res->fields[FIELD_imm] = (64) - ((res->fields[FIELD_imm6])); + res->fields_mask[FIELD_imm >> 6] |= 1LL << (FIELD_imm & 63); + } + /* pcode: if esize == 32 then imm = 64 - UInt(imm6) */ + if((res->fields[FIELD_esize]) == (32)) { + res->fields[FIELD_imm] = (64) - ((res->fields[FIELD_imm6])); + res->fields_mask[FIELD_imm >> 6] |= 1LL << (FIELD_imm & 63); + } + /* pcode: if esize == 16 then imm = 32 -UInt(imm6) */ + if((res->fields[FIELD_esize]) == (16)) { + res->fields[FIELD_imm] = (32) - ((res->fields[FIELD_imm6])); + res->fields_mask[FIELD_imm >> 6] |= 1LL << (FIELD_imm & 63); + } + /* pcode: if esize == 8 then imm = 16 - UInt(imm6) */ + if((res->fields[FIELD_esize]) == (8)) { + res->fields[FIELD_imm] = (16) - ((res->fields[FIELD_imm6])); + res->fields_mask[FIELD_imm >> 6] |= 1LL << (FIELD_imm & 63); + } + /* pcode: fmt_idx = (Q == '1') */ + res->fields[FIELD_fmt_idx] = ((res->fields[FIELD_Q]) == (0x1)); + res->fields_mask[FIELD_fmt_idx >> 6] |= 1LL << (FIELD_fmt_idx & 63); + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: DFF3E84B +int vst1_mult_1elem(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + res->group = INSN_GROUP_NEON; + /* Encoding T1 */ + /* pattern="1111,1001,0,D.1,00,Rn.4,Vd.4,type.4,size.2,align.2,Rm.4" width=32 stringency=12 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFFB00000)==0xF9000000)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ADVSIMD)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_D] = (instr & 0x400000)>>22; + res->fields_mask[FIELD_D >> 6] |= 1LL << (FIELD_D & 63); + char D_width = 1; + res->fields[FIELD_Rn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Rn >> 6] |= 1LL << (FIELD_Rn & 63); + char Rn_width = 4; + res->fields[FIELD_Vd] = (instr & 0xF000)>>12; + res->fields_mask[FIELD_Vd >> 6] |= 1LL << (FIELD_Vd & 63); + char Vd_width = 4; + res->fields[FIELD_type] = (instr & 0xF00)>>8; + res->fields_mask[FIELD_type >> 6] |= 1LL << (FIELD_type & 63); + char type_width = 4; + res->fields[FIELD_size] = (instr & 0xC0)>>6; + res->fields_mask[FIELD_size >> 6] |= 1LL << (FIELD_size & 63); + char size_width = 2; + res->fields[FIELD_align] = (instr & 0x30)>>4; + res->fields_mask[FIELD_align >> 6] |= 1LL << (FIELD_align & 63); + char align_width = 2; + res->fields[FIELD_Rm] = instr & 0xF; + res->fields_mask[FIELD_Rm >> 6] |= 1LL << (FIELD_Rm & 63); + char Rm_width = 4; + + static const instruction_format instr_formats[] = + { + { /* VST1<c>.<size> <registers>,[<Rn>,#<align>] */ + "vst1", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_NEON_SIZE, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REGISTERS,FIELD_registers,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_MEMORY_ONE_REG_ALIGNED,FIELD_Rn,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + { /* VST1<c>.<size> <registers>,[<Rn>,#<align>]! */ + "vst1", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_NEON_SIZE, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REGISTERS,FIELD_registers,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_MEMORY_ONE_REG_ALIGNED,FIELD_Rn,FIELD_UNINIT,"","",WRITEBACK_YES}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + { /* VST1<c>.<size> <registers>,[<Rn>,#<align>],<Rm> */ + "vst1", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_NEON_SIZE, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REGISTERS,FIELD_registers,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_MEMORY_ONE_REG_ALIGNED,FIELD_Rn,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rm,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 3; + res->mnem = armv7::ARMV7_VST1; + + /* pcode: case type of */ + /* pcode: when '0111' */ + if(res->fields[FIELD_type] == 0x7) { + /* pcode: regs = 1 */ + res->fields[FIELD_regs] = 1; + res->fields_mask[FIELD_regs >> 6] |= 1LL << (FIELD_regs & 63); + /* pcode: if align<1> == '1' then UNDEFINED */ + if((((res->fields[FIELD_align] >> 1) & 1)) == (0x1)) { + res->status |= STATUS_UNDEFINED; + } + } + /* pcode: when '1010' */ + else + if(res->fields[FIELD_type] == 0xA) { + /* pcode: regs = 2 */ + res->fields[FIELD_regs] = 2; + res->fields_mask[FIELD_regs >> 6] |= 1LL << (FIELD_regs & 63); + /* pcode: if align == '11' then UNDEFINED */ + if((res->fields[FIELD_align]) == (0x3)) { + res->status |= STATUS_UNDEFINED; + } + } + /* pcode: when '0110' */ + else + if(res->fields[FIELD_type] == 0x6) { + /* pcode: regs = 3 */ + res->fields[FIELD_regs] = 3; + res->fields_mask[FIELD_regs >> 6] |= 1LL << (FIELD_regs & 63); + /* pcode: if align<1> == '1' then UNDEFINED */ + if((((res->fields[FIELD_align] >> 1) & 1)) == (0x1)) { + res->status |= STATUS_UNDEFINED; + } + } + /* pcode: when '0010' */ + else + if(res->fields[FIELD_type] == 0x2) { + /* pcode: regs = 4 */ + res->fields[FIELD_regs] = 4; + res->fields_mask[FIELD_regs >> 6] |= 1LL << (FIELD_regs & 63); + } + /* pcode: alignment = if align == '00' then 1 else 64 << UInt(align-1) */ + if((res->fields[FIELD_align]) == (0x0)) { + res->fields[FIELD_alignment] = 1; + res->fields_mask[FIELD_alignment >> 6] |= 1LL << (FIELD_alignment & 63); + } + else { + res->fields[FIELD_alignment] = (64) << (((res->fields[FIELD_align]) - (1))); + res->fields_mask[FIELD_alignment >> 6] |= 1LL << (FIELD_alignment & 63); + } + /* pcode: ebytes = 1 << UInt(size) */ + res->fields[FIELD_ebytes] = (1) << ((res->fields[FIELD_size])); + res->fields_mask[FIELD_ebytes >> 6] |= 1LL << (FIELD_ebytes & 63); + /* pcode: esize = 8 * ebytes */ + res->fields[FIELD_esize] = (8) * (res->fields[FIELD_ebytes]); + res->fields_mask[FIELD_esize >> 6] |= 1LL << (FIELD_esize & 63); + /* pcode: elements = 8 / ebytes */ + res->fields[FIELD_elements] = ((res->fields[FIELD_ebytes]) ? ((8) / (res->fields[FIELD_ebytes])) : 0); + res->fields_mask[FIELD_elements >> 6] |= 1LL << (FIELD_elements & 63); + /* pcode: d = UInt(D:Vd) */ + res->fields[FIELD_d] = ((res->fields[FIELD_D]<<Vd_width)|(res->fields[FIELD_Vd])); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: n = UInt(Rn) */ + res->fields[FIELD_n] = (res->fields[FIELD_Rn]); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: m = UInt(Rm) */ + res->fields[FIELD_m] = (res->fields[FIELD_Rm]); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + /* pcode: wback = (m != 15) */ + res->fields[FIELD_wback] = ((res->fields[FIELD_m]) != (15)); + res->fields_mask[FIELD_wback >> 6] |= 1LL << (FIELD_wback & 63); + /* pcode: register_index = (m != 15 && m != 13) */ + res->fields[FIELD_register_index] = (((res->fields[FIELD_m]) != (15)) && ((res->fields[FIELD_m]) != (13))); + res->fields_mask[FIELD_register_index >> 6] |= 1LL << (FIELD_register_index & 63); + /* pcode: if d+regs > 32 then UNPREDICTABLE */ + if((res->fields[FIELD_d]) + ((res->fields[FIELD_regs]) > (32))) { + res->flags |= FLAG_UNPREDICTABLE; + } + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: E24E8A78 +int vst1_single_1elem(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + res->group = INSN_GROUP_NEON; + /* Encoding T1 */ + /* pattern="1111,1001,1,D.1,00,Rn.4,Vd.4,size.2,00,index_align.4,Rm.4" width=32 stringency=14 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFFB00300)==0xF9800000)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ADVSIMD)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_D] = (instr & 0x400000)>>22; + res->fields_mask[FIELD_D >> 6] |= 1LL << (FIELD_D & 63); + char D_width = 1; + res->fields[FIELD_Rn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Rn >> 6] |= 1LL << (FIELD_Rn & 63); + char Rn_width = 4; + res->fields[FIELD_Vd] = (instr & 0xF000)>>12; + res->fields_mask[FIELD_Vd >> 6] |= 1LL << (FIELD_Vd & 63); + char Vd_width = 4; + res->fields[FIELD_size] = (instr & 0xC00)>>10; + res->fields_mask[FIELD_size >> 6] |= 1LL << (FIELD_size & 63); + char size_width = 2; + res->fields[FIELD_index_align] = (instr & 0xF0)>>4; + res->fields_mask[FIELD_index_align >> 6] |= 1LL << (FIELD_index_align & 63); + char index_align_width = 4; + res->fields[FIELD_Rm] = instr & 0xF; + res->fields_mask[FIELD_Rm >> 6] |= 1LL << (FIELD_Rm & 63); + char Rm_width = 4; + + static const instruction_format instr_formats[] = + { + { /* VST1<c>.<size> <registers_indexed>,[<Rn>,#<align>] */ + "vst1", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_NEON_SIZE, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REGISTERS_INDEXED,FIELD_registers_indexed,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_MEMORY_ONE_REG_ALIGNED,FIELD_Rn,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + { /* VST1<c>.<size> <registers_indexed>,[<Rn>,#<align>]! */ + "vst1", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_NEON_SIZE, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REGISTERS_INDEXED,FIELD_registers_indexed,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_MEMORY_ONE_REG_ALIGNED,FIELD_Rn,FIELD_UNINIT,"","",WRITEBACK_YES}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + { /* VST1<c>.<size> <registers_indexed>,[<Rn>,#<align>],<Rm> */ + "vst1", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_NEON_SIZE, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REGISTERS_INDEXED,FIELD_registers_indexed,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_MEMORY_ONE_REG_ALIGNED,FIELD_Rn,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rm,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 3; + res->mnem = armv7::ARMV7_VST1; + + /* pcode: if size=='11' then UNDEFINED */ + if((res->fields[FIELD_size]) == (0x3)) { + res->status |= STATUS_UNDEFINED; + } + /* pcode: case size of */ + /* pcode: when '00' */ + if(res->fields[FIELD_size] == 0x0) { + /* pcode: if index_align<0> != '0' then UNDEFINED */ + if(((res->fields[FIELD_index_align] & 1)) != (0x0)) { + res->status |= STATUS_UNDEFINED; + } + /* pcode: ebytes = 1 */ + res->fields[FIELD_ebytes] = 1; + res->fields_mask[FIELD_ebytes >> 6] |= 1LL << (FIELD_ebytes & 63); + /* pcode: esize = 8 */ + res->fields[FIELD_esize] = 8; + res->fields_mask[FIELD_esize >> 6] |= 1LL << (FIELD_esize & 63); + /* pcode: index = UInt(index_align<3:1>) */ + res->fields[FIELD_index] = (((res->fields[FIELD_index_align] >> 1) & 0x7)); + res->fields_mask[FIELD_index >> 6] |= 1LL << (FIELD_index & 63); + /* pcode: alignment = 1 */ + res->fields[FIELD_alignment] = 1; + res->fields_mask[FIELD_alignment >> 6] |= 1LL << (FIELD_alignment & 63); + } + /* pcode: when '01' */ + else + if(res->fields[FIELD_size] == 0x1) { + /* pcode: if index_align<1> != '0' then UNDEFINED */ + if((((res->fields[FIELD_index_align] >> 1) & 1)) != (0x0)) { + res->status |= STATUS_UNDEFINED; + } + /* pcode: ebytes = 2 */ + res->fields[FIELD_ebytes] = 2; + res->fields_mask[FIELD_ebytes >> 6] |= 1LL << (FIELD_ebytes & 63); + /* pcode: esize = 16 */ + res->fields[FIELD_esize] = 16; + res->fields_mask[FIELD_esize >> 6] |= 1LL << (FIELD_esize & 63); + /* pcode: index = UInt(index_align<3:2>) */ + res->fields[FIELD_index] = (((res->fields[FIELD_index_align] >> 2) & 0x3)); + res->fields_mask[FIELD_index >> 6] |= 1LL << (FIELD_index & 63); + /* pcode: alignment = if index_align<0> == '0' then 1 else 16 */ + if(((res->fields[FIELD_index_align] & 1)) == (0x0)) { + res->fields[FIELD_alignment] = 1; + res->fields_mask[FIELD_alignment >> 6] |= 1LL << (FIELD_alignment & 63); + } + else { + res->fields[FIELD_alignment] = 16; + res->fields_mask[FIELD_alignment >> 6] |= 1LL << (FIELD_alignment & 63); + } + } + /* pcode: when '10' */ + else + if(res->fields[FIELD_size] == 0x2) { + /* pcode: if index_align<2> != '0' then UNDEFINED */ + if((((res->fields[FIELD_index_align] >> 2) & 1)) != (0x0)) { + res->status |= STATUS_UNDEFINED; + } + /* pcode: if index_align<1:0> != '00' && index_align<1:0> != '11' then UNDEFINED */ + if((((res->fields[FIELD_index_align] & 0x3)) != (0x0)) && (((res->fields[FIELD_index_align] & 0x3)) != (0x3))) { + res->status |= STATUS_UNDEFINED; + } + /* pcode: ebytes = 4 */ + res->fields[FIELD_ebytes] = 4; + res->fields_mask[FIELD_ebytes >> 6] |= 1LL << (FIELD_ebytes & 63); + /* pcode: esize = 32 */ + res->fields[FIELD_esize] = 32; + res->fields_mask[FIELD_esize >> 6] |= 1LL << (FIELD_esize & 63); + /* pcode: index = UInt(index_align<3>) */ + res->fields[FIELD_index] = (((res->fields[FIELD_index_align] >> 3) & 1)); + res->fields_mask[FIELD_index >> 6] |= 1LL << (FIELD_index & 63); + /* pcode: alignment = if index_align<1:0> == '00' then 1 else 32 */ + if(((res->fields[FIELD_index_align] & 0x3)) == (0x0)) { + res->fields[FIELD_alignment] = 1; + res->fields_mask[FIELD_alignment >> 6] |= 1LL << (FIELD_alignment & 63); + } + else { + res->fields[FIELD_alignment] = 32; + res->fields_mask[FIELD_alignment >> 6] |= 1LL << (FIELD_alignment & 63); + } + } + /* pcode: d = UInt(D:Vd) */ + res->fields[FIELD_d] = ((res->fields[FIELD_D]<<Vd_width)|(res->fields[FIELD_Vd])); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: n = UInt(Rn) */ + res->fields[FIELD_n] = (res->fields[FIELD_Rn]); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: m = UInt(Rm) */ + res->fields[FIELD_m] = (res->fields[FIELD_Rm]); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + /* pcode: wback = (m != 15) */ + res->fields[FIELD_wback] = ((res->fields[FIELD_m]) != (15)); + res->fields_mask[FIELD_wback >> 6] |= 1LL << (FIELD_wback & 63); + /* pcode: register_index = (m != 15 && m != 13) */ + res->fields[FIELD_register_index] = (((res->fields[FIELD_m]) != (15)) && ((res->fields[FIELD_m]) != (13))); + res->fields_mask[FIELD_register_index >> 6] |= 1LL << (FIELD_register_index & 63); + /* pcode: length = 1 */ + res->fields[FIELD_length] = 1; + res->fields_mask[FIELD_length >> 6] |= 1LL << (FIELD_length & 63); + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: 834F7C1E +int vst2_mult_2elem(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + res->group = INSN_GROUP_NEON; + /* Encoding T1 */ + /* pattern="1111,1001,0,D.1,00,Rn.4,Vd.4,type.4,size.2,align.2,Rm.4" width=32 stringency=12 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFFB00000)==0xF9000000)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ADVSIMD)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_D] = (instr & 0x400000)>>22; + res->fields_mask[FIELD_D >> 6] |= 1LL << (FIELD_D & 63); + char D_width = 1; + res->fields[FIELD_Rn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Rn >> 6] |= 1LL << (FIELD_Rn & 63); + char Rn_width = 4; + res->fields[FIELD_Vd] = (instr & 0xF000)>>12; + res->fields_mask[FIELD_Vd >> 6] |= 1LL << (FIELD_Vd & 63); + char Vd_width = 4; + res->fields[FIELD_type] = (instr & 0xF00)>>8; + res->fields_mask[FIELD_type >> 6] |= 1LL << (FIELD_type & 63); + char type_width = 4; + res->fields[FIELD_size] = (instr & 0xC0)>>6; + res->fields_mask[FIELD_size >> 6] |= 1LL << (FIELD_size & 63); + char size_width = 2; + res->fields[FIELD_align] = (instr & 0x30)>>4; + res->fields_mask[FIELD_align >> 6] |= 1LL << (FIELD_align & 63); + char align_width = 2; + res->fields[FIELD_Rm] = instr & 0xF; + res->fields_mask[FIELD_Rm >> 6] |= 1LL << (FIELD_Rm & 63); + char Rm_width = 4; + + static const instruction_format instr_formats[] = + { + { /* VST2<c>.<size> <registers>,[<Rn>,#<align>] */ + "vst2", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_NEON_SIZE, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REGISTERS,FIELD_registers,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_MEMORY_ONE_REG_ALIGNED,FIELD_Rn,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + { /* VST2<c>.<size> <registers>,[<Rn>,#<align>]! */ + "vst2", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_NEON_SIZE, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REGISTERS,FIELD_registers,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_MEMORY_ONE_REG_ALIGNED,FIELD_Rn,FIELD_UNINIT,"","",WRITEBACK_YES}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + { /* VST2<c>.<size> <registers>,[<Rn>,#<align>],<Rm> */ + "vst2", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_NEON_SIZE, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REGISTERS,FIELD_registers,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_MEMORY_ONE_REG_ALIGNED,FIELD_Rn,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rm,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 3; + res->mnem = armv7::ARMV7_VST2; + + /* pcode: if size == '11' then UNDEFINED */ + if((res->fields[FIELD_size]) == (0x3)) { + res->status |= STATUS_UNDEFINED; + } + /* pcode: case type of */ + /* pcode: when '1000' */ + if(res->fields[FIELD_type] == 0x8) { + /* pcode: regs = 2 */ + res->fields[FIELD_regs] = 2; + res->fields_mask[FIELD_regs >> 6] |= 1LL << (FIELD_regs & 63); + /* pcode: inc = 1 */ + res->fields[FIELD_inc] = 1; + res->fields_mask[FIELD_inc >> 6] |= 1LL << (FIELD_inc & 63); + /* pcode: if align == '11' then UNDEFINED */ + if((res->fields[FIELD_align]) == (0x3)) { + res->status |= STATUS_UNDEFINED; + } + } + /* pcode: when '1001' */ + else + if(res->fields[FIELD_type] == 0x9) { + /* pcode: regs = 2 */ + res->fields[FIELD_regs] = 2; + res->fields_mask[FIELD_regs >> 6] |= 1LL << (FIELD_regs & 63); + /* pcode: inc = 2 */ + res->fields[FIELD_inc] = 2; + res->fields_mask[FIELD_inc >> 6] |= 1LL << (FIELD_inc & 63); + /* pcode: if align == '11' then UNDEFINED */ + if((res->fields[FIELD_align]) == (0x3)) { + res->status |= STATUS_UNDEFINED; + } + } + /* pcode: when '0011' */ + else + if(res->fields[FIELD_type] == 0x3) { + /* pcode: regs = 4 */ + res->fields[FIELD_regs] = 4; + res->fields_mask[FIELD_regs >> 6] |= 1LL << (FIELD_regs & 63); + /* pcode: inc = 1 */ + res->fields[FIELD_inc] = 1; + res->fields_mask[FIELD_inc >> 6] |= 1LL << (FIELD_inc & 63); + } + /* pcode: alignment = if align == '00' then 1 else 64 << UInt(align-1) */ + if((res->fields[FIELD_align]) == (0x0)) { + res->fields[FIELD_alignment] = 1; + res->fields_mask[FIELD_alignment >> 6] |= 1LL << (FIELD_alignment & 63); + } + else { + res->fields[FIELD_alignment] = (64) << (((res->fields[FIELD_align]) - (1))); + res->fields_mask[FIELD_alignment >> 6] |= 1LL << (FIELD_alignment & 63); + } + /* pcode: ebytes = 1 << UInt(size) */ + res->fields[FIELD_ebytes] = (1) << ((res->fields[FIELD_size])); + res->fields_mask[FIELD_ebytes >> 6] |= 1LL << (FIELD_ebytes & 63); + /* pcode: esize = 8*ebytes */ + res->fields[FIELD_esize] = (8) * (res->fields[FIELD_ebytes]); + res->fields_mask[FIELD_esize >> 6] |= 1LL << (FIELD_esize & 63); + /* pcode: elements = 8 / ebytes */ + res->fields[FIELD_elements] = ((res->fields[FIELD_ebytes]) ? ((8) / (res->fields[FIELD_ebytes])) : 0); + res->fields_mask[FIELD_elements >> 6] |= 1LL << (FIELD_elements & 63); + /* pcode: d = UInt(D:Vd) */ + res->fields[FIELD_d] = ((res->fields[FIELD_D]<<Vd_width)|(res->fields[FIELD_Vd])); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: d2 = d + inc */ + res->fields[FIELD_d2] = (res->fields[FIELD_d]) + (res->fields[FIELD_inc]); + res->fields_mask[FIELD_d2 >> 6] |= 1LL << (FIELD_d2 & 63); + /* pcode: n = UInt(Rn) */ + res->fields[FIELD_n] = (res->fields[FIELD_Rn]); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: m = UInt(Rm) */ + res->fields[FIELD_m] = (res->fields[FIELD_Rm]); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + /* pcode: wback = (m != 15) */ + res->fields[FIELD_wback] = ((res->fields[FIELD_m]) != (15)); + res->fields_mask[FIELD_wback >> 6] |= 1LL << (FIELD_wback & 63); + /* pcode: register_index = (m != 15 && m != 13) */ + res->fields[FIELD_register_index] = (((res->fields[FIELD_m]) != (15)) && ((res->fields[FIELD_m]) != (13))); + res->fields_mask[FIELD_register_index >> 6] |= 1LL << (FIELD_register_index & 63); + /* pcode: if d2+regs > 32 then UNPREDICTABLE */ + if((res->fields[FIELD_d2]) + ((res->fields[FIELD_regs]) > (32))) { + res->flags |= FLAG_UNPREDICTABLE; + } + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: F34BE769 +int vst2_single_2elem(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + res->group = INSN_GROUP_NEON; + /* Encoding T1 */ + /* pattern="1111,1001,1,D.1,00,Rn.4,Vd.4,size.2,01,index_align.4,Rm.4" width=32 stringency=14 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFFB00300)==0xF9800100)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ADVSIMD)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_D] = (instr & 0x400000)>>22; + res->fields_mask[FIELD_D >> 6] |= 1LL << (FIELD_D & 63); + char D_width = 1; + res->fields[FIELD_Rn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Rn >> 6] |= 1LL << (FIELD_Rn & 63); + char Rn_width = 4; + res->fields[FIELD_Vd] = (instr & 0xF000)>>12; + res->fields_mask[FIELD_Vd >> 6] |= 1LL << (FIELD_Vd & 63); + char Vd_width = 4; + res->fields[FIELD_size] = (instr & 0xC00)>>10; + res->fields_mask[FIELD_size >> 6] |= 1LL << (FIELD_size & 63); + char size_width = 2; + res->fields[FIELD_index_align] = (instr & 0xF0)>>4; + res->fields_mask[FIELD_index_align >> 6] |= 1LL << (FIELD_index_align & 63); + char index_align_width = 4; + res->fields[FIELD_Rm] = instr & 0xF; + res->fields_mask[FIELD_Rm >> 6] |= 1LL << (FIELD_Rm & 63); + char Rm_width = 4; + + static const instruction_format instr_formats[] = + { + { /* VST2<c>.<size> <registers_indexed>,[<Rn>,#<align>] */ + "vst2", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_NEON_SIZE, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REGISTERS_INDEXED,FIELD_registers_indexed,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_MEMORY_ONE_REG_ALIGNED,FIELD_Rn,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + { /* VST2<c>.<size> <registers_indexed>,[<Rn>,#<align>]! */ + "vst2", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_NEON_SIZE, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REGISTERS_INDEXED,FIELD_registers_indexed,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_MEMORY_ONE_REG_ALIGNED,FIELD_Rn,FIELD_UNINIT,"","",WRITEBACK_YES}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + { /* VST2<c>.<size> <registers_indexed>,[<Rn>,#<align>],<Rm> */ + "vst2", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_NEON_SIZE, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REGISTERS_INDEXED,FIELD_registers_indexed,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_MEMORY_ONE_REG_ALIGNED,FIELD_Rn,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rm,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 3; + res->mnem = armv7::ARMV7_VST2; + + /* pcode: if size == '11' then UNDEFINED */ + if((res->fields[FIELD_size]) == (0x3)) { + res->status |= STATUS_UNDEFINED; + } + /* pcode: case size of */ + /* pcode: when '00' */ + if(res->fields[FIELD_size] == 0x0) { + /* pcode: ebytes = 1 */ + res->fields[FIELD_ebytes] = 1; + res->fields_mask[FIELD_ebytes >> 6] |= 1LL << (FIELD_ebytes & 63); + /* pcode: esize = 8 */ + res->fields[FIELD_esize] = 8; + res->fields_mask[FIELD_esize >> 6] |= 1LL << (FIELD_esize & 63); + /* pcode: index = UInt(index_align<3:1>) */ + res->fields[FIELD_index] = (((res->fields[FIELD_index_align] >> 1) & 0x7)); + res->fields_mask[FIELD_index >> 6] |= 1LL << (FIELD_index & 63); + /* pcode: inc = 1 */ + res->fields[FIELD_inc] = 1; + res->fields_mask[FIELD_inc >> 6] |= 1LL << (FIELD_inc & 63); + /* pcode: alignment = if index_align<0> == '0' then 1 else 16 */ + if(((res->fields[FIELD_index_align] & 1)) == (0x0)) { + res->fields[FIELD_alignment] = 1; + res->fields_mask[FIELD_alignment >> 6] |= 1LL << (FIELD_alignment & 63); + } + else { + res->fields[FIELD_alignment] = 16; + res->fields_mask[FIELD_alignment >> 6] |= 1LL << (FIELD_alignment & 63); + } + } + /* pcode: when '01' */ + else + if(res->fields[FIELD_size] == 0x1) { + /* pcode: ebytes = 2 */ + res->fields[FIELD_ebytes] = 2; + res->fields_mask[FIELD_ebytes >> 6] |= 1LL << (FIELD_ebytes & 63); + /* pcode: esize = 16 */ + res->fields[FIELD_esize] = 16; + res->fields_mask[FIELD_esize >> 6] |= 1LL << (FIELD_esize & 63); + /* pcode: index = UInt(index_align<3:2>) */ + res->fields[FIELD_index] = (((res->fields[FIELD_index_align] >> 2) & 0x3)); + res->fields_mask[FIELD_index >> 6] |= 1LL << (FIELD_index & 63); + /* pcode: inc = if index_align<1> == '0' then 1 else 2 */ + if((((res->fields[FIELD_index_align] >> 1) & 1)) == (0x0)) { + res->fields[FIELD_inc] = 1; + res->fields_mask[FIELD_inc >> 6] |= 1LL << (FIELD_inc & 63); + } + else { + res->fields[FIELD_inc] = 2; + res->fields_mask[FIELD_inc >> 6] |= 1LL << (FIELD_inc & 63); + } + /* pcode: alignment = if index_align<0> == '0' then 1 else 32 */ + if(((res->fields[FIELD_index_align] & 1)) == (0x0)) { + res->fields[FIELD_alignment] = 1; + res->fields_mask[FIELD_alignment >> 6] |= 1LL << (FIELD_alignment & 63); + } + else { + res->fields[FIELD_alignment] = 32; + res->fields_mask[FIELD_alignment >> 6] |= 1LL << (FIELD_alignment & 63); + } + } + /* pcode: when '10' */ + else + if(res->fields[FIELD_size] == 0x2) { + /* pcode: if index_align<1> != '0' then UNDEFINED */ + if((((res->fields[FIELD_index_align] >> 1) & 1)) != (0x0)) { + res->status |= STATUS_UNDEFINED; + } + /* pcode: ebytes = 4 */ + res->fields[FIELD_ebytes] = 4; + res->fields_mask[FIELD_ebytes >> 6] |= 1LL << (FIELD_ebytes & 63); + /* pcode: esize = 32 */ + res->fields[FIELD_esize] = 32; + res->fields_mask[FIELD_esize >> 6] |= 1LL << (FIELD_esize & 63); + /* pcode: index = UInt(index_align<3>) */ + res->fields[FIELD_index] = (((res->fields[FIELD_index_align] >> 3) & 1)); + res->fields_mask[FIELD_index >> 6] |= 1LL << (FIELD_index & 63); + /* pcode: inc = if index_align<2> == '0' then 1 else 2 */ + if((((res->fields[FIELD_index_align] >> 2) & 1)) == (0x0)) { + res->fields[FIELD_inc] = 1; + res->fields_mask[FIELD_inc >> 6] |= 1LL << (FIELD_inc & 63); + } + else { + res->fields[FIELD_inc] = 2; + res->fields_mask[FIELD_inc >> 6] |= 1LL << (FIELD_inc & 63); + } + /* pcode: alignment = if index_align<0> == '0' then 1 else 64 */ + if(((res->fields[FIELD_index_align] & 1)) == (0x0)) { + res->fields[FIELD_alignment] = 1; + res->fields_mask[FIELD_alignment >> 6] |= 1LL << (FIELD_alignment & 63); + } + else { + res->fields[FIELD_alignment] = 64; + res->fields_mask[FIELD_alignment >> 6] |= 1LL << (FIELD_alignment & 63); + } + } + /* pcode: d = UInt(D:Vd) */ + res->fields[FIELD_d] = ((res->fields[FIELD_D]<<Vd_width)|(res->fields[FIELD_Vd])); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: d2 = d + inc */ + res->fields[FIELD_d2] = (res->fields[FIELD_d]) + (res->fields[FIELD_inc]); + res->fields_mask[FIELD_d2 >> 6] |= 1LL << (FIELD_d2 & 63); + /* pcode: n = UInt(Rn) */ + res->fields[FIELD_n] = (res->fields[FIELD_Rn]); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: m = UInt(Rm) */ + res->fields[FIELD_m] = (res->fields[FIELD_Rm]); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + /* pcode: wback = (m != 15) */ + res->fields[FIELD_wback] = ((res->fields[FIELD_m]) != (15)); + res->fields_mask[FIELD_wback >> 6] |= 1LL << (FIELD_wback & 63); + /* pcode: register_index = (m != 15 && m != 13) */ + res->fields[FIELD_register_index] = (((res->fields[FIELD_m]) != (15)) && ((res->fields[FIELD_m]) != (13))); + res->fields_mask[FIELD_register_index >> 6] |= 1LL << (FIELD_register_index & 63); + /* pcode: if d2 > 31 then UNPREDICTABLE */ + if((res->fields[FIELD_d2]) > (31)) { + res->flags |= FLAG_UNPREDICTABLE; + } + /* pcode: length = 2 */ + res->fields[FIELD_length] = 2; + res->fields_mask[FIELD_length >> 6] |= 1LL << (FIELD_length & 63); + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: 4BD08F1B +int vst3_mult_3elem(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + res->group = INSN_GROUP_NEON; + /* Encoding T1 */ + /* pattern="1111,1001,0,D.1,00,Rn.4,Vd.4,type.4,size.2,align.2,Rm.4" width=32 stringency=12 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFFB00000)==0xF9000000)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ADVSIMD)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_D] = (instr & 0x400000)>>22; + res->fields_mask[FIELD_D >> 6] |= 1LL << (FIELD_D & 63); + char D_width = 1; + res->fields[FIELD_Rn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Rn >> 6] |= 1LL << (FIELD_Rn & 63); + char Rn_width = 4; + res->fields[FIELD_Vd] = (instr & 0xF000)>>12; + res->fields_mask[FIELD_Vd >> 6] |= 1LL << (FIELD_Vd & 63); + char Vd_width = 4; + res->fields[FIELD_type] = (instr & 0xF00)>>8; + res->fields_mask[FIELD_type >> 6] |= 1LL << (FIELD_type & 63); + char type_width = 4; + res->fields[FIELD_size] = (instr & 0xC0)>>6; + res->fields_mask[FIELD_size >> 6] |= 1LL << (FIELD_size & 63); + char size_width = 2; + res->fields[FIELD_align] = (instr & 0x30)>>4; + res->fields_mask[FIELD_align >> 6] |= 1LL << (FIELD_align & 63); + char align_width = 2; + res->fields[FIELD_Rm] = instr & 0xF; + res->fields_mask[FIELD_Rm >> 6] |= 1LL << (FIELD_Rm & 63); + char Rm_width = 4; + + static const instruction_format instr_formats[] = + { + { /* VST3<c>.<size> <registers>,[<Rn>,#<align>] */ + "vst3", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_NEON_SIZE, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REGISTERS,FIELD_registers,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_MEMORY_ONE_REG_ALIGNED,FIELD_Rn,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + { /* VST3<c>.<size> <registers>,[<Rn>,#<align>]! */ + "vst3", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_NEON_SIZE, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REGISTERS,FIELD_registers,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_MEMORY_ONE_REG_ALIGNED,FIELD_Rn,FIELD_UNINIT,"","",WRITEBACK_YES}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + { /* VST3<c>.<size> <registers>,[<Rn>,#<align>],<Rm> */ + "vst3", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_NEON_SIZE, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REGISTERS,FIELD_registers,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_MEMORY_ONE_REG_ALIGNED,FIELD_Rn,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rm,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 3; + res->mnem = armv7::ARMV7_VST3; + + /* pcode: if (size == '11' || align<1>) == '1' then UNDEFINED */ + if(((((res->fields[FIELD_size]) == (0x3)) || (((res->fields[FIELD_align] >> 1) & 1)))) == (0x1)) { + res->status |= STATUS_UNDEFINED; + } + /* pcode: case type of */ + /* pcode: when '0100' */ + if(res->fields[FIELD_type] == 0x4) { + /* pcode: inc = 1 */ + res->fields[FIELD_inc] = 1; + res->fields_mask[FIELD_inc >> 6] |= 1LL << (FIELD_inc & 63); + } + /* pcode: when '0101' */ + else + if(res->fields[FIELD_type] == 0x5) { + /* pcode: inc = 2 */ + res->fields[FIELD_inc] = 2; + res->fields_mask[FIELD_inc >> 6] |= 1LL << (FIELD_inc & 63); + } + /* pcode: alignment = if align<0> == '0' then 1 else 64 */ + if(((res->fields[FIELD_align] & 1)) == (0x0)) { + res->fields[FIELD_alignment] = 1; + res->fields_mask[FIELD_alignment >> 6] |= 1LL << (FIELD_alignment & 63); + } + else { + res->fields[FIELD_alignment] = 64; + res->fields_mask[FIELD_alignment >> 6] |= 1LL << (FIELD_alignment & 63); + } + /* pcode: ebytes = 1 << UInt(size) */ + res->fields[FIELD_ebytes] = (1) << ((res->fields[FIELD_size])); + res->fields_mask[FIELD_ebytes >> 6] |= 1LL << (FIELD_ebytes & 63); + /* pcode: esize = 8 * ebytes */ + res->fields[FIELD_esize] = (8) * (res->fields[FIELD_ebytes]); + res->fields_mask[FIELD_esize >> 6] |= 1LL << (FIELD_esize & 63); + /* pcode: elements = 8 / ebytes */ + res->fields[FIELD_elements] = ((res->fields[FIELD_ebytes]) ? ((8) / (res->fields[FIELD_ebytes])) : 0); + res->fields_mask[FIELD_elements >> 6] |= 1LL << (FIELD_elements & 63); + /* pcode: d = UInt(D:Vd) */ + res->fields[FIELD_d] = ((res->fields[FIELD_D]<<Vd_width)|(res->fields[FIELD_Vd])); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: d2 = d + inc */ + res->fields[FIELD_d2] = (res->fields[FIELD_d]) + (res->fields[FIELD_inc]); + res->fields_mask[FIELD_d2 >> 6] |= 1LL << (FIELD_d2 & 63); + /* pcode: d3 = d2 + inc */ + res->fields[FIELD_d3] = (res->fields[FIELD_d2]) + (res->fields[FIELD_inc]); + res->fields_mask[FIELD_d3 >> 6] |= 1LL << (FIELD_d3 & 63); + /* pcode: n = UInt(Rn) */ + res->fields[FIELD_n] = (res->fields[FIELD_Rn]); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: m = UInt(Rm) */ + res->fields[FIELD_m] = (res->fields[FIELD_Rm]); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + /* pcode: wback = (m != 15) */ + res->fields[FIELD_wback] = ((res->fields[FIELD_m]) != (15)); + res->fields_mask[FIELD_wback >> 6] |= 1LL << (FIELD_wback & 63); + /* pcode: register_index = (m != 15 && m != 13) */ + res->fields[FIELD_register_index] = (((res->fields[FIELD_m]) != (15)) && ((res->fields[FIELD_m]) != (13))); + res->fields_mask[FIELD_register_index >> 6] |= 1LL << (FIELD_register_index & 63); + /* pcode: if d3 > 31 then UNPREDICTABLE */ + if((res->fields[FIELD_d3]) > (31)) { + res->flags |= FLAG_UNPREDICTABLE; + } + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: 9DF6D2AC +int vst3_single_3elem(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + res->group = INSN_GROUP_NEON; + /* Encoding T1 */ + /* pattern="1111,1001,1,D.1,00,Rn.4,Vd.4,size.2,10,index_align.4,Rm.4" width=32 stringency=14 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFFB00300)==0xF9800200)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ADVSIMD)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_D] = (instr & 0x400000)>>22; + res->fields_mask[FIELD_D >> 6] |= 1LL << (FIELD_D & 63); + char D_width = 1; + res->fields[FIELD_Rn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Rn >> 6] |= 1LL << (FIELD_Rn & 63); + char Rn_width = 4; + res->fields[FIELD_Vd] = (instr & 0xF000)>>12; + res->fields_mask[FIELD_Vd >> 6] |= 1LL << (FIELD_Vd & 63); + char Vd_width = 4; + res->fields[FIELD_size] = (instr & 0xC00)>>10; + res->fields_mask[FIELD_size >> 6] |= 1LL << (FIELD_size & 63); + char size_width = 2; + res->fields[FIELD_index_align] = (instr & 0xF0)>>4; + res->fields_mask[FIELD_index_align >> 6] |= 1LL << (FIELD_index_align & 63); + char index_align_width = 4; + res->fields[FIELD_Rm] = instr & 0xF; + res->fields_mask[FIELD_Rm >> 6] |= 1LL << (FIELD_Rm & 63); + char Rm_width = 4; + + static const instruction_format instr_formats[] = + { + { /* VST3<c>.<size> <registers_indexed>,[<Rn>,#<align>] */ + "vst3", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_NEON_SIZE, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REGISTERS_INDEXED,FIELD_registers_indexed,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_MEMORY_ONE_REG_ALIGNED,FIELD_Rn,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + { /* VST3<c>.<size> <registers_indexed>,[<Rn>,#<align>]! */ + "vst3", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_NEON_SIZE, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REGISTERS_INDEXED,FIELD_registers_indexed,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_MEMORY_ONE_REG_ALIGNED,FIELD_Rn,FIELD_UNINIT,"","",WRITEBACK_YES}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + { /* VST3<c>.<size> <registers_indexed>,[<Rn>,#<align>],<Rm> */ + "vst3", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_NEON_SIZE, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REGISTERS_INDEXED,FIELD_registers_indexed,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_MEMORY_ONE_REG_ALIGNED,FIELD_Rn,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rm,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 3; + res->mnem = armv7::ARMV7_VST3; + + /* pcode: if size == '11' then UNDEFINED */ + if((res->fields[FIELD_size]) == (0x3)) { + res->status |= STATUS_UNDEFINED; + } + /* pcode: case size of */ + /* pcode: when '00' */ + if(res->fields[FIELD_size] == 0x0) { + /* pcode: if index_align<0> != '0' then UNDEFINED */ + if(((res->fields[FIELD_index_align] & 1)) != (0x0)) { + res->status |= STATUS_UNDEFINED; + } + /* pcode: ebytes = 1 */ + res->fields[FIELD_ebytes] = 1; + res->fields_mask[FIELD_ebytes >> 6] |= 1LL << (FIELD_ebytes & 63); + /* pcode: esize = 8 */ + res->fields[FIELD_esize] = 8; + res->fields_mask[FIELD_esize >> 6] |= 1LL << (FIELD_esize & 63); + /* pcode: index = UInt(index_align<3:1>) */ + res->fields[FIELD_index] = (((res->fields[FIELD_index_align] >> 1) & 0x7)); + res->fields_mask[FIELD_index >> 6] |= 1LL << (FIELD_index & 63); + /* pcode: inc = 1 */ + res->fields[FIELD_inc] = 1; + res->fields_mask[FIELD_inc >> 6] |= 1LL << (FIELD_inc & 63); + } + /* pcode: when '01' */ + else + if(res->fields[FIELD_size] == 0x1) { + /* pcode: if index_align<0> != '0' then UNDEFINED */ + if(((res->fields[FIELD_index_align] & 1)) != (0x0)) { + res->status |= STATUS_UNDEFINED; + } + /* pcode: ebytes = 2 */ + res->fields[FIELD_ebytes] = 2; + res->fields_mask[FIELD_ebytes >> 6] |= 1LL << (FIELD_ebytes & 63); + /* pcode: esize = 16 */ + res->fields[FIELD_esize] = 16; + res->fields_mask[FIELD_esize >> 6] |= 1LL << (FIELD_esize & 63); + /* pcode: index = UInt(index_align<3:2>) */ + res->fields[FIELD_index] = (((res->fields[FIELD_index_align] >> 2) & 0x3)); + res->fields_mask[FIELD_index >> 6] |= 1LL << (FIELD_index & 63); + /* pcode: inc = if index_align<1> == '0' then 1 else 2 */ + if((((res->fields[FIELD_index_align] >> 1) & 1)) == (0x0)) { + res->fields[FIELD_inc] = 1; + res->fields_mask[FIELD_inc >> 6] |= 1LL << (FIELD_inc & 63); + } + else { + res->fields[FIELD_inc] = 2; + res->fields_mask[FIELD_inc >> 6] |= 1LL << (FIELD_inc & 63); + } + } + /* pcode: when '10' */ + else + if(res->fields[FIELD_size] == 0x2) { + /* pcode: if index_align<1:0> != '00' then UNDEFINED */ + if(((res->fields[FIELD_index_align] & 0x3)) != (0x0)) { + res->status |= STATUS_UNDEFINED; + } + /* pcode: ebytes = 4 */ + res->fields[FIELD_ebytes] = 4; + res->fields_mask[FIELD_ebytes >> 6] |= 1LL << (FIELD_ebytes & 63); + /* pcode: esize = 32 */ + res->fields[FIELD_esize] = 32; + res->fields_mask[FIELD_esize >> 6] |= 1LL << (FIELD_esize & 63); + /* pcode: index = UInt(index_align<3>) */ + res->fields[FIELD_index] = (((res->fields[FIELD_index_align] >> 3) & 1)); + res->fields_mask[FIELD_index >> 6] |= 1LL << (FIELD_index & 63); + /* pcode: inc = if index_align<2> == '0' then 1 else 2 */ + if((((res->fields[FIELD_index_align] >> 2) & 1)) == (0x0)) { + res->fields[FIELD_inc] = 1; + res->fields_mask[FIELD_inc >> 6] |= 1LL << (FIELD_inc & 63); + } + else { + res->fields[FIELD_inc] = 2; + res->fields_mask[FIELD_inc >> 6] |= 1LL << (FIELD_inc & 63); + } + } + /* pcode: d = UInt(D:Vd) */ + res->fields[FIELD_d] = ((res->fields[FIELD_D]<<Vd_width)|(res->fields[FIELD_Vd])); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: d2 = d + inc */ + res->fields[FIELD_d2] = (res->fields[FIELD_d]) + (res->fields[FIELD_inc]); + res->fields_mask[FIELD_d2 >> 6] |= 1LL << (FIELD_d2 & 63); + /* pcode: d3 = d2 + inc */ + res->fields[FIELD_d3] = (res->fields[FIELD_d2]) + (res->fields[FIELD_inc]); + res->fields_mask[FIELD_d3 >> 6] |= 1LL << (FIELD_d3 & 63); + /* pcode: n = UInt(Rn) */ + res->fields[FIELD_n] = (res->fields[FIELD_Rn]); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: m = UInt(Rm) */ + res->fields[FIELD_m] = (res->fields[FIELD_Rm]); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + /* pcode: wback = (m != 15) */ + res->fields[FIELD_wback] = ((res->fields[FIELD_m]) != (15)); + res->fields_mask[FIELD_wback >> 6] |= 1LL << (FIELD_wback & 63); + /* pcode: register_index = (m != 15 && m != 13) */ + res->fields[FIELD_register_index] = (((res->fields[FIELD_m]) != (15)) && ((res->fields[FIELD_m]) != (13))); + res->fields_mask[FIELD_register_index >> 6] |= 1LL << (FIELD_register_index & 63); + /* pcode: if d3 > 31 then UNPREDICTABLE */ + if((res->fields[FIELD_d3]) > (31)) { + res->flags |= FLAG_UNPREDICTABLE; + } + /* pcode: alignment = 1 */ + res->fields[FIELD_alignment] = 1; + res->fields_mask[FIELD_alignment >> 6] |= 1LL << (FIELD_alignment & 63); + /* pcode: length = 3 */ + res->fields[FIELD_length] = 3; + res->fields_mask[FIELD_length >> 6] |= 1LL << (FIELD_length & 63); + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: C1AC6C5B +int vst4_mult_4elem(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + res->group = INSN_GROUP_NEON; + /* Encoding T1 */ + /* pattern="1111,1001,0,D.1,00,Rn.4,Vd.4,type.4,size.2,align.2,Rm.4" width=32 stringency=12 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFFB00000)==0xF9000000)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ADVSIMD)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_D] = (instr & 0x400000)>>22; + res->fields_mask[FIELD_D >> 6] |= 1LL << (FIELD_D & 63); + char D_width = 1; + res->fields[FIELD_Rn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Rn >> 6] |= 1LL << (FIELD_Rn & 63); + char Rn_width = 4; + res->fields[FIELD_Vd] = (instr & 0xF000)>>12; + res->fields_mask[FIELD_Vd >> 6] |= 1LL << (FIELD_Vd & 63); + char Vd_width = 4; + res->fields[FIELD_type] = (instr & 0xF00)>>8; + res->fields_mask[FIELD_type >> 6] |= 1LL << (FIELD_type & 63); + char type_width = 4; + res->fields[FIELD_size] = (instr & 0xC0)>>6; + res->fields_mask[FIELD_size >> 6] |= 1LL << (FIELD_size & 63); + char size_width = 2; + res->fields[FIELD_align] = (instr & 0x30)>>4; + res->fields_mask[FIELD_align >> 6] |= 1LL << (FIELD_align & 63); + char align_width = 2; + res->fields[FIELD_Rm] = instr & 0xF; + res->fields_mask[FIELD_Rm >> 6] |= 1LL << (FIELD_Rm & 63); + char Rm_width = 4; + + static const instruction_format instr_formats[] = + { + { /* VST4<c>.<size> <registers>,[<Rn>,#<align>] */ + "vst4", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_NEON_SIZE, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REGISTERS,FIELD_registers,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_MEMORY_ONE_REG_ALIGNED,FIELD_Rn,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + { /* VST4<c>.<size> <registers>,[<Rn>,#<align>]! */ + "vst4", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_NEON_SIZE, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REGISTERS,FIELD_registers,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_MEMORY_ONE_REG_ALIGNED,FIELD_Rn,FIELD_UNINIT,"","",WRITEBACK_YES}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + { /* VST4<c>.<size> <registers>,[<Rn>,#<align>],<Rm> */ + "vst4", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_NEON_SIZE, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REGISTERS,FIELD_registers,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_MEMORY_ONE_REG_ALIGNED,FIELD_Rn,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rm,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 3; + res->mnem = armv7::ARMV7_VST4; + + /* pcode: if size == '11' then UNDEFINED */ + if((res->fields[FIELD_size]) == (0x3)) { + res->status |= STATUS_UNDEFINED; + } + /* pcode: case type of */ + /* pcode: when '0000' */ + if(res->fields[FIELD_type] == 0x0) { + /* pcode: inc = 1 */ + res->fields[FIELD_inc] = 1; + res->fields_mask[FIELD_inc >> 6] |= 1LL << (FIELD_inc & 63); + } + /* pcode: when '0001' */ + else + if(res->fields[FIELD_type] == 0x1) { + /* pcode: inc = 2 */ + res->fields[FIELD_inc] = 2; + res->fields_mask[FIELD_inc >> 6] |= 1LL << (FIELD_inc & 63); + } + /* pcode: alignment = if align == '00' then 1 else 64 << UInt(align-1) */ + if((res->fields[FIELD_align]) == (0x0)) { + res->fields[FIELD_alignment] = 1; + res->fields_mask[FIELD_alignment >> 6] |= 1LL << (FIELD_alignment & 63); + } + else { + res->fields[FIELD_alignment] = (64) << (((res->fields[FIELD_align]) - (1))); + res->fields_mask[FIELD_alignment >> 6] |= 1LL << (FIELD_alignment & 63); + } + /* pcode: ebytes = 1 << UInt(size) */ + res->fields[FIELD_ebytes] = (1) << ((res->fields[FIELD_size])); + res->fields_mask[FIELD_ebytes >> 6] |= 1LL << (FIELD_ebytes & 63); + /* pcode: esize = 8 * ebytes */ + res->fields[FIELD_esize] = (8) * (res->fields[FIELD_ebytes]); + res->fields_mask[FIELD_esize >> 6] |= 1LL << (FIELD_esize & 63); + /* pcode: elements = 8/ebytes */ + res->fields[FIELD_elements] = ((res->fields[FIELD_ebytes]) ? ((8) / (res->fields[FIELD_ebytes])) : 0); + res->fields_mask[FIELD_elements >> 6] |= 1LL << (FIELD_elements & 63); + /* pcode: d = UInt(D:Vd) */ + res->fields[FIELD_d] = ((res->fields[FIELD_D]<<Vd_width)|(res->fields[FIELD_Vd])); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: d2 = d + inc */ + res->fields[FIELD_d2] = (res->fields[FIELD_d]) + (res->fields[FIELD_inc]); + res->fields_mask[FIELD_d2 >> 6] |= 1LL << (FIELD_d2 & 63); + /* pcode: d3 = d2 + inc */ + res->fields[FIELD_d3] = (res->fields[FIELD_d2]) + (res->fields[FIELD_inc]); + res->fields_mask[FIELD_d3 >> 6] |= 1LL << (FIELD_d3 & 63); + /* pcode: d4 = d3 + inc */ + res->fields[FIELD_d4] = (res->fields[FIELD_d3]) + (res->fields[FIELD_inc]); + res->fields_mask[FIELD_d4 >> 6] |= 1LL << (FIELD_d4 & 63); + /* pcode: n = UInt(Rn) */ + res->fields[FIELD_n] = (res->fields[FIELD_Rn]); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: m = UInt(Rm) */ + res->fields[FIELD_m] = (res->fields[FIELD_Rm]); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + /* pcode: wback = (m != 15) */ + res->fields[FIELD_wback] = ((res->fields[FIELD_m]) != (15)); + res->fields_mask[FIELD_wback >> 6] |= 1LL << (FIELD_wback & 63); + /* pcode: register_index = (m != 15 && m != 13) */ + res->fields[FIELD_register_index] = (((res->fields[FIELD_m]) != (15)) && ((res->fields[FIELD_m]) != (13))); + res->fields_mask[FIELD_register_index >> 6] |= 1LL << (FIELD_register_index & 63); + /* pcode: if d4 > 31 then UNPREDICTABLE */ + if((res->fields[FIELD_d4]) > (31)) { + res->flags |= FLAG_UNPREDICTABLE; + } + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: 8DC6E923 +int vst4_single_4elem(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + res->group = INSN_GROUP_NEON; + /* Encoding T1 */ + /* pattern="1111,1001,1,D.1,00,Rn.4,Vd.4,size.2,11,index_align.4,Rm.4" width=32 stringency=14 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFFB00300)==0xF9800300)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ADVSIMD)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_D] = (instr & 0x400000)>>22; + res->fields_mask[FIELD_D >> 6] |= 1LL << (FIELD_D & 63); + char D_width = 1; + res->fields[FIELD_Rn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Rn >> 6] |= 1LL << (FIELD_Rn & 63); + char Rn_width = 4; + res->fields[FIELD_Vd] = (instr & 0xF000)>>12; + res->fields_mask[FIELD_Vd >> 6] |= 1LL << (FIELD_Vd & 63); + char Vd_width = 4; + res->fields[FIELD_size] = (instr & 0xC00)>>10; + res->fields_mask[FIELD_size >> 6] |= 1LL << (FIELD_size & 63); + char size_width = 2; + res->fields[FIELD_index_align] = (instr & 0xF0)>>4; + res->fields_mask[FIELD_index_align >> 6] |= 1LL << (FIELD_index_align & 63); + char index_align_width = 4; + res->fields[FIELD_Rm] = instr & 0xF; + res->fields_mask[FIELD_Rm >> 6] |= 1LL << (FIELD_Rm & 63); + char Rm_width = 4; + + static const instruction_format instr_formats[] = + { + { /* VST4<c>.<size> <registers_indexed>,[<Rn>,#<align>] */ + "vst4", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_NEON_SIZE, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REGISTERS_INDEXED,FIELD_registers_indexed,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_MEMORY_ONE_REG_ALIGNED,FIELD_Rn,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + { /* VST4<c>.<size> <registers_indexed>,[<Rn>,#<align>]! */ + "vst4", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_NEON_SIZE, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REGISTERS_INDEXED,FIELD_registers_indexed,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_MEMORY_ONE_REG_ALIGNED,FIELD_Rn,FIELD_UNINIT,"","",WRITEBACK_YES}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + { /* VST4<c>.<size> <registers_indexed>,[<Rn>,#<align>],<Rm> */ + "vst4", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_NEON_SIZE, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REGISTERS_INDEXED,FIELD_registers_indexed,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_MEMORY_ONE_REG_ALIGNED,FIELD_Rn,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG,FIELD_Rm,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 3; + res->mnem = armv7::ARMV7_VST4; + + /* pcode: if size == '11' then UNDEFINED */ + if((res->fields[FIELD_size]) == (0x3)) { + res->status |= STATUS_UNDEFINED; + } + /* pcode: case size of */ + /* pcode: when '00' */ + if(res->fields[FIELD_size] == 0x0) { + /* pcode: ebytes = 1 */ + res->fields[FIELD_ebytes] = 1; + res->fields_mask[FIELD_ebytes >> 6] |= 1LL << (FIELD_ebytes & 63); + /* pcode: esize = 8 */ + res->fields[FIELD_esize] = 8; + res->fields_mask[FIELD_esize >> 6] |= 1LL << (FIELD_esize & 63); + /* pcode: index = UInt(index_align<3:1>) */ + res->fields[FIELD_index] = (((res->fields[FIELD_index_align] >> 1) & 0x7)); + res->fields_mask[FIELD_index >> 6] |= 1LL << (FIELD_index & 63); + /* pcode: inc = 1 */ + res->fields[FIELD_inc] = 1; + res->fields_mask[FIELD_inc >> 6] |= 1LL << (FIELD_inc & 63); + /* pcode: alignment = if index_align<0> == '0' then 1 else 32 */ + if(((res->fields[FIELD_index_align] & 1)) == (0x0)) { + res->fields[FIELD_alignment] = 1; + res->fields_mask[FIELD_alignment >> 6] |= 1LL << (FIELD_alignment & 63); + } + else { + res->fields[FIELD_alignment] = 32; + res->fields_mask[FIELD_alignment >> 6] |= 1LL << (FIELD_alignment & 63); + } + } + /* pcode: when '01' */ + else + if(res->fields[FIELD_size] == 0x1) { + /* pcode: ebytes = 2 */ + res->fields[FIELD_ebytes] = 2; + res->fields_mask[FIELD_ebytes >> 6] |= 1LL << (FIELD_ebytes & 63); + /* pcode: esize = 16 */ + res->fields[FIELD_esize] = 16; + res->fields_mask[FIELD_esize >> 6] |= 1LL << (FIELD_esize & 63); + /* pcode: index = UInt(index_align<3:2>) */ + res->fields[FIELD_index] = (((res->fields[FIELD_index_align] >> 2) & 0x3)); + res->fields_mask[FIELD_index >> 6] |= 1LL << (FIELD_index & 63); + /* pcode: inc = if index_align<1> == '0' then 1 else 2 */ + if((((res->fields[FIELD_index_align] >> 1) & 1)) == (0x0)) { + res->fields[FIELD_inc] = 1; + res->fields_mask[FIELD_inc >> 6] |= 1LL << (FIELD_inc & 63); + } + else { + res->fields[FIELD_inc] = 2; + res->fields_mask[FIELD_inc >> 6] |= 1LL << (FIELD_inc & 63); + } + /* pcode: alignment = if index_align<0> == '0' then 1 else 64 */ + if(((res->fields[FIELD_index_align] & 1)) == (0x0)) { + res->fields[FIELD_alignment] = 1; + res->fields_mask[FIELD_alignment >> 6] |= 1LL << (FIELD_alignment & 63); + } + else { + res->fields[FIELD_alignment] = 64; + res->fields_mask[FIELD_alignment >> 6] |= 1LL << (FIELD_alignment & 63); + } + } + /* pcode: when '10' */ + else + if(res->fields[FIELD_size] == 0x2) { + /* pcode: if index_align<1:0> == '11' then UNDEFINED */ + if(((res->fields[FIELD_index_align] & 0x3)) == (0x3)) { + res->status |= STATUS_UNDEFINED; + } + /* pcode: ebytes = 4 */ + res->fields[FIELD_ebytes] = 4; + res->fields_mask[FIELD_ebytes >> 6] |= 1LL << (FIELD_ebytes & 63); + /* pcode: esize = 32 */ + res->fields[FIELD_esize] = 32; + res->fields_mask[FIELD_esize >> 6] |= 1LL << (FIELD_esize & 63); + /* pcode: index = UInt(index_align<3>) */ + res->fields[FIELD_index] = (((res->fields[FIELD_index_align] >> 3) & 1)); + res->fields_mask[FIELD_index >> 6] |= 1LL << (FIELD_index & 63); + /* pcode: inc = if index_align<2> == '0' then 1 else 2 */ + if((((res->fields[FIELD_index_align] >> 2) & 1)) == (0x0)) { + res->fields[FIELD_inc] = 1; + res->fields_mask[FIELD_inc >> 6] |= 1LL << (FIELD_inc & 63); + } + else { + res->fields[FIELD_inc] = 2; + res->fields_mask[FIELD_inc >> 6] |= 1LL << (FIELD_inc & 63); + } + /* pcode: alignment = if index_align<1:0> == '00' then 1 else 64 << UInt(index_align<1:0> - 1) */ + if(((res->fields[FIELD_index_align] & 0x3)) == (0x0)) { + res->fields[FIELD_alignment] = 1; + res->fields_mask[FIELD_alignment >> 6] |= 1LL << (FIELD_alignment & 63); + } + else { + res->fields[FIELD_alignment] = (64) << ((((res->fields[FIELD_index_align] & 0x3)) - (1))); + res->fields_mask[FIELD_alignment >> 6] |= 1LL << (FIELD_alignment & 63); + } + } + /* pcode: d = UInt(D:Vd) */ + res->fields[FIELD_d] = ((res->fields[FIELD_D]<<Vd_width)|(res->fields[FIELD_Vd])); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: d2 = d + inc */ + res->fields[FIELD_d2] = (res->fields[FIELD_d]) + (res->fields[FIELD_inc]); + res->fields_mask[FIELD_d2 >> 6] |= 1LL << (FIELD_d2 & 63); + /* pcode: d3 = d2 + inc */ + res->fields[FIELD_d3] = (res->fields[FIELD_d2]) + (res->fields[FIELD_inc]); + res->fields_mask[FIELD_d3 >> 6] |= 1LL << (FIELD_d3 & 63); + /* pcode: d4 = d3 + inc */ + res->fields[FIELD_d4] = (res->fields[FIELD_d3]) + (res->fields[FIELD_inc]); + res->fields_mask[FIELD_d4 >> 6] |= 1LL << (FIELD_d4 & 63); + /* pcode: n = UInt(Rn) */ + res->fields[FIELD_n] = (res->fields[FIELD_Rn]); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: m = UInt(Rm) */ + res->fields[FIELD_m] = (res->fields[FIELD_Rm]); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + /* pcode: wback = (m != 15) */ + res->fields[FIELD_wback] = ((res->fields[FIELD_m]) != (15)); + res->fields_mask[FIELD_wback >> 6] |= 1LL << (FIELD_wback & 63); + /* pcode: register_index = (m != 15 && m != 13) */ + res->fields[FIELD_register_index] = (((res->fields[FIELD_m]) != (15)) && ((res->fields[FIELD_m]) != (13))); + res->fields_mask[FIELD_register_index >> 6] |= 1LL << (FIELD_register_index & 63); + /* pcode: if d4 > 31 then UNPREDICTABLE */ + if((res->fields[FIELD_d4]) > (31)) { + res->flags |= FLAG_UNPREDICTABLE; + } + /* pcode: length = 4 */ + res->fields[FIELD_length] = 4; + res->fields_mask[FIELD_length >> 6] |= 1LL << (FIELD_length & 63); + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: A180DDD2 +int vstm(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + res->group = INSN_GROUP_NEON; + /* Encoding T2 */ + /* pattern="1110,110,P.1,U.1,D.1,W.1,0,Rn.4,Vd.4,1010,imm8.8" width=32 stringency=16 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFE100F00)==0xEC000A00)) { + res->instrSize = 32; + if(!(req->arch & ARCH_VFPv2) && !(req->arch & ARCH_VFPv3)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_P] = (instr & 0x1000000)>>24; + res->fields_mask[FIELD_P >> 6] |= 1LL << (FIELD_P & 63); + char P_width = 1; + res->fields[FIELD_U] = (instr & 0x800000)>>23; + res->fields_mask[FIELD_U >> 6] |= 1LL << (FIELD_U & 63); + char U_width = 1; + res->fields[FIELD_D] = (instr & 0x400000)>>22; + res->fields_mask[FIELD_D >> 6] |= 1LL << (FIELD_D & 63); + char D_width = 1; + res->fields[FIELD_W] = (instr & 0x200000)>>21; + res->fields_mask[FIELD_W >> 6] |= 1LL << (FIELD_W & 63); + char W_width = 1; + res->fields[FIELD_Rn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Rn >> 6] |= 1LL << (FIELD_Rn & 63); + char Rn_width = 4; + res->fields[FIELD_Vd] = (instr & 0xF000)>>12; + res->fields_mask[FIELD_Vd >> 6] |= 1LL << (FIELD_Vd & 63); + char Vd_width = 4; + res->fields[FIELD_imm8] = instr & 0xFF; + res->fields_mask[FIELD_imm8 >> 6] |= 1LL << (FIELD_imm8 & 63); + char imm8_width = 8; + + static const instruction_format instr_formats[] = + { + { /* VSTMDB<c> <Rn>{!},<registers> */ + "vstmdb", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rn,FIELD_UNINIT,"","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REGISTERS,FIELD_registers,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + { /* VSTMIA<c> <Rn>{!},<registers> */ + "vstmia", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rn,FIELD_UNINIT,"","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REGISTERS,FIELD_registers,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 2; + res->mnem = armv7::ARMV7_VSTMDB; + + /* pcode: if P == '0' && U == '0' && W == '0' then SEE xfer_64_core_ext_regs */ + if((((res->fields[FIELD_P]) == (0x0)) && ((res->fields[FIELD_U]) == (0x0))) && ((res->fields[FIELD_W]) == (0x0))) { + + return xfer_64_core_ext_regs(req, res); + } + /* pcode: if P == '1' && U == '0' && W == '1' && Rn == '1101' then SEE vpush */ + if(((((res->fields[FIELD_P]) == (0x1)) && ((res->fields[FIELD_U]) == (0x0))) && ((res->fields[FIELD_W]) == (0x1))) && ((res->fields[FIELD_Rn]) == (0xD))) { + + return vpush(req, res); + } + /* pcode: if P == '1' && W == '0' then SEE vstr */ + if(((res->fields[FIELD_P]) == (0x1)) && ((res->fields[FIELD_W]) == (0x0))) { + + return vstr(req, res); + } + /* pcode: if P == U && W == '1' then UNDEFINED */ + if(((res->fields[FIELD_P]) == (res->fields[FIELD_U])) && ((res->fields[FIELD_W]) == (0x1))) { + res->status |= STATUS_UNDEFINED; + } + /* pcode: single_regs = TRUE */ + res->fields[FIELD_single_regs] = 1; + res->fields_mask[FIELD_single_regs >> 6] |= 1LL << (FIELD_single_regs & 63); + /* pcode: add = (U == '1') */ + res->fields[FIELD_add] = ((res->fields[FIELD_U]) == (0x1)); + res->fields_mask[FIELD_add >> 6] |= 1LL << (FIELD_add & 63); + /* pcode: wback = (W == '1') */ + res->fields[FIELD_wback] = ((res->fields[FIELD_W]) == (0x1)); + res->fields_mask[FIELD_wback >> 6] |= 1LL << (FIELD_wback & 63); + /* pcode: d = UInt(Vd:D) */ + res->fields[FIELD_d] = ((res->fields[FIELD_Vd]<<D_width)|(res->fields[FIELD_D])); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: n = UInt(Rn) */ + res->fields[FIELD_n] = (res->fields[FIELD_Rn]); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: imm32 = ZeroExtend(imm8:'00', 32) */ + res->fields[FIELD_imm32] = (res->fields[FIELD_imm8]<<2)|(0x0); + res->fields_mask[FIELD_imm32 >> 6] |= 1LL << (FIELD_imm32 & 63); + /* pcode: regs = UInt(imm8) */ + res->fields[FIELD_regs] = (res->fields[FIELD_imm8]); + res->fields_mask[FIELD_regs >> 6] |= 1LL << (FIELD_regs & 63); + /* pcode: if n == 15 && (wback) then UNPREDICTABLE */ + if(((res->fields[FIELD_n]) == (15)) && ((res->fields[FIELD_wback]))) { + res->flags |= FLAG_UNPREDICTABLE; + } + /* pcode: if regs == 0 || (d+regs) > 32 then UNPREDICTABLE */ + if(((res->fields[FIELD_regs]) == (0)) || ((((res->fields[FIELD_d]) + (res->fields[FIELD_regs]))) > (32))) { + res->flags |= FLAG_UNPREDICTABLE; + } + /* pcode: fmt_idx = U */ + res->fields[FIELD_fmt_idx] = res->fields[FIELD_U]; + res->fields_mask[FIELD_fmt_idx >> 6] |= 1LL << (FIELD_fmt_idx & 63); + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* Encoding T1 */ + /* pattern="1110,110,P.1,U.1,D.1,W.1,0,Rn.4,Vd.4,1011,imm8.8" width=32 stringency=16 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFE100F00)==0xEC000B00)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ADVSIMD)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_P] = (instr & 0x1000000)>>24; + res->fields_mask[FIELD_P >> 6] |= 1LL << (FIELD_P & 63); + char P_width = 1; + res->fields[FIELD_U] = (instr & 0x800000)>>23; + res->fields_mask[FIELD_U >> 6] |= 1LL << (FIELD_U & 63); + char U_width = 1; + res->fields[FIELD_D] = (instr & 0x400000)>>22; + res->fields_mask[FIELD_D >> 6] |= 1LL << (FIELD_D & 63); + char D_width = 1; + res->fields[FIELD_W] = (instr & 0x200000)>>21; + res->fields_mask[FIELD_W >> 6] |= 1LL << (FIELD_W & 63); + char W_width = 1; + res->fields[FIELD_Rn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Rn >> 6] |= 1LL << (FIELD_Rn & 63); + char Rn_width = 4; + res->fields[FIELD_Vd] = (instr & 0xF000)>>12; + res->fields_mask[FIELD_Vd >> 6] |= 1LL << (FIELD_Vd & 63); + char Vd_width = 4; + res->fields[FIELD_imm8] = instr & 0xFF; + res->fields_mask[FIELD_imm8 >> 6] |= 1LL << (FIELD_imm8 & 63); + char imm8_width = 8; + + static const instruction_format instr_formats[] = + { + { /* VSTMDB<c> <Rn>{!},<registers> */ + "vstmdb", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rn,FIELD_UNINIT,"","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REGISTERS,FIELD_registers,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + { /* VSTMIA<c> <Rn>{!},<registers> */ + "vstmia", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG,FIELD_Rn,FIELD_UNINIT,"","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REGISTERS,FIELD_registers,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 2; + res->mnem = armv7::ARMV7_VSTMDB; + + /* pcode: if P == '0' && U == '0' && W == '0' then SEE xfer_64_core_ext_regs */ + if((((res->fields[FIELD_P]) == (0x0)) && ((res->fields[FIELD_U]) == (0x0))) && ((res->fields[FIELD_W]) == (0x0))) { + + return xfer_64_core_ext_regs(req, res); + } + /* pcode: if P == '1' && U == '0' && W == '1' && Rn == '1101' then SEE vpush */ + if(((((res->fields[FIELD_P]) == (0x1)) && ((res->fields[FIELD_U]) == (0x0))) && ((res->fields[FIELD_W]) == (0x1))) && ((res->fields[FIELD_Rn]) == (0xD))) { + + return vpush(req, res); + } + /* pcode: if P == '1' && W == '0' then SEE vstr */ + if(((res->fields[FIELD_P]) == (0x1)) && ((res->fields[FIELD_W]) == (0x0))) { + + return vstr(req, res); + } + /* pcode: if P == U && W == '1' then UNDEFINED */ + if(((res->fields[FIELD_P]) == (res->fields[FIELD_U])) && ((res->fields[FIELD_W]) == (0x1))) { + res->status |= STATUS_UNDEFINED; + } + /* pcode: single_regs = FALSE */ + res->fields[FIELD_single_regs] = 0; + res->fields_mask[FIELD_single_regs >> 6] |= 1LL << (FIELD_single_regs & 63); + /* pcode: add = (U == '1') */ + res->fields[FIELD_add] = ((res->fields[FIELD_U]) == (0x1)); + res->fields_mask[FIELD_add >> 6] |= 1LL << (FIELD_add & 63); + /* pcode: wback = (W == '1') */ + res->fields[FIELD_wback] = ((res->fields[FIELD_W]) == (0x1)); + res->fields_mask[FIELD_wback >> 6] |= 1LL << (FIELD_wback & 63); + /* pcode: d = UInt(D:Vd) */ + res->fields[FIELD_d] = ((res->fields[FIELD_D]<<Vd_width)|(res->fields[FIELD_Vd])); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: n = UInt(Rn) */ + res->fields[FIELD_n] = (res->fields[FIELD_Rn]); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: imm32 = ZeroExtend(imm8:'00', 32) */ + res->fields[FIELD_imm32] = (res->fields[FIELD_imm8]<<2)|(0x0); + res->fields_mask[FIELD_imm32 >> 6] |= 1LL << (FIELD_imm32 & 63); + /* pcode: regs = UInt(imm8) DIV 2 */ + res->fields[FIELD_regs] = ((2) ? (((res->fields[FIELD_imm8])) / (2)) : 0); + res->fields_mask[FIELD_regs >> 6] |= 1LL << (FIELD_regs & 63); + /* pcode: if n == 15 && (wback) then UNPREDICTABLE */ + if(((res->fields[FIELD_n]) == (15)) && ((res->fields[FIELD_wback]))) { + res->flags |= FLAG_UNPREDICTABLE; + } + /* pcode: if (regs == 0 || regs > 16 || (d+regs) > 32) then UNPREDICTABLE */ + if(((((res->fields[FIELD_regs]) == (0)) || ((res->fields[FIELD_regs]) > (16))) || ((((res->fields[FIELD_d]) + (res->fields[FIELD_regs]))) > (32)))) { + res->flags |= FLAG_UNPREDICTABLE; + } + /* pcode: if (d+regs) > 16 then UNPREDICTABLE */ + if((((res->fields[FIELD_d]) + (res->fields[FIELD_regs]))) > (16)) { + res->flags |= FLAG_UNPREDICTABLE; + } + /* pcode: fmt_idx = U */ + res->fields[FIELD_fmt_idx] = res->fields[FIELD_U]; + res->fields_mask[FIELD_fmt_idx >> 6] |= 1LL << (FIELD_fmt_idx & 63); + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: 68F31CE8 +int vstr(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + res->group = INSN_GROUP_NEON; + /* Encoding T2 */ + /* pattern="1110,1101,U.1,D.1,0,0,Rn.4,Vd.4,1010,imm8.8" width=32 stringency=16 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFF300F00)==0xED000A00)) { + res->instrSize = 32; + if(!(req->arch & ARCH_VFPv2) && !(req->arch & ARCH_VFPv3)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_U] = (instr & 0x800000)>>23; + res->fields_mask[FIELD_U >> 6] |= 1LL << (FIELD_U & 63); + char U_width = 1; + res->fields[FIELD_D] = (instr & 0x400000)>>22; + res->fields_mask[FIELD_D >> 6] |= 1LL << (FIELD_D & 63); + char D_width = 1; + res->fields[FIELD_Rn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Rn >> 6] |= 1LL << (FIELD_Rn & 63); + char Rn_width = 4; + res->fields[FIELD_Vd] = (instr & 0xF000)>>12; + res->fields_mask[FIELD_Vd >> 6] |= 1LL << (FIELD_Vd & 63); + char Vd_width = 4; + res->fields[FIELD_imm8] = instr & 0xFF; + res->fields_mask[FIELD_imm8 >> 6] |= 1LL << (FIELD_imm8 & 63); + char imm8_width = 8; + + static const instruction_format instr_formats[] = + { + { /* VSTR<c> <Sd>,[<Rn>,#<+/-><imm32>] */ + "vstr", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"s","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_MEMORY_ONE_REG_ADD_IMM,FIELD_Rn,FIELD_imm32,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_VSTR; + + /* pcode: add = (U == '1') */ + res->fields[FIELD_add] = ((res->fields[FIELD_U]) == (0x1)); + res->fields_mask[FIELD_add >> 6] |= 1LL << (FIELD_add & 63); + /* pcode: imm32 = ZeroExtend(imm8:'00', 32) */ + res->fields[FIELD_imm32] = (res->fields[FIELD_imm8]<<2)|(0x0); + res->fields_mask[FIELD_imm32 >> 6] |= 1LL << (FIELD_imm32 & 63); + /* pcode: d = UInt(Vd:D) */ + res->fields[FIELD_d] = ((res->fields[FIELD_Vd]<<D_width)|(res->fields[FIELD_D])); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: n = UInt(Rn) */ + res->fields[FIELD_n] = (res->fields[FIELD_Rn]); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* Encoding T1 */ + /* pattern="1110,1101,U.1,D.1,0,0,Rn.4,Vd.4,1011,imm8.8" width=32 stringency=16 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFF300F00)==0xED000B00)) { + res->instrSize = 32; + if(!(req->arch & ARCH_VFPv2) && !(req->arch & ARCH_VFPv3)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_U] = (instr & 0x800000)>>23; + res->fields_mask[FIELD_U >> 6] |= 1LL << (FIELD_U & 63); + char U_width = 1; + res->fields[FIELD_D] = (instr & 0x400000)>>22; + res->fields_mask[FIELD_D >> 6] |= 1LL << (FIELD_D & 63); + char D_width = 1; + res->fields[FIELD_Rn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Rn >> 6] |= 1LL << (FIELD_Rn & 63); + char Rn_width = 4; + res->fields[FIELD_Vd] = (instr & 0xF000)>>12; + res->fields_mask[FIELD_Vd >> 6] |= 1LL << (FIELD_Vd & 63); + char Vd_width = 4; + res->fields[FIELD_imm8] = instr & 0xFF; + res->fields_mask[FIELD_imm8 >> 6] |= 1LL << (FIELD_imm8 & 63); + char imm8_width = 8; + + static const instruction_format instr_formats[] = + { + { /* VSTR<c> <Dd>,[<Rn>,#<+/-><imm32>] */ + "vstr", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_MEMORY_ONE_REG_ADD_IMM,FIELD_Rn,FIELD_imm32,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_VSTR; + + /* pcode: add = (U == '1') */ + res->fields[FIELD_add] = ((res->fields[FIELD_U]) == (0x1)); + res->fields_mask[FIELD_add >> 6] |= 1LL << (FIELD_add & 63); + /* pcode: imm32 = ZeroExtend(imm8:'00', 32) */ + res->fields[FIELD_imm32] = (res->fields[FIELD_imm8]<<2)|(0x0); + res->fields_mask[FIELD_imm32 >> 6] |= 1LL << (FIELD_imm32 & 63); + /* pcode: d = UInt(D:Vd) */ + res->fields[FIELD_d] = ((res->fields[FIELD_D]<<Vd_width)|(res->fields[FIELD_Vd])); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: n = UInt(Rn) */ + res->fields[FIELD_n] = (res->fields[FIELD_Rn]); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: 060A0569 +int vsub_float(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + res->group = INSN_GROUP_NEON; + /* Encoding T2 */ + /* pattern="1110,11100,D.1,11,Vn.4,Vd.4,101,sz.1,N.1,1,M.1,0,Vm.4" width=32 stringency=20 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFFB00E50)==0xEE300A40)) { + res->instrSize = 32; + if(!(req->arch & ARCH_VFPv2) && !(req->arch & ARCH_VFPv3)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_D] = (instr & 0x400000)>>22; + res->fields_mask[FIELD_D >> 6] |= 1LL << (FIELD_D & 63); + char D_width = 1; + res->fields[FIELD_Vn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Vn >> 6] |= 1LL << (FIELD_Vn & 63); + char Vn_width = 4; + res->fields[FIELD_Vd] = (instr & 0xF000)>>12; + res->fields_mask[FIELD_Vd >> 6] |= 1LL << (FIELD_Vd & 63); + char Vd_width = 4; + res->fields[FIELD_sz] = (instr & 0x100)>>8; + res->fields_mask[FIELD_sz >> 6] |= 1LL << (FIELD_sz & 63); + char sz_width = 1; + res->fields[FIELD_N] = (instr & 0x80)>>7; + res->fields_mask[FIELD_N >> 6] |= 1LL << (FIELD_N & 63); + char N_width = 1; + res->fields[FIELD_M] = (instr & 0x20)>>5; + res->fields_mask[FIELD_M >> 6] |= 1LL << (FIELD_M & 63); + char M_width = 1; + res->fields[FIELD_Vm] = instr & 0xF; + res->fields_mask[FIELD_Vm >> 6] |= 1LL << (FIELD_Vm & 63); + char Vm_width = 4; + + static const instruction_format instr_formats[] = + { + { /* VSUB<c>.F32 <Sd>,<Sn>,<Sm> */ + "vsub.f32", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_F32, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"s","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_n,FIELD_UNINIT,"s","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_m,FIELD_UNINIT,"s","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + { /* VSUB<c>.F64 <Dd>,<Dn>,<Dm> */ + "vsub.f64", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_F64, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_n,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_m,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 2; + res->mnem = armv7::ARMV7_VSUB; + + /* pcode: advsimd = FALSE */ + res->fields[FIELD_advsimd] = 0; + res->fields_mask[FIELD_advsimd >> 6] |= 1LL << (FIELD_advsimd & 63); + /* pcode: dp_operation = (sz == '1') */ + res->fields[FIELD_dp_operation] = ((res->fields[FIELD_sz]) == (0x1)); + res->fields_mask[FIELD_dp_operation >> 6] |= 1LL << (FIELD_dp_operation & 63); + /* pcode: d = if dp_operation then UInt(D:Vd) else UInt(Vd:D) */ + if(res->fields[FIELD_dp_operation]) { + res->fields[FIELD_d] = ((res->fields[FIELD_D]<<Vd_width)|(res->fields[FIELD_Vd])); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + } + else { + res->fields[FIELD_d] = ((res->fields[FIELD_Vd]<<D_width)|(res->fields[FIELD_D])); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + } + /* pcode: n = if dp_operation then UInt(N:Vn) else UInt(Vn:N) */ + if(res->fields[FIELD_dp_operation]) { + res->fields[FIELD_n] = ((res->fields[FIELD_N]<<Vn_width)|(res->fields[FIELD_Vn])); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + } + else { + res->fields[FIELD_n] = ((res->fields[FIELD_Vn]<<N_width)|(res->fields[FIELD_N])); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + } + /* pcode: m = if dp_operation then UInt(M:Vm) else UInt(Vm:M) */ + if(res->fields[FIELD_dp_operation]) { + res->fields[FIELD_m] = ((res->fields[FIELD_M]<<Vm_width)|(res->fields[FIELD_Vm])); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + } + else { + res->fields[FIELD_m] = ((res->fields[FIELD_Vm]<<M_width)|(res->fields[FIELD_M])); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + } + /* pcode: fmt_idx = dp_operation */ + res->fields[FIELD_fmt_idx] = res->fields[FIELD_dp_operation]; + res->fields_mask[FIELD_fmt_idx >> 6] |= 1LL << (FIELD_fmt_idx & 63); + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* Encoding T1 */ + /* pattern="1110,1111,0,D.1,1,sz.1,Vn.4,Vd.4,1101,N.1,Q.1,M.1,0,Vm.4" width=32 stringency=20 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFFA00F10)==0xEF200D00)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ADVSIMD)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_D] = (instr & 0x400000)>>22; + res->fields_mask[FIELD_D >> 6] |= 1LL << (FIELD_D & 63); + char D_width = 1; + res->fields[FIELD_sz] = (instr & 0x100000)>>20; + res->fields_mask[FIELD_sz >> 6] |= 1LL << (FIELD_sz & 63); + char sz_width = 1; + res->fields[FIELD_Vn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Vn >> 6] |= 1LL << (FIELD_Vn & 63); + char Vn_width = 4; + res->fields[FIELD_Vd] = (instr & 0xF000)>>12; + res->fields_mask[FIELD_Vd >> 6] |= 1LL << (FIELD_Vd & 63); + char Vd_width = 4; + res->fields[FIELD_N] = (instr & 0x80)>>7; + res->fields_mask[FIELD_N >> 6] |= 1LL << (FIELD_N & 63); + char N_width = 1; + res->fields[FIELD_Q] = (instr & 0x40)>>6; + res->fields_mask[FIELD_Q >> 6] |= 1LL << (FIELD_Q & 63); + char Q_width = 1; + res->fields[FIELD_M] = (instr & 0x20)>>5; + res->fields_mask[FIELD_M >> 6] |= 1LL << (FIELD_M & 63); + char M_width = 1; + res->fields[FIELD_Vm] = instr & 0xF; + res->fields_mask[FIELD_Vm >> 6] |= 1LL << (FIELD_Vm & 63); + char Vm_width = 4; + + static const instruction_format instr_formats[] = + { + { /* VSUB<c>.F32 <Dd>,<Dn>,<Dm> */ + "vsub.f32", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_F32, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_n,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_m,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + { /* VSUB<c>.F32 <Qd>,<Qn>,<Qm> */ + "vsub.f32", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_F32, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"q","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_n,FIELD_UNINIT,"q","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_m,FIELD_UNINIT,"q","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 2; + res->mnem = armv7::ARMV7_VSUB; + + /* pcode: if Q == '1' && (Vd<0> == '1' || Vn<0> == '1' || Vm<0> == '1') then UNDEFINED */ + if(((res->fields[FIELD_Q]) == (0x1)) && ((((((res->fields[FIELD_Vd] & 1)) == (0x1)) || (((res->fields[FIELD_Vn] & 1)) == (0x1))) || (((res->fields[FIELD_Vm] & 1)) == (0x1))))) { + res->status |= STATUS_UNDEFINED; + } + /* pcode: if sz == '1' then UNDEFINED */ + if((res->fields[FIELD_sz]) == (0x1)) { + res->status |= STATUS_UNDEFINED; + } + /* pcode: advsimd = TRUE */ + res->fields[FIELD_advsimd] = 1; + res->fields_mask[FIELD_advsimd >> 6] |= 1LL << (FIELD_advsimd & 63); + /* pcode: esize = 32 */ + res->fields[FIELD_esize] = 32; + res->fields_mask[FIELD_esize >> 6] |= 1LL << (FIELD_esize & 63); + /* pcode: elements = 2 */ + res->fields[FIELD_elements] = 2; + res->fields_mask[FIELD_elements >> 6] |= 1LL << (FIELD_elements & 63); + /* pcode: d = UInt(D:Vd) */ + res->fields[FIELD_d] = ((res->fields[FIELD_D]<<Vd_width)|(res->fields[FIELD_Vd])); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: n = UInt(N:Vn) */ + res->fields[FIELD_n] = ((res->fields[FIELD_N]<<Vn_width)|(res->fields[FIELD_Vn])); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: m = UInt(M:Vm) */ + res->fields[FIELD_m] = ((res->fields[FIELD_M]<<Vm_width)|(res->fields[FIELD_Vm])); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + /* pcode: regs = if Q == '0' then 1 else 2 */ + if((res->fields[FIELD_Q]) == (0x0)) { + res->fields[FIELD_regs] = 1; + res->fields_mask[FIELD_regs >> 6] |= 1LL << (FIELD_regs & 63); + } + else { + res->fields[FIELD_regs] = 2; + res->fields_mask[FIELD_regs >> 6] |= 1LL << (FIELD_regs & 63); + } + /* pcode: fmt_idx = (Q == '1') */ + res->fields[FIELD_fmt_idx] = ((res->fields[FIELD_Q]) == (0x1)); + res->fields_mask[FIELD_fmt_idx >> 6] |= 1LL << (FIELD_fmt_idx & 63); + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: 00196482 +int vsub_integer(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + res->group = INSN_GROUP_NEON; + /* Encoding T1 */ + /* pattern="1111,1111,0,D.1,size.2,Vn.4,Vd.4,1000,N.1,Q.1,M.1,0,Vm.4" width=32 stringency=18 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFF800F10)==0xFF000800)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ADVSIMD)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_D] = (instr & 0x400000)>>22; + res->fields_mask[FIELD_D >> 6] |= 1LL << (FIELD_D & 63); + char D_width = 1; + res->fields[FIELD_size] = (instr & 0x300000)>>20; + res->fields_mask[FIELD_size >> 6] |= 1LL << (FIELD_size & 63); + char size_width = 2; + res->fields[FIELD_Vn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Vn >> 6] |= 1LL << (FIELD_Vn & 63); + char Vn_width = 4; + res->fields[FIELD_Vd] = (instr & 0xF000)>>12; + res->fields_mask[FIELD_Vd >> 6] |= 1LL << (FIELD_Vd & 63); + char Vd_width = 4; + res->fields[FIELD_N] = (instr & 0x80)>>7; + res->fields_mask[FIELD_N >> 6] |= 1LL << (FIELD_N & 63); + char N_width = 1; + res->fields[FIELD_Q] = (instr & 0x40)>>6; + res->fields_mask[FIELD_Q >> 6] |= 1LL << (FIELD_Q & 63); + char Q_width = 1; + res->fields[FIELD_M] = (instr & 0x20)>>5; + res->fields_mask[FIELD_M >> 6] |= 1LL << (FIELD_M & 63); + char M_width = 1; + res->fields[FIELD_Vm] = instr & 0xF; + res->fields_mask[FIELD_Vm >> 6] |= 1LL << (FIELD_Vm & 63); + char Vm_width = 4; + + static const instruction_format instr_formats[] = + { + { /* VSUB<c>.<dt> <Dd>,<Dn>,<Dm> */ + "vsub", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_VFP_DATA_SIZE, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_n,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_m,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + { /* VSUB<c>.<dt> <Qd>,<Qn>,<Qm> */ + "vsub", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_VFP_DATA_SIZE, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"q","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_n,FIELD_UNINIT,"q","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_m,FIELD_UNINIT,"q","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 2; + res->mnem = armv7::ARMV7_VSUB; + + /* pcode: if Q == '1' && (Vd<0> == '1' || Vn<0> == '1' || Vm<0> == '1') then UNDEFINED */ + if(((res->fields[FIELD_Q]) == (0x1)) && ((((((res->fields[FIELD_Vd] & 1)) == (0x1)) || (((res->fields[FIELD_Vn] & 1)) == (0x1))) || (((res->fields[FIELD_Vm] & 1)) == (0x1))))) { + res->status |= STATUS_UNDEFINED; + } + /* pcode: esize = 8 << UInt(size) */ + res->fields[FIELD_esize] = (8) << ((res->fields[FIELD_size])); + res->fields_mask[FIELD_esize >> 6] |= 1LL << (FIELD_esize & 63); + /* pcode: elements = 64 DIV esize */ + res->fields[FIELD_elements] = ((res->fields[FIELD_esize]) ? ((64) / (res->fields[FIELD_esize])) : 0); + res->fields_mask[FIELD_elements >> 6] |= 1LL << (FIELD_elements & 63); + /* pcode: d = UInt(D:Vd) */ + res->fields[FIELD_d] = ((res->fields[FIELD_D]<<Vd_width)|(res->fields[FIELD_Vd])); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: n = UInt(N:Vn) */ + res->fields[FIELD_n] = ((res->fields[FIELD_N]<<Vn_width)|(res->fields[FIELD_Vn])); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: m = UInt(M:Vm) */ + res->fields[FIELD_m] = ((res->fields[FIELD_M]<<Vm_width)|(res->fields[FIELD_Vm])); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + /* pcode: regs = if Q == '0' then 1 else 2 */ + if((res->fields[FIELD_Q]) == (0x0)) { + res->fields[FIELD_regs] = 1; + res->fields_mask[FIELD_regs >> 6] |= 1LL << (FIELD_regs & 63); + } + else { + res->fields[FIELD_regs] = 2; + res->fields_mask[FIELD_regs >> 6] |= 1LL << (FIELD_regs & 63); + } + /* pcode: iword = TRUE */ + res->fields[FIELD_iword] = 1; + res->fields_mask[FIELD_iword >> 6] |= 1LL << (FIELD_iword & 63); + /* pcode: dt = size */ + res->fields[FIELD_dt] = res->fields[FIELD_size]; + res->fields_mask[FIELD_dt >> 6] |= 1LL << (FIELD_dt & 63); + /* pcode: fmt_idx = (Q == '1') */ + res->fields[FIELD_fmt_idx] = ((res->fields[FIELD_Q]) == (0x1)); + res->fields_mask[FIELD_fmt_idx >> 6] |= 1LL << (FIELD_fmt_idx & 63); + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: A4ED12B5 +int vsubhn(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + res->group = INSN_GROUP_NEON; + /* Encoding T1 */ + /* pattern="1110,1111,1,D.1,size.2,Vn.4,Vd.4,0110,N.1,0,M.1,0,Vm.4" width=32 stringency=18 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFF800F50)==0xEF800600)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ADVSIMD)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_D] = (instr & 0x400000)>>22; + res->fields_mask[FIELD_D >> 6] |= 1LL << (FIELD_D & 63); + char D_width = 1; + res->fields[FIELD_size] = (instr & 0x300000)>>20; + res->fields_mask[FIELD_size >> 6] |= 1LL << (FIELD_size & 63); + char size_width = 2; + res->fields[FIELD_Vn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Vn >> 6] |= 1LL << (FIELD_Vn & 63); + char Vn_width = 4; + res->fields[FIELD_Vd] = (instr & 0xF000)>>12; + res->fields_mask[FIELD_Vd >> 6] |= 1LL << (FIELD_Vd & 63); + char Vd_width = 4; + res->fields[FIELD_N] = (instr & 0x80)>>7; + res->fields_mask[FIELD_N >> 6] |= 1LL << (FIELD_N & 63); + char N_width = 1; + res->fields[FIELD_M] = (instr & 0x20)>>5; + res->fields_mask[FIELD_M >> 6] |= 1LL << (FIELD_M & 63); + char M_width = 1; + res->fields[FIELD_Vm] = instr & 0xF; + res->fields_mask[FIELD_Vm >> 6] |= 1LL << (FIELD_Vm & 63); + char Vm_width = 4; + + static const instruction_format instr_formats[] = + { + { /* VSUBHN<c>.<dt> <Dd>,<Qn>,<Qm> */ + "vsubhn", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_VFP_DATA_SIZE, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_n,FIELD_UNINIT,"q","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_m,FIELD_UNINIT,"q","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_VSUBHN; + + /* pcode: if size == '11' then SEE advanced_simd_data_proc */ + if((res->fields[FIELD_size]) == (0x3)) { + + return advanced_simd_data_proc(req, res); + } + /* pcode: if Vn<0> == '1' || Vm<0> == '1' then UNDEFINED */ + if((((res->fields[FIELD_Vn] & 1)) == (0x1)) || (((res->fields[FIELD_Vm] & 1)) == (0x1))) { + res->status |= STATUS_UNDEFINED; + } + /* pcode: esize = 8 << UInt(size) */ + res->fields[FIELD_esize] = (8) << ((res->fields[FIELD_size])); + res->fields_mask[FIELD_esize >> 6] |= 1LL << (FIELD_esize & 63); + /* pcode: elements = 64 DIV esize */ + res->fields[FIELD_elements] = ((res->fields[FIELD_esize]) ? ((64) / (res->fields[FIELD_esize])) : 0); + res->fields_mask[FIELD_elements >> 6] |= 1LL << (FIELD_elements & 63); + /* pcode: d = UInt(D:Vd) */ + res->fields[FIELD_d] = ((res->fields[FIELD_D]<<Vd_width)|(res->fields[FIELD_Vd])); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: n = UInt(N:Vn) */ + res->fields[FIELD_n] = ((res->fields[FIELD_N]<<Vn_width)|(res->fields[FIELD_Vn])); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: m = UInt(M:Vm) */ + res->fields[FIELD_m] = ((res->fields[FIELD_M]<<Vm_width)|(res->fields[FIELD_Vm])); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + /* pcode: iword = TRUE */ + res->fields[FIELD_iword] = 1; + res->fields_mask[FIELD_iword >> 6] |= 1LL << (FIELD_iword & 63); + /* pcode: dt = size + 1 */ + res->fields[FIELD_dt] = (res->fields[FIELD_size]) + (1); + res->fields_mask[FIELD_dt >> 6] |= 1LL << (FIELD_dt & 63); + /* pcode: fmt_idx = (Q == '1') */ + res->fields[FIELD_fmt_idx] = ((res->fields[FIELD_Q]) == (0x1)); + res->fields_mask[FIELD_fmt_idx >> 6] |= 1LL << (FIELD_fmt_idx & 63); + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: 77BB2AE0 +int vsubl(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + res->group = INSN_GROUP_NEON; + /* Encoding T1 */ + /* pattern="111,U.1,1111,1,D.1,size.2,Vn.4,Vd.4,001,op.1,N.1,0,M.1,0,Vm.4" width=32 stringency=18 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xEF800E50)==0xEF800200)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ADVSIMD)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_U] = (instr & 0x10000000)>>28; + res->fields_mask[FIELD_U >> 6] |= 1LL << (FIELD_U & 63); + char U_width = 1; + res->fields[FIELD_D] = (instr & 0x400000)>>22; + res->fields_mask[FIELD_D >> 6] |= 1LL << (FIELD_D & 63); + char D_width = 1; + res->fields[FIELD_size] = (instr & 0x300000)>>20; + res->fields_mask[FIELD_size >> 6] |= 1LL << (FIELD_size & 63); + char size_width = 2; + res->fields[FIELD_Vn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Vn >> 6] |= 1LL << (FIELD_Vn & 63); + char Vn_width = 4; + res->fields[FIELD_Vd] = (instr & 0xF000)>>12; + res->fields_mask[FIELD_Vd >> 6] |= 1LL << (FIELD_Vd & 63); + char Vd_width = 4; + res->fields[FIELD_op] = (instr & 0x100)>>8; + res->fields_mask[FIELD_op >> 6] |= 1LL << (FIELD_op & 63); + char op_width = 1; + res->fields[FIELD_N] = (instr & 0x80)>>7; + res->fields_mask[FIELD_N >> 6] |= 1LL << (FIELD_N & 63); + char N_width = 1; + res->fields[FIELD_M] = (instr & 0x20)>>5; + res->fields_mask[FIELD_M >> 6] |= 1LL << (FIELD_M & 63); + char M_width = 1; + res->fields[FIELD_Vm] = instr & 0xF; + res->fields_mask[FIELD_Vm >> 6] |= 1LL << (FIELD_Vm & 63); + char Vm_width = 4; + + static const instruction_format instr_formats[] = + { + { /* VSUBL<c>.<dt> <Qd>,<Dn>,<Dm> */ + "vsubl", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_VFP_DATA_SIZE, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"q","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_n,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_m,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + { /* VSUBW<c>.<dt> <Qd>,<Qn>,<Dm> */ + "vsubw", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_VFP_DATA_SIZE, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"q","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_n,FIELD_UNINIT,"q","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_m,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 2; + res->mnem = armv7::ARMV7_VSUBL; + + /* pcode: if size == '11' then SEE advanced_simd_data_proc */ + if((res->fields[FIELD_size]) == (0x3)) { + + return advanced_simd_data_proc(req, res); + } + /* pcode: if Vd<0> == '1' || (op == '1' && Vn<0> == '1') then UNDEFINED */ + if((((res->fields[FIELD_Vd] & 1)) == (0x1)) || ((((res->fields[FIELD_op]) == (0x1)) && (((res->fields[FIELD_Vn] & 1)) == (0x1))))) { + res->status |= STATUS_UNDEFINED; + } + /* pcode: unsigned = (U == '1') */ + res->fields[FIELD_unsigned] = ((res->fields[FIELD_U]) == (0x1)); + res->fields_mask[FIELD_unsigned >> 6] |= 1LL << (FIELD_unsigned & 63); + /* pcode: esize = 8 << UInt(size) */ + res->fields[FIELD_esize] = (8) << ((res->fields[FIELD_size])); + res->fields_mask[FIELD_esize >> 6] |= 1LL << (FIELD_esize & 63); + /* pcode: elements = 64 DIV esize */ + res->fields[FIELD_elements] = ((res->fields[FIELD_esize]) ? ((64) / (res->fields[FIELD_esize])) : 0); + res->fields_mask[FIELD_elements >> 6] |= 1LL << (FIELD_elements & 63); + /* pcode: d = UInt(D:Vd) */ + res->fields[FIELD_d] = ((res->fields[FIELD_D]<<Vd_width)|(res->fields[FIELD_Vd])); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: n = UInt(N:Vn) */ + res->fields[FIELD_n] = ((res->fields[FIELD_N]<<Vn_width)|(res->fields[FIELD_Vn])); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: m = UInt(M:Vm) */ + res->fields[FIELD_m] = ((res->fields[FIELD_M]<<Vm_width)|(res->fields[FIELD_Vm])); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + /* pcode: dt = UInt(U:size) */ + res->fields[FIELD_dt] = ((res->fields[FIELD_U]<<size_width)|(res->fields[FIELD_size])); + res->fields_mask[FIELD_dt >> 6] |= 1LL << (FIELD_dt & 63); + /* pcode: fmt_idx = op */ + res->fields[FIELD_fmt_idx] = res->fields[FIELD_op]; + res->fields_mask[FIELD_fmt_idx >> 6] |= 1LL << (FIELD_fmt_idx & 63); + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: DB960356 +int vswp(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + res->group = INSN_GROUP_NEON; + /* Encoding T1 */ + /* pattern="1111,1111,1,D.1,11,size.2,10,Vd.4,0,0000,Q.1,M.1,0,Vm.4" width=32 stringency=22 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFFB30F90)==0xFFB20000)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ADVSIMD)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_D] = (instr & 0x400000)>>22; + res->fields_mask[FIELD_D >> 6] |= 1LL << (FIELD_D & 63); + char D_width = 1; + res->fields[FIELD_size] = (instr & 0xC0000)>>18; + res->fields_mask[FIELD_size >> 6] |= 1LL << (FIELD_size & 63); + char size_width = 2; + res->fields[FIELD_Vd] = (instr & 0xF000)>>12; + res->fields_mask[FIELD_Vd >> 6] |= 1LL << (FIELD_Vd & 63); + char Vd_width = 4; + res->fields[FIELD_Q] = (instr & 0x40)>>6; + res->fields_mask[FIELD_Q >> 6] |= 1LL << (FIELD_Q & 63); + char Q_width = 1; + res->fields[FIELD_M] = (instr & 0x20)>>5; + res->fields_mask[FIELD_M >> 6] |= 1LL << (FIELD_M & 63); + char M_width = 1; + res->fields[FIELD_Vm] = instr & 0xF; + res->fields_mask[FIELD_Vm >> 6] |= 1LL << (FIELD_Vm & 63); + char Vm_width = 4; + + static const instruction_format instr_formats[] = + { + { /* VSWP<c> <Dd>,<Dm> */ + "vswp", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_m,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + { /* VSWP<c> <Qd>,<Qm> */ + "vswp", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"q","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_m,FIELD_UNINIT,"q","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 2; + res->mnem = armv7::ARMV7_VSWP; + + /* pcode: if size != '00' then UNDEFINED */ + if((res->fields[FIELD_size]) != (0x0)) { + res->status |= STATUS_UNDEFINED; + } + /* pcode: if (Q == '1' && (Vd<0> == '1' || Vm<0> == '1')) then UNDEFINED */ + if((((res->fields[FIELD_Q]) == (0x1)) && (((((res->fields[FIELD_Vd] & 1)) == (0x1)) || (((res->fields[FIELD_Vm] & 1)) == (0x1)))))) { + res->status |= STATUS_UNDEFINED; + } + /* pcode: d = UInt(D:Vd) */ + res->fields[FIELD_d] = ((res->fields[FIELD_D]<<Vd_width)|(res->fields[FIELD_Vd])); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: m = UInt(M:Vm) */ + res->fields[FIELD_m] = ((res->fields[FIELD_M]<<Vm_width)|(res->fields[FIELD_Vm])); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + /* pcode: regs = if Q == '0' then 1 else 2 */ + if((res->fields[FIELD_Q]) == (0x0)) { + res->fields[FIELD_regs] = 1; + res->fields_mask[FIELD_regs >> 6] |= 1LL << (FIELD_regs & 63); + } + else { + res->fields[FIELD_regs] = 2; + res->fields_mask[FIELD_regs >> 6] |= 1LL << (FIELD_regs & 63); + } + /* pcode: fmt_idx = (Q == '1') */ + res->fields[FIELD_fmt_idx] = ((res->fields[FIELD_Q]) == (0x1)); + res->fields_mask[FIELD_fmt_idx >> 6] |= 1LL << (FIELD_fmt_idx & 63); + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: DA881311 +int vtbl(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + res->group = INSN_GROUP_NEON; + /* Encoding T1 */ + /* pattern="1111,xx11,1,D.1,11,Vn.4,Vd.4,10,len.2,N.1,op.1,M.1,0,Vm.4" width=32 stringency=16 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xF3B00C10)==0xF3B00800)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ADVSIMD)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_D] = (instr & 0x400000)>>22; + res->fields_mask[FIELD_D >> 6] |= 1LL << (FIELD_D & 63); + char D_width = 1; + res->fields[FIELD_Vn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Vn >> 6] |= 1LL << (FIELD_Vn & 63); + char Vn_width = 4; + res->fields[FIELD_Vd] = (instr & 0xF000)>>12; + res->fields_mask[FIELD_Vd >> 6] |= 1LL << (FIELD_Vd & 63); + char Vd_width = 4; + res->fields[FIELD_len] = (instr & 0x300)>>8; + res->fields_mask[FIELD_len >> 6] |= 1LL << (FIELD_len & 63); + char len_width = 2; + res->fields[FIELD_N] = (instr & 0x80)>>7; + res->fields_mask[FIELD_N >> 6] |= 1LL << (FIELD_N & 63); + char N_width = 1; + res->fields[FIELD_op] = (instr & 0x40)>>6; + res->fields_mask[FIELD_op >> 6] |= 1LL << (FIELD_op & 63); + char op_width = 1; + res->fields[FIELD_M] = (instr & 0x20)>>5; + res->fields_mask[FIELD_M >> 6] |= 1LL << (FIELD_M & 63); + char M_width = 1; + res->fields[FIELD_Vm] = instr & 0xF; + res->fields_mask[FIELD_Vm >> 6] |= 1LL << (FIELD_Vm & 63); + char Vm_width = 4; + + static const instruction_format instr_formats[] = + { + { /* VTBL<c>.8 <Dd>,<list>,<Dm> */ + "vtbl.8", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_LIST,FIELD_list,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG_FP,FIELD_m,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + { /* VTBX<c>.8 <Dd>,<list>,<Dm> */ + "vtbx.8", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_LIST,FIELD_list,FIELD_UNINIT,"","",WRITEBACK_NO}, + {OPERAND_FORMAT_REG_FP,FIELD_m,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 2; + res->mnem = armv7::ARMV7_VTBL; + + /* pcode: is_vtbl = (op == '0') */ + res->fields[FIELD_is_vtbl] = ((res->fields[FIELD_op]) == (0x0)); + res->fields_mask[FIELD_is_vtbl >> 6] |= 1LL << (FIELD_is_vtbl & 63); + /* pcode: length = UInt(len)+1 */ + res->fields[FIELD_length] = ((res->fields[FIELD_len])) + (1); + res->fields_mask[FIELD_length >> 6] |= 1LL << (FIELD_length & 63); + /* pcode: d = UInt(D:Vd) */ + res->fields[FIELD_d] = ((res->fields[FIELD_D]<<Vd_width)|(res->fields[FIELD_Vd])); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: n = UInt(N:Vn) */ + res->fields[FIELD_n] = ((res->fields[FIELD_N]<<Vn_width)|(res->fields[FIELD_Vn])); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: m = UInt(M:Vm) */ + res->fields[FIELD_m] = ((res->fields[FIELD_M]<<Vm_width)|(res->fields[FIELD_Vm])); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + /* pcode: if (n + length > 32) then UNPREDICTABLE */ + if(((res->fields[FIELD_n]) + ((res->fields[FIELD_length]) > (32)))) { + res->flags |= FLAG_UNPREDICTABLE; + } + /* pcode: fmt_idx = (op == '1') */ + res->fields[FIELD_fmt_idx] = ((res->fields[FIELD_op]) == (0x1)); + res->fields_mask[FIELD_fmt_idx >> 6] |= 1LL << (FIELD_fmt_idx & 63); + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: 6752D8F0 +int vtrn(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + res->group = INSN_GROUP_NEON; + /* Encoding T1 */ + /* pattern="1111,xx11,1,D.1,11,size.2,10,Vd.4,0000,1,Q.1,M.1,0,Vm.4" width=32 stringency=20 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xF3B30F90)==0xF3B20080)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ADVSIMD)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_D] = (instr & 0x400000)>>22; + res->fields_mask[FIELD_D >> 6] |= 1LL << (FIELD_D & 63); + char D_width = 1; + res->fields[FIELD_size] = (instr & 0xC0000)>>18; + res->fields_mask[FIELD_size >> 6] |= 1LL << (FIELD_size & 63); + char size_width = 2; + res->fields[FIELD_Vd] = (instr & 0xF000)>>12; + res->fields_mask[FIELD_Vd >> 6] |= 1LL << (FIELD_Vd & 63); + char Vd_width = 4; + res->fields[FIELD_Q] = (instr & 0x40)>>6; + res->fields_mask[FIELD_Q >> 6] |= 1LL << (FIELD_Q & 63); + char Q_width = 1; + res->fields[FIELD_M] = (instr & 0x20)>>5; + res->fields_mask[FIELD_M >> 6] |= 1LL << (FIELD_M & 63); + char M_width = 1; + res->fields[FIELD_Vm] = instr & 0xF; + res->fields_mask[FIELD_Vm >> 6] |= 1LL << (FIELD_Vm & 63); + char Vm_width = 4; + + static const instruction_format instr_formats[] = + { + { /* VTRN<c>.<size> <Dd>,<Dm> */ + "vtrn", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_NEON_SIZE, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_m,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + { /* VTRN<c>.<size> <Qd>,<Qm> */ + "vtrn", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_NEON_SIZE, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"q","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_m,FIELD_UNINIT,"q","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 2; + res->mnem = armv7::ARMV7_VTRN; + + /* pcode: if size == '11' then UNDEFINED */ + if((res->fields[FIELD_size]) == (0x3)) { + res->status |= STATUS_UNDEFINED; + } + /* pcode: if (Q == '1' && (Vd<0> == '1' || Vm<0> == '1')) then UNDEFINED */ + if((((res->fields[FIELD_Q]) == (0x1)) && (((((res->fields[FIELD_Vd] & 1)) == (0x1)) || (((res->fields[FIELD_Vm] & 1)) == (0x1)))))) { + res->status |= STATUS_UNDEFINED; + } + /* pcode: esize = 8 << UInt(size) */ + res->fields[FIELD_esize] = (8) << ((res->fields[FIELD_size])); + res->fields_mask[FIELD_esize >> 6] |= 1LL << (FIELD_esize & 63); + /* pcode: elements = 64 DIV esize */ + res->fields[FIELD_elements] = ((res->fields[FIELD_esize]) ? ((64) / (res->fields[FIELD_esize])) : 0); + res->fields_mask[FIELD_elements >> 6] |= 1LL << (FIELD_elements & 63); + /* pcode: d = UInt(D:Vd) */ + res->fields[FIELD_d] = ((res->fields[FIELD_D]<<Vd_width)|(res->fields[FIELD_Vd])); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: m = UInt(M:Vm) */ + res->fields[FIELD_m] = ((res->fields[FIELD_M]<<Vm_width)|(res->fields[FIELD_Vm])); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + /* pcode: regs = if Q == '0' then 1 else 2 */ + if((res->fields[FIELD_Q]) == (0x0)) { + res->fields[FIELD_regs] = 1; + res->fields_mask[FIELD_regs >> 6] |= 1LL << (FIELD_regs & 63); + } + else { + res->fields[FIELD_regs] = 2; + res->fields_mask[FIELD_regs >> 6] |= 1LL << (FIELD_regs & 63); + } + /* pcode: fmt_idx = (Q == '1') */ + res->fields[FIELD_fmt_idx] = ((res->fields[FIELD_Q]) == (0x1)); + res->fields_mask[FIELD_fmt_idx >> 6] |= 1LL << (FIELD_fmt_idx & 63); + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: 62629263 +int vtst(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + res->group = INSN_GROUP_NEON; + /* Encoding T1 */ + /* pattern="1110,1111,0,D.1,size.2,Vn.4,Vd.4,1000,N.1,Q.1,M.1,1,Vm.4" width=32 stringency=18 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFF800F10)==0xEF000810)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ADVSIMD)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_D] = (instr & 0x400000)>>22; + res->fields_mask[FIELD_D >> 6] |= 1LL << (FIELD_D & 63); + char D_width = 1; + res->fields[FIELD_size] = (instr & 0x300000)>>20; + res->fields_mask[FIELD_size >> 6] |= 1LL << (FIELD_size & 63); + char size_width = 2; + res->fields[FIELD_Vn] = (instr & 0xF0000)>>16; + res->fields_mask[FIELD_Vn >> 6] |= 1LL << (FIELD_Vn & 63); + char Vn_width = 4; + res->fields[FIELD_Vd] = (instr & 0xF000)>>12; + res->fields_mask[FIELD_Vd >> 6] |= 1LL << (FIELD_Vd & 63); + char Vd_width = 4; + res->fields[FIELD_N] = (instr & 0x80)>>7; + res->fields_mask[FIELD_N >> 6] |= 1LL << (FIELD_N & 63); + char N_width = 1; + res->fields[FIELD_Q] = (instr & 0x40)>>6; + res->fields_mask[FIELD_Q >> 6] |= 1LL << (FIELD_Q & 63); + char Q_width = 1; + res->fields[FIELD_M] = (instr & 0x20)>>5; + res->fields_mask[FIELD_M >> 6] |= 1LL << (FIELD_M & 63); + char M_width = 1; + res->fields[FIELD_Vm] = instr & 0xF; + res->fields_mask[FIELD_Vm >> 6] |= 1LL << (FIELD_Vm & 63); + char Vm_width = 4; + + static const instruction_format instr_formats[] = + { + { /* VTST<c>.<size> <Dd>,<Dn>,<Dm> */ + "vtst", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_NEON_SIZE, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_n,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_m,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + { /* VTST<c>.<size> <Qd>,<Qn>,<Qm> */ + "vtst", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_NEON_SIZE, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"q","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_n,FIELD_UNINIT,"q","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_m,FIELD_UNINIT,"q","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 3 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 2; + res->mnem = armv7::ARMV7_VTST; + + /* pcode: if Q == '1' && (Vd<0> == '1' || Vn<0> == '1' || Vm<0> == '1') then UNDEFINED */ + if(((res->fields[FIELD_Q]) == (0x1)) && ((((((res->fields[FIELD_Vd] & 1)) == (0x1)) || (((res->fields[FIELD_Vn] & 1)) == (0x1))) || (((res->fields[FIELD_Vm] & 1)) == (0x1))))) { + res->status |= STATUS_UNDEFINED; + } + /* pcode: if size == '11' then UNDEFINED */ + if((res->fields[FIELD_size]) == (0x3)) { + res->status |= STATUS_UNDEFINED; + } + /* pcode: esize = 8 << UInt(size) */ + res->fields[FIELD_esize] = (8) << ((res->fields[FIELD_size])); + res->fields_mask[FIELD_esize >> 6] |= 1LL << (FIELD_esize & 63); + /* pcode: elements = 64 DIV esize */ + res->fields[FIELD_elements] = ((res->fields[FIELD_esize]) ? ((64) / (res->fields[FIELD_esize])) : 0); + res->fields_mask[FIELD_elements >> 6] |= 1LL << (FIELD_elements & 63); + /* pcode: d = UInt(D:Vd) */ + res->fields[FIELD_d] = ((res->fields[FIELD_D]<<Vd_width)|(res->fields[FIELD_Vd])); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: n = UInt(N:Vn) */ + res->fields[FIELD_n] = ((res->fields[FIELD_N]<<Vn_width)|(res->fields[FIELD_Vn])); + res->fields_mask[FIELD_n >> 6] |= 1LL << (FIELD_n & 63); + /* pcode: m = UInt(M:Vm) */ + res->fields[FIELD_m] = ((res->fields[FIELD_M]<<Vm_width)|(res->fields[FIELD_Vm])); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + /* pcode: regs = if Q == '0' then 1 else 2 */ + if((res->fields[FIELD_Q]) == (0x0)) { + res->fields[FIELD_regs] = 1; + res->fields_mask[FIELD_regs >> 6] |= 1LL << (FIELD_regs & 63); + } + else { + res->fields[FIELD_regs] = 2; + res->fields_mask[FIELD_regs >> 6] |= 1LL << (FIELD_regs & 63); + } + /* pcode: fmt_idx = (Q == '1') */ + res->fields[FIELD_fmt_idx] = ((res->fields[FIELD_Q]) == (0x1)); + res->fields_mask[FIELD_fmt_idx >> 6] |= 1LL << (FIELD_fmt_idx & 63); + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: 807A756C +int vuzp(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + res->group = INSN_GROUP_NEON; + /* Encoding T1 */ + /* pattern="1111,xx11,1,D.1,11,size.2,10,Vd.4,0001,0,Q.1,M.1,0,Vm.4" width=32 stringency=20 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xF3B30F90)==0xF3B20100)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ADVSIMD)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_D] = (instr & 0x400000)>>22; + res->fields_mask[FIELD_D >> 6] |= 1LL << (FIELD_D & 63); + char D_width = 1; + res->fields[FIELD_size] = (instr & 0xC0000)>>18; + res->fields_mask[FIELD_size >> 6] |= 1LL << (FIELD_size & 63); + char size_width = 2; + res->fields[FIELD_Vd] = (instr & 0xF000)>>12; + res->fields_mask[FIELD_Vd >> 6] |= 1LL << (FIELD_Vd & 63); + char Vd_width = 4; + res->fields[FIELD_Q] = (instr & 0x40)>>6; + res->fields_mask[FIELD_Q >> 6] |= 1LL << (FIELD_Q & 63); + char Q_width = 1; + res->fields[FIELD_M] = (instr & 0x20)>>5; + res->fields_mask[FIELD_M >> 6] |= 1LL << (FIELD_M & 63); + char M_width = 1; + res->fields[FIELD_Vm] = instr & 0xF; + res->fields_mask[FIELD_Vm >> 6] |= 1LL << (FIELD_Vm & 63); + char Vm_width = 4; + + static const instruction_format instr_formats[] = + { + { /* VUZP<c>.<size> <Dd>,<Dm> */ + "vuzp", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_NEON_SIZE, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_m,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + { /* VUZP<c>.<size> <Qd>,<Qm> */ + "vuzp", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_NEON_SIZE, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"q","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_m,FIELD_UNINIT,"q","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 2; + res->mnem = armv7::ARMV7_VUZP; + + /* pcode: if (size == '11' || (Q == '0' && size == '10')) then UNDEFINED */ + if((((res->fields[FIELD_size]) == (0x3)) || ((((res->fields[FIELD_Q]) == (0x0)) && ((res->fields[FIELD_size]) == (0x2)))))) { + res->status |= STATUS_UNDEFINED; + } + /* pcode: if (Q == '1' && (Vd<0> == '1' || Vm<0> == '1')) then UNDEFINED */ + if((((res->fields[FIELD_Q]) == (0x1)) && (((((res->fields[FIELD_Vd] & 1)) == (0x1)) || (((res->fields[FIELD_Vm] & 1)) == (0x1)))))) { + res->status |= STATUS_UNDEFINED; + } + /* pcode: quadword_operation = (Q == '1') */ + res->fields[FIELD_quadword_operation] = ((res->fields[FIELD_Q]) == (0x1)); + res->fields_mask[FIELD_quadword_operation >> 6] |= 1LL << (FIELD_quadword_operation & 63); + /* pcode: esize = 8 << UInt(size) */ + res->fields[FIELD_esize] = (8) << ((res->fields[FIELD_size])); + res->fields_mask[FIELD_esize >> 6] |= 1LL << (FIELD_esize & 63); + /* pcode: d = UInt(D:Vd) */ + res->fields[FIELD_d] = ((res->fields[FIELD_D]<<Vd_width)|(res->fields[FIELD_Vd])); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: m = UInt(M:Vm) */ + res->fields[FIELD_m] = ((res->fields[FIELD_M]<<Vm_width)|(res->fields[FIELD_Vm])); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + /* pcode: fmt_idx = (Q == '1') */ + res->fields[FIELD_fmt_idx] = ((res->fields[FIELD_Q]) == (0x1)); + res->fields_mask[FIELD_fmt_idx >> 6] |= 1LL << (FIELD_fmt_idx & 63); + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: 60253677 +int vzip(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + res->group = INSN_GROUP_NEON; + /* Encoding T1 */ + /* pattern="1111,xx11,1,D.1,11,size.2,10,Vd.4,0001,1,Q.1,M.1,0,Vm.4" width=32 stringency=20 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xF3B30F90)==0xF3B20180)) { + res->instrSize = 32; + if(!(req->arch & ARCH_ADVSIMD)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + res->fields[FIELD_D] = (instr & 0x400000)>>22; + res->fields_mask[FIELD_D >> 6] |= 1LL << (FIELD_D & 63); + char D_width = 1; + res->fields[FIELD_size] = (instr & 0xC0000)>>18; + res->fields_mask[FIELD_size >> 6] |= 1LL << (FIELD_size & 63); + char size_width = 2; + res->fields[FIELD_Vd] = (instr & 0xF000)>>12; + res->fields_mask[FIELD_Vd >> 6] |= 1LL << (FIELD_Vd & 63); + char Vd_width = 4; + res->fields[FIELD_Q] = (instr & 0x40)>>6; + res->fields_mask[FIELD_Q >> 6] |= 1LL << (FIELD_Q & 63); + char Q_width = 1; + res->fields[FIELD_M] = (instr & 0x20)>>5; + res->fields_mask[FIELD_M >> 6] |= 1LL << (FIELD_M & 63); + char M_width = 1; + res->fields[FIELD_Vm] = instr & 0xF; + res->fields_mask[FIELD_Vm >> 6] |= 1LL << (FIELD_Vm & 63); + char Vm_width = 4; + + static const instruction_format instr_formats[] = + { + { /* VZIP<c>.<size> <Dd>,<Dm> */ + "vzip", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_NEON_SIZE, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_m,FIELD_UNINIT,"d","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + { /* VZIP<c>.<size> <Qd>,<Qm> */ + "vzip", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_NEON_SIZE, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_REG_FP,FIELD_d,FIELD_UNINIT,"q","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_REG_FP,FIELD_m,FIELD_UNINIT,"q","",WRITEBACK_OPTIONAL}, + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 2 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 2; + res->mnem = armv7::ARMV7_VZIP; + + /* pcode: if (size == '11' || (Q == '0' && size == '10')) then UNDEFINED */ + if((((res->fields[FIELD_size]) == (0x3)) || ((((res->fields[FIELD_Q]) == (0x0)) && ((res->fields[FIELD_size]) == (0x2)))))) { + res->status |= STATUS_UNDEFINED; + } + /* pcode: if (Q == '1' && (Vd<0> == '1' || Vm<0> == '1')) then UNDEFINED */ + if((((res->fields[FIELD_Q]) == (0x1)) && (((((res->fields[FIELD_Vd] & 1)) == (0x1)) || (((res->fields[FIELD_Vm] & 1)) == (0x1)))))) { + res->status |= STATUS_UNDEFINED; + } + /* pcode: quadword_operation = (Q == '1') */ + res->fields[FIELD_quadword_operation] = ((res->fields[FIELD_Q]) == (0x1)); + res->fields_mask[FIELD_quadword_operation >> 6] |= 1LL << (FIELD_quadword_operation & 63); + /* pcode: esize = 8 << UInt(size) */ + res->fields[FIELD_esize] = (8) << ((res->fields[FIELD_size])); + res->fields_mask[FIELD_esize >> 6] |= 1LL << (FIELD_esize & 63); + /* pcode: d = UInt(D:Vd) */ + res->fields[FIELD_d] = ((res->fields[FIELD_D]<<Vd_width)|(res->fields[FIELD_Vd])); + res->fields_mask[FIELD_d >> 6] |= 1LL << (FIELD_d & 63); + /* pcode: m = UInt(M:Vm) */ + res->fields[FIELD_m] = ((res->fields[FIELD_M]<<Vm_width)|(res->fields[FIELD_Vm])); + res->fields_mask[FIELD_m >> 6] |= 1LL << (FIELD_m & 63); + /* pcode: fmt_idx = (Q == '1') */ + res->fields[FIELD_fmt_idx] = ((res->fields[FIELD_Q]) == (0x1)); + res->fields_mask[FIELD_fmt_idx >> 6] |= 1LL << (FIELD_fmt_idx & 63); + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: 10C09F53 +int wfe(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + /* Encoding T1 */ + /* pattern="1011,1111,0010,0000" width=16 stringency=16 */ + { + uint16_t instr = req->instr_word16; + if(((instr & 0xFFFF)==0xBF20)) { + res->instrSize = 16; + if(!(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + static const instruction_format instr_formats[] = + { + { /* WFE<c> */ + "wfe", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 0 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_WFE; + + /* pcode: nop */ + while(0); + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* Encoding T2 */ + /* pattern="11110,0,111,01,0,(1)(1)(1)(1),10,(0),0,(0),000,00000010" width=32 stringency=32 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFFF0D7FF)==0xF3A08002)) { + res->instrSize = 32; + if(!((instr & 0xF2800)==0xF0000)) { + res->flags |= FLAG_UNPREDICTABLE; + } + if(!(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + static const instruction_format instr_formats[] = + { + { /* WFE<c>.W */ + "wfe", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_WIDE, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 0 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_WFE; + + /* pcode: nop */ + while(0); + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: 0899202A +int wfi(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + /* Encoding T1 */ + /* pattern="1011,1111,0011,0000" width=16 stringency=16 */ + { + uint16_t instr = req->instr_word16; + if(((instr & 0xFFFF)==0xBF30)) { + res->instrSize = 16; + if(!(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + static const instruction_format instr_formats[] = + { + { /* WFI<c> */ + "wfi", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 0 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_WFI; + + /* pcode: nop */ + while(0); + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* Encoding T2 */ + /* pattern="11110,0,111,01,0,(1)(1)(1)(1),10,(0),0,(0),000,00000011" width=32 stringency=32 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFFF0D7FF)==0xF3A08003)) { + res->instrSize = 32; + if(!((instr & 0xF2800)==0xF0000)) { + res->flags |= FLAG_UNPREDICTABLE; + } + if(!(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + static const instruction_format instr_formats[] = + { + { /* WFI<c>.W */ + "wfi", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_WIDE, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 0 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_WFI; + + /* pcode: nop */ + while(0); + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + +// gen_crc: 48D60D22 +int xfer_64_core_ext_regs(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + uint32_t instr = req->instr_word32; + uint32_t T = (instr & 0x10000000)>>28; + uint32_t C = (instr & 0x100)>>8; + uint32_t op = (instr & 0xF0)>>4; + if(((C & 0x1)==0x0) && ((op & 0xD)==0x1)) return vmov_core_two_single(req, res); + if(((C & 0x1)==0x1) && ((op & 0xD)==0x1)) return vmov_core_double(req, res); + return undefined(req, res); +} + +// gen_crc: C4A9A5AC +int xfer_8_16_32_core_extension(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + uint32_t instr = req->instr_word32; + uint32_t T = (instr & 0x10000000)>>28; + uint32_t A = (instr & 0xE00000)>>21; + uint32_t L = (instr & 0x100000)>>20; + uint32_t C = (instr & 0x100)>>8; + uint32_t B = (instr & 0x60)>>5; + if(((L & 0x1)==0x0) && ((C & 0x1)==0x0) && ((A & 0x7)==0x0) && 1) return vmov_core_single(req, res); + if(((L & 0x1)==0x0) && ((C & 0x1)==0x0) && ((A & 0x7)==0x7) && 1) return vmsr(req, res); + if(((L & 0x1)==0x1) && ((C & 0x1)==0x0) && ((A & 0x7)==0x0) && 1) return vmov_core_single(req, res); + if(((L & 0x1)==0x1) && ((C & 0x1)==0x0) && ((A & 0x7)==0x7) && 1) return vmrs(req, res); + if(((L & 0x1)==0x0) && ((C & 0x1)==0x1) && ((A & 0x4)==0x4) && ((B & 0x2)==0x0)) return vdup_register(req, res); + if(((L & 0x1)==0x0) && ((C & 0x1)==0x1) && ((A & 0x4)==0x0) && 1) return vmov_core_scalar(req, res); + if(((L & 0x1)==0x1) && ((C & 0x1)==0x1) && 1) return vmov_scalar_core(req, res); + return undefined(req, res); +} + +// gen_crc: 9CE624A5 +int yield(struct decomp_request *req, struct decomp_result *res) +{ + int rc = -1; + + res->group = INSN_GROUP_UNKNOWN; + /* Encoding T1 */ + /* pattern="1011,1111,0001,0000" width=16 stringency=16 */ + { + uint16_t instr = req->instr_word16; + if(((instr & 0xFFFF)==0xBF10)) { + res->instrSize = 16; + if(!(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + static const instruction_format instr_formats[] = + { + { /* YIELD<c> */ + "yield", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 0 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_YIELD; + + /* pcode: nop */ + while(0); + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* Encoding T2 */ + /* pattern="11110,0,111,01,0,(1)(1)(1)(1),10,(0),0,(0),000,00000001" width=32 stringency=32 */ + { + uint32_t instr = req->instr_word32; + if(((instr & 0xFFF0D7FF)==0xF3A08001)) { + res->instrSize = 32; + if(!((instr & 0xF2800)==0xF0000)) { + res->flags |= FLAG_UNPREDICTABLE; + } + if(!(req->arch & ARCH_ARMv7)) { + res->status |= STATUS_ARCH_UNSUPPORTED; + } + res->fields[FIELD_cond] = COND_AL; + res->fields_mask[FIELD_cond >> 6] |= 1LL << (FIELD_cond & 63); + static const instruction_format instr_formats[] = + { + { /* YIELD<c>.W */ + "yield", /* .operation (const char *) */ + 0|INSTR_FORMAT_FLAG_CONDITIONAL|INSTR_FORMAT_FLAG_WIDE, /* .operationFlags (uint32_t) */ + {/* .operands (instruction_operand_format) */ + {OPERAND_FORMAT_END,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO}, + }, + 0 /* .operandCount */ + }, + }; /* ENDS instruction_format array */ + + res->formats = instr_formats; + res->formatCount = 1; + res->mnem = armv7::ARMV7_YIELD; + + /* pcode: nop */ + while(0); + + return success(); + } /* ENDS if(<encoding_match_test>) ... */ + } /* ENDS single encoding block */ + + /* if fall-thru here, no encoding block matched */ + return undefined(req, res); +} + + + +#if defined(__clang__) +#pragma clang diagnostic pop +#elif defined(__GNUC__) +#pragma GCC diagnostic pop +#endif |
