#include #include #include #include #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" #pragma clang diagnostic ignored "-Wparentheses-equality" #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" #pragma GCC diagnostic ignored "-Wparentheses-equality" #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< bit_width) ? str_width - bit_width : 0; for(int i=0; i 32) bit_width = 32; for(int i=bit_width-1; i>=0; --i) printf("%c", (val & (1<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} ,,# */ "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() ... */ } /* 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 , */ "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 , */ "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() ... */ } /* 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} ,,{,} */ "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() ... */ } /* 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 ,,# */ "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 ,,# */ "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() ... */ } /* 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 ,# */ "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 ,# */ "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() ... */ } /* 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} ,,# */ "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() ... */ } /* 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 ,,# */ "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() ... */ } /* 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 ,, */ "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 ,, */ "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() ... */ } /* 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 , */ "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]<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]<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]<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() ... */ } /* 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} ,,{,} */ "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() ... */ } /* 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 ,SP,# */ "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() ... */ } /* 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 SP,# */ "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() ... */ } /* 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} ,SP,# */ "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() ... */ } /* 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 ,SP,# */ "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() ... */ } /* 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 ,SP, */ "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]<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]<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() ... */ } /* 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 SP, */ "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() ... */ } /* 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} ,SP,{,} */ "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() ... */ } /* 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 ,# */ "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() ... */ } /* 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 ,PC,# */ "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() ... */ } /* 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 ,PC,# */ "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() ... */ } /* 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} ,,# */ "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() ... */ } /* 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 , */ "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 , */ "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() ... */ } /* 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} ,,{,} */ "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() ... */ } /* 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 ,,# */ "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 ,,# */ "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() ... */ } /* 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} ,,# */ "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() ... */ } /* 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 , */ "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 , */ "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() ... */ } /* 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} ,, */ "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() ... */ } /* 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 # */ "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() ... */ } /* 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 # */ "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() ... */ } /* 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 # */ "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() ... */ } /* 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 # */ "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() ... */ } /* 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 ,#,# */ "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() ... */ } /* 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 ,,#,# */ "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() ... */ } /* 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} ,,# */ "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() ... */ } /* 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 , */ "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 , */ "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() ... */ } /* 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} ,,{,} */ "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() ... */ } /* 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 # */ "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() ... */ } /* 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 # */ "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() ... */ } /* 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 # */ "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() ... */ } /* 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 # */ "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() ... */ } /* 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 # */ "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() ... */ } /* 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 */ "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() ... */ } /* 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 */ "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() ... */ } /* 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 */ "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() ... */ } /* 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 ,# */ "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() ... */ } /* 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 ,# */ "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() ... */ } /* 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 ,#,,,,# */ "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() ... */ } /* 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 ,#,,,,# */ "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() ... */ } /* 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 */ "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() ... */ } /* 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 , */ "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() ... */ } /* 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 ,# */ "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() ... */ } /* 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 , */ "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() ... */ } /* 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 ,{,} */ "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() ... */ } /* 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 ,# */ "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() ... */ } /* 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 ,# */ "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() ... */ } /* 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 , */ "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() ... */ } /* 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 , */ "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]<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]<fields[FIELD_Rn])); res->fields_mask[FIELD_Rn >> 6] |= 1LL << (FIELD_Rn & 63); return success(); } /* ENDS if() ... */ } /* 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 ,{,} */ "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() ... */ } /* 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 */ "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() ... */ } /* 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 {,#} */ "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]<fields[FIELD_F])) == (0x0)))) || ((((((res->fields[FIELD_imod] >> 1) & 1)) == (0x0)) && (((res->fields[FIELD_A]<<(F_width+I_width))|(res->fields[FIELD_I]<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() ... */ } /* 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 #