diff options
| author | Rusty Wagner <rusty.wagner@gmail.com> | 2024-03-05 19:50:13 -0500 |
|---|---|---|
| committer | Rusty Wagner <rusty.wagner@gmail.com> | 2024-03-05 20:34:34 -0500 |
| commit | e093c21ed880ac3eb72119be15093ee04f8ce299 (patch) | |
| tree | 9f720ebdc0ae415734b1199ed341668c69710a94 /arch/armv7/thumb2_disasm/spec.txt | |
| parent | 0609276712622908254065546102381466033141 (diff) | |
Move architecture modules into the API repo
Diffstat (limited to 'arch/armv7/thumb2_disasm/spec.txt')
| -rw-r--r-- | arch/armv7/thumb2_disasm/spec.txt | 6535 |
1 files changed, 6535 insertions, 0 deletions
diff --git a/arch/armv7/thumb2_disasm/spec.txt b/arch/armv7/thumb2_disasm/spec.txt new file mode 100644 index 00000000..ebb5932d --- /dev/null +++ b/arch/armv7/thumb2_disasm/spec.txt @@ -0,0 +1,6535 @@ +//----------------------------------------------------------------------------- +// decide thumb16 (thumb1, thumb2), thumb32 (thumb2), roots of each +//----------------------------------------------------------------------------- + +thumb_root: +extract16 tmp.5 +on tmp +11101 thumb32 +11110 thumb32 +11111 thumb32 +xxxxx thumb16 + +thumb32: +extract32 111,op1.2,op2.7,xxxx,op.1,xxxxxxxxxxxxxxx +on op1,op2,op +01,00xx0xx,x load_store_multiple +01,00xx1xx,x load_store_dual_exclusive_table_branch +01,01xxxxx,x data_processing_shifted_register +01,1xxxxxx,x coprocessor_instructions +10,x0xxxxx,0 data_processing_modified_immediate +10,x1xxxxx,0 data_processing_plain_binary_immediate +10,xxxxxxx,1 branches_misc_control +11,000xxx0,x store_single_data_item +11,001xxx0,x advanced_simd_elem_struct_load_store +11,00xx001,x load_byte_mem_hint +11,00xx011,x load_halfword_mem_hint +11,00xx101,x load_word +11,00xx111,x undefined +11,010xxxx,x data_processing_register +11,0110xxx,x mul_accumulate_absolute_difference +11,0111xxx,x long_mul_accumulate_divide +11,1xxxxxx,x coprocessor_instructions + +thumb16: +extract16 Opcode.6 +on Opcode +00xxxx shift_immediate_add_sub_mov_cmp +010000 data_proc +010001 spcl_data_branch_exch +01001x load_lit_pool +0101xx load_store_single_data +011xxx load_store_single_data +100xxx load_store_single_data +10100x adr +10101x add_sp_plus_immediate +1011xx misc +11000x stm +11001x ldm +1101xx cond_branch_superv_call +11100x b + +//----------------------------------------------------------------------------- +// thumb32, level 1 +//----------------------------------------------------------------------------- + +load_store_multiple: +extract32 111,0100,op.2,0,W.1,L.1,Rn.4,xxxxxxxxxxxxxxxx +on op,L,W,Rn +00,0,x,xxxx srs +00,1,x,xxxx rfe +// +01,0,x,xxxx stm +01,1,0,xxxx ldm +01,1,1,~1101 ldm +01,1,1,1101 pop +// +10,0,x,xxxx stmdb +10,0,1,1101 push +10,1,x,xxxx ldmdb +// +11,0,x,xxxx srs +11,1,x,xxxx rfe + +load_store_dual_exclusive_table_branch: +extract32 111,0100,op1.2,1,op2.2,Rn.4,xxxxxxxx,op3.4 +on op1,op2,op3,Rn +00,00,xxxx,xxxx strex +00,01,xxxx,xxxx ldrex +0x,10,xxxx,xxxx strd_immediate +1x,x0,xxxx,xxxx strd_immediate +0x,11,xxxx,~1111 ldrd_immediate +1x,x1,xxxx,~1111 ldrd_immediate +0x,11,xxxx,1111 ldrd_literal +1x,x1,xxxx,1111 ldrd_literal +01,00,0100,xxxx strexb +01,00,0101,xxxx strexh +01,00,0111,xxxx strexd +01,01,0000,xxxx tbb_tbh +01,01,0001,xxxx tbb_tbh +01,01,0100,xxxx ldrexb +01,01,0101,xxxx ldrexh +01,01,0111,xxxx ldrexd +01,00,1000,xxxx stlb +01,00,1001,xxxx stlh +01,00,1010,xxxx stl +01,00,1100,xxxx stlexb +01,00,1101,xxxx stlexh +01,00,1110,xxxx stlex +01,01,1000,xxxx ldab +01,01,1001,xxxx ldah +01,01,1010,xxxx lda +01,01,1100,xxxx ldaexb +01,01,1101,xxxx ldaexh +01,01,1110,xxxx ldaex + +// wookie is the imm3:Rd:imm2 from errata markup, necessary +// for subtable decoding +data_processing_shifted_register: +extract32 111,0101,op.4,S.1,Rn.4,x,wookie.9,type.2,xxxx +on op,Rn,wookie,S,type +0000,xxxx,~xxx1111xx,x,xx and_register +0000,xxxx,xxx1111xx,0,xx unpredictable +0000,xxxx,xxx1111xx,1,xx tst_register +0001,xxxx,xxxxxxxxx,x,xx bic_register +0010,~1111,xxxxxxxxx,x,xx orr_register +// <errata_mov_subtable> +0010,1111,000xxxx00,x,00 mov_register +0010,1111,~000xxxx00,x,00 lsl_immediate +0010,1111,xxxxxxxxx,x,01 lsr_immediate +0010,1111,xxxxxxxxx,x,10 asr_immediate +0010,1111,000xxxx00,x,11 rrx +0010,1111,~000xxxx00,x,11 ror_immediate +// </errata_mov_subtable> +0011,~1111,xxxxxxxxx,x,xx orn_register +0011,1111,xxxxxxxxx,x,xx mvn_register +0100,xxxx,~xxx1111xx,x,xx eor_register +0100,xxxx,xxx1111xx,0,xx unpredictable +0100,xxxx,xxx1111xx,1,xx teq_register +0110,xxxx,xxxxxxxxx,x,xx pkh +1000,xxxx,~xxx1111xx,x,xx add_register +xxxx,xxxx,xxx1111xx,0,xx unpredictable +1000,xxxx,xxx1111xx,1,xx cmn_register +1010,xxxx,xxxxxxxxx,x,xx adc_register +1011,xxxx,xxxxxxxxx,x,xx sbc_register +1101,xxxx,~xxx1111xx,x,xx sub_register +1101,xxxx,xxx1111xx,0,xx unpredictable +1101,xxxx,xxx1111xx,1,xx cmp_register +1110,xxxx,xxxxxxxxx,x,xx rsb_register + +data_processing_modified_immediate: +extract32 111,10,x,0,op.4,S.1,Rn.4,0,xxx,Rd.4,xxxxxxxx +on op,Rn,Rd,S +0000,xxxx,~1111,x and_immediate +0000,xxxx,1111,0 unpredictable +0000,xxxx,1111,1 tst_immediate +0001,xxxx,xxxx,x bic_immediate +0010,~1111,xxxx,x orr_immediate +0010,1111,xxxx,x mov_immediate +0011,~1111,xxxx,x orn_immediate +0011,1111,xxxx,x mvn_immediate +0100,xxxx,~1111,x eor_immediate +0100,xxxx,1111,0 unpredictable +0100,xxxx,1111,1 teq_immediate +1000,xxxx,~1111,x add_immediate +1000,xxxx,1111,0 unpredictable +1000,xxxx,1111,1 cmn_immediate +1010,xxxx,xxxx,x adc_immediate +1011,xxxx,xxxx,x sbc_immediate +1101,xxxx,~1111,x sub_immediate +1101,xxxx,1111,0 unpredictable +1101,xxxx,1111,1 cmp_immediate +1110,xxxx,xxxx,x rsb_immediate + +// wookie captures b14..12 and b7..6 to implement the "a." and "b." footnotes +// near bottom of A6.3.3 +data_processing_plain_binary_immediate: +extract32 111,10,x,1,op.5,Rn.4,0,wookie.9,xxxxxx +on op,Rn,wookie +00000,~1111,xxxxxxxxx add_immediate +00000,1111,xxxxxxxxx adr +00100,xxxx,xxxxxxxxx mov_immediate +01010,~1111,xxxxxxxxx sub_immediate +01010,1111,xxxxxxxxx adr +01100,xxxx,xxxxxxxxx movt +100x0,xxxx,xxxxxxxxx ssat +10010,xxxx,000xxxx00 ssat16 +10100,xxxx,xxxxxxxxx sbfx +10110,~1111,xxxxxxxxx bfi +10110,1111,xxxxxxxxx bfc +110x0,xxxx,xxxxxxxxx usat +11010,xxxx,000xxxx00 usat16 +11100,xxxx,xxxxxxxxx ubfx + +branches_misc_control: +extract32 111,10,op.7,xxxx,1,op1.3,op2.4,xxxxxxxx +on op1,op,op2 +0x0,~x111xxx,xxxx b +000,0111000,xx00 msr_reg_app +000,0111000,xx01 msr_reg_sys +000,0111000,xx1x msr_reg_sys +000,0111001,xxxx msr_reg_sys +000,0111010,xxxx change_proc_state_and_hints +000,0111011,xxxx misc_control +000,0111100,xxxx bxj +000,0111101,xxxx subs_pc_lr_related +000,011111x,xxxx mrs +000,1111111,xxxx smc +010,1111111,xxxx undefined +0x1,xxxxxxx,xxxx b +1x0,xxxxxxx,xxxx bl_blx_immediate +1x1,xxxxxxx,xxxx bl_blx_immediate + +store_single_data_item: +extract32 111,1100,0,op1.3,0,xxxx,xxxx,op2.6,xxxxxx +on op1,op2 +100,xxxxxx strb_immediate +000,1xx1xx strb_immediate +000,1100xx strb_immediate +000,1110xx strbt +000,0xxxxx strb_register +101,xxxxxx strh_immediate +001,1xx1xx strh_immediate +001,1100xx strh_immediate +001,1110xx strht +001,0xxxxx strh_register +110,xxxxxx str_immediate +010,1xx1xx str_immediate +010,1100xx str_immediate +010,1110xx strt +010,0xxxxx str_register + +coprocessor_instructions: +extract32 111,x,11,op1.6,Rn.4,xxxx,coproc.4,xxx,op.1,xxxx +on op1,op,coproc,Rn +000x1x,x,101x,xxxx extension_reg_load_store +001xxx,x,101x,xxxx extension_reg_load_store +01xxxx,x,101x,xxxx extension_reg_load_store +000x10,x,~101x,xxxx stc_stc2 +001xx0,x,~101x,xxxx stc_stc2 +01xxx0,x,~101x,xxxx stc_stc2 +000x11,x,~101x,~1111 ldc_immediate +001xx1,x,~101x,~1111 ldc_immediate +01xxx1,x,~101x,~1111 ldc_immediate +000x11,x,~101x,1111 ldc_literal +001xx1,x,~101x,1111 ldc_literal +01xxx1,x,~101x,1111 ldc_literal +00000x,x,xxxx,xxxx undefined +00010x,x,101x,xxxx xfer_64_core_ext_regs +000100,x,~101x,xxxx mcrr_mcrr2 +000101,x,~101x,xxxx mrrc_mrrc2 +10xxxx,0,101x,xxxx vfp_data_proc +10xxxx,0,~101x,xxxx cdp_cdp2 +10xxxx,1,101x,xxxx xfer_8_16_32_core_extension +10xxx0,1,~101x,xxxx mcr_mcr2 +10xxx1,1,~101x,xxxx mrc_mrc2 +11xxxx,x,xxxx,xxxx advanced_simd_data_proc + +load_word: +extract32 111,1100,op1.2,10,1,Rn.4,xxxx,op2.6,xxxxxx +on op1,op2,Rn +01,xxxxxx,~1111 ldr_immediate +00,1xx1xx,~1111 ldr_immediate +00,1100xx,~1111 ldr_immediate +00,1110xx,~1111 ldrt +00,000000,~1111 ldr_register +0x,xxxxxx,1111 ldr_literal + +//----------------------------------------------------------------------------- +// thumb32, level 2 +//----------------------------------------------------------------------------- + +extension_reg_load_store: +extract32 111,T.1,110,Opcode.5,Rn.4,xxxx,101,xxxxxxxxx +on Opcode,Rn +0010x,xxxx xfer_64_core_ext_regs +01x00,xxxx vstm +01x10,xxxx vstm +1xx00,xxxx vstr +10x10,~1101 vstm +10x10,1101 vpush +01x11,1101 vpop +01x01,xxxx vldm +01x11,~1101 vldm +01x11,1101 undefined +1xx01,xxxx vldr +10x11,xxxx vldm + +change_proc_state_and_hints: +extract32 111,10,0111010,xxxx,10,x,0,x,op1.3,op2.8 +on op1,op2 +~000,xxxxxxxx cps +000,00000000 nop +000,00000001 yield +000,00000010 wfe +000,00000011 wfi +000,00000100 sev +000,1111xxxx dbg +000,xxxxxxxx hint_undoc + +misc_control: +extract32 1,1,1,1,0,0,1,1,1,0,1,1,xxxx,1,0,x,0,xxxx,op.4,x,x,x,x +on op +0000 enterx_leavex +0001 enterx_leavex +0010 clrex +0100 dsb +0101 dmb +0110 isb + +vfp_data_proc: +extract32 111,T.1,1110,opc1.4,opc2.4,xxxx,101,x,opc3.2,x,0,opc4.4 +on T,opc1,opc2,opc3 +// Table A7-16 +1,0xxx,xxxx,xx vsel +1,1x00,xxxx,xx vmaxnm +0,0x11,xxxx,x0 vadd_float +0,0x11,xxxx,x1 vsub_float +x,1x10,x,x vfma +0,0x10,xxxx,x0 vmul_float +x,1x01,xxxx,xxxx vfnma +0,0x00,xxxx,xx vmla_float +0,1x00,xxxx,x0 vdiv +x,1x11,xxxx,xx vfp_data_proc_ext +0,0x01,xxxx,xx vnmla +0,0x10,xxxx,xx vnmla +x,x,x,x undefined + +vfp_data_proc_ext: +extract32 111,T.1,1110,opc1.4,opc2.4,xxxx,101,x,opc3.2,x,0,opc4.4 +on T,opc2,opc3 +// Table A7-17 +0,0001,11 vsqrt +1,10xx,01 vrinta +1,1100,x1 vcvta +1,1101,x1 vcvtn +1,1110,x1 vcvtp +1,1111,x1 vcvtm +x,001x,x1 vcvtb +x,0111,11 vcvt_double_single +0,0111,01 vrintx +x,0000,01 vmov_register +0,xxxx,x0 vmov_immediate +x,0000,11 vabs +0,0001,01 vneg +x,010x,x1 vcmp +0,011x,x1 vrintz +0,1000,x1 vcvt_float_int +0,101x,x1 vcvt_float_fixed +0,110x,x1 vcvt_float_int +0,111x,x1 vcvt_float_fixed +x,x,x undefined + +load_byte_mem_hint: +extract32 111,1100,op1.2,00,1,Rn.4,Rt.4,op2.6,xxxxxx +on op1,op2,Rn,Rt +0x,xxxxxx,1111,~1111 ldrb_literal +01,xxxxxx,~1111,~1111 ldrb_immediate +00,1xx1xx,~1111,~1111 ldrb_immediate +00,1100xx,~1111,~1111 ldrb_immediate +00,1110xx,~1111,~1111 ldrbt +00,000000,~1111,~1111 ldrb_register +1x,xxxxxx,1111,~1111 ldrsb_literal +11,xxxxxx,~1111,~1111 ldrsb_immediate +10,1xx1xx,~1111,~1111 ldrsb_immediate +10,1100xx,~1111,~1111 ldrsb_immediate +10,1110xx,~1111,~1111 ldrsbt +10,000000,~1111,~1111 ldrsb_register +0x,xxxxxx,1111,1111 pld_literal +01,xxxxxx,~1111,1111 pld_pldw_immediate +00,1100xx,~1111,1111 pld_pldw_immediate +00,000000,~1111,1111 pld_pldw_register +00,1xx1xx,~1111,1111 unpredictable +00,1110xx,~1111,1111 unpredictable +1x,xxxxxx,1111,1111 pli_immediate_literal +11,xxxxxx,~1111,1111 pli_immediate_literal +10,1100xx,~1111,1111 pli_immediate_literal +10,000000,~1111,1111 pli_register +10,1xx1xx,~1111,1111 unpredictable +10,1110xx,~1111,1111 unpredictable + +load_halfword_mem_hint: +extract32 111,1100,op1.2,01,1,Rn.4,Rt.4,op2.6,xxxxxx +on op1,op2,Rn,Rt +0x,xxxxxx,1111,~1111 ldrh_literal +01,xxxxxx,~1111,~1111 ldrh_immediate +00,1xx1xx,~1111,~1111 ldrh_immediate +00,1100xx,~1111,~1111 ldrh_immediate +00,1110xx,~1111,~1111 ldrht +00,000000,~1111,~1111 ldrh_register +1x,xxxxxx,1111,~1111 ldrsh_literal +11,xxxxxx,~1111,~1111 ldrsh_immediate +10,1xx1xx,~1111,~1111 ldrsh_immediate +10,1100xx,~1111,~1111 ldrsh_immediate +10,1110xx,~1111,~1111 ldrsht +10,000000,~1111,~1111 ldrsh_register +0x,xxxxxx,1111,1111 unpredictable +01,xxxxxx,~1111,1111 pld_pldw_immediate +00,1100xx,~1111,1111 pld_pldw_immediate +00,000000,~1111,1111 pld_pldw_register +00,1xx1xx,~1111,1111 unpredictable +00,1110xx,~1111,1111 unpredictable +1x,xxxxxx,1111,1111 nop +10,1100xx,~1111,1111 nop +10,000000,~1111,1111 nop +10,1xx1xx,~1111,1111 unpredictable +10,1110xx,~1111,1111 unpredictable +11,xxxxxx,~1111,1111 nop + +// this is the A6.3.12 version (vs. the A5.2.1) +data_processing_register: +extract32 111,1101,0,op1.4,Rn.4,check.4,xxxx,op2.4,xxxx +on op1,op2,Rn +000x,0000,xxxx lsl_register +001x,0000,xxxx lsr_register +010x,0000,xxxx asr_register +011x,0000,xxxx ror_register +0000,1xxx,~1111 sxtah +0000,1xxx,1111 sxth +0001,1xxx,~1111 uxtah +0001,1xxx,1111 uxth +0010,1xxx,~1111 sxtab16 +0010,1xxx,1111 sxtb16 +0011,1xxx,~1111 uxtab16 +0011,1xxx,1111 uxtb16 +0100,1xxx,~1111 sxtab +0100,1xxx,1111 sxtb +0101,1xxx,~1111 uxtab +0101,1xxx,1111 uxtb +1xxx,00xx,xxxx parallel_add_sub_signed +1xxx,01xx,xxxx parallel_add_sub_unsigned +10xx,10xx,xxxx misc_operations + +// note that this table gets the criteria on Ra for travel to usad8 and usada8 WRONG +// drill down into usad8 and usada8 to see contradiction +mul_accumulate_absolute_difference: +extract32 111,1101,10,op1.3,xxxx,Ra.4,xxxx,00,op2.2,xxxx +on op1,op2,Ra +000,00,~1111 mla +000,00,1111 mul +000,01,xxxx mls +001,xx,~1111 smlabb_smlabt_smlatb_smlatt +001,xx,1111 smulbb_smulbt_smultb_smultt +010,0x,~1111 smlad +010,0x,1111 smuad +011,0x,~1111 smlawb_smlawt +011,0x,1111 smulwb_smulwt +100,0x,~1111 smlsd +100,0x,1111 smusd +101,0x,~1111 smmla +101,0x,1111 smmul +110,0x,xxxx smmls +111,00,1111 usad8 +111,00,~1111 usada8 + +long_mul_accumulate_divide: +extract32 111,1101,11,op1.3,xxxx,xxxxxxxx,op2.4,xxxx +on op1,op2 +000,0000 smull +001,1111 sdiv +010,0000 umull +011,1111 udiv +100,0000 smlal +100,10xx smlalbb_smlalbt_smlaltb_smlaltt +100,110x smlald +101,110x smlsld +110,0000 umlal +110,0110 umaal + +//----------------------------------------------------------------------------- +// thumb32, level 3 +//----------------------------------------------------------------------------- + +xfer_64_core_ext_regs: +extract32 111,T.1,1100,010,xxxxx,xxxx,101,C.1,op.4,xxxx +on C,op +0,00x1 vmov_core_two_single +1,00x1 vmov_core_double + +xfer_8_16_32_core_extension: +extract32 111,T.1,1110,A.3,L.1,xxxx,xxxx,101,C.1,x,B.2,1,xxxx +on L,C,A,B +0,0,000,xx vmov_core_single +0,0,111,xx vmsr +0,1,0xx,xx vmov_core_scalar +0,1,1xx,0x vdup_register +1,0,000,xx vmov_core_single +1,0,111,xx vmrs +1,1,xxx,xx vmov_scalar_core + +parallel_add_sub_signed: +extract32 111,1101,01,op1.3,xxxx,1111,xxxx,00,op2.2,xxxx +on op1,op2 +001,00 sadd16 +010,00 sasx +110,00 ssax +101,00 ssub16 +000,00 sadd8 +100,00 ssub8 +001,01 qadd16 +010,01 qasx +110,01 qsax +101,01 qsub16 +000,01 qadd8 +100,01 qsub8 +001,10 shadd16 +010,10 shasx +110,10 shsax +101,10 shsub16 +000,10 shadd8 +100,10 shsub8 + +parallel_add_sub_unsigned: +extract32 111,1101,01,op1.3,xxxx,1111,xxxx,01,op2.2,xxxx +on op1,op2 +001,00 uadd16 +010,00 uasx +110,00 usax +101,00 usub16 +000,00 uadd8 +100,00 usub8 +001,01 uqadd16 +010,01 uqasx +110,01 uqsax +101,01 uqsub16 +000,01 uqadd8 +100,01 uqsub8 +001,10 uhadd16 +010,10 uhasx +110,10 uhsax +101,10 uhsub16 +000,10 uhadd8 +100,10 uhsub8 + +//----------------------------------------------------------------------------- +// thumb16, level 1 +//----------------------------------------------------------------------------- + +shift_immediate_add_sub_mov_cmp: +extract16 00,Opcode.5,clue.3 +on Opcode,clue +000xx,xxx lsl_immediate +001xx,xxx lsr_immediate +010xx,xxx asr_immediate +01100,xxx add_register +01101,xxx sub_register +01110,xxx add_immediate +01111,xxx sub_immediate +100xx,xxx mov_immediate +101xx,xxx cmp_immediate +110xx,xxx add_immediate +111xx,xxx sub_immediate +00000,000 mov_register + +data_proc: +extract16 010000,Opcode.4 +on Opcode +0000 and_register +0001 eor_register +0010 lsl_register +0011 lsr_register +0100 asr_register +0101 adc_register +0110 sbc_register +0111 ror_register +1000 tst_register +1001 rsb_immediate +1010 cmp_register +1011 cmn_register +1100 orr_register +1101 mul_register +1110 bic_register +1111 mvn_register + +spcl_data_branch_exch: +extract16 010001,Opcode.4 +on Opcode +0000 add_register +0001 add_register +001x add_register +// 0100 unpredictable ... this should fall thru and be flagged as unpredictable +// by the cmp_register() subroutine +0100 cmp_register +0101 cmp_register +011x cmp_register +1000 mov_register +1001 mov_register +101x mov_register +110x bx +111x blx + +load_store_single_data: +extract16 opA.4,opB.3 +on opA,opB +0101,000 str_register +0101,001 strh_register +0101,010 strb_register +0101,011 ldrsb_register +0101,100 ldr_register +0101,101 ldrh_register +0101,110 ldrb_register +0101,111 ldrsh_register +0110,0xx str_immediate +0110,1xx ldr_immediate +0111,0xx strb_immediate +0111,1xx ldrb_immediate +1000,0xx strh_immediate +1000,1xx ldrh_immediate +1001,0xx str_immediate +1001,1xx ldr_immediate + +misc: +extract16 1011,opcode.7 +on opcode +0110010 setend +0110011 cps +00000xx add_sp_plus_immediate +00001xx sub_sp_minus_immediate +0001xxx cbnz_cbz +001000x sxth +001001x sxtb +001010x uxth +001011x uxtb +0011xxx cbnz_cbz +010xxxx push +1001xxx cbnz_cbz +101000x rev +101001x rev16 +101011x revsh +1011xxx cbnz_cbz +110xxxx pop +1110xxx bkpt +1111xxx if_then_hints + +misc_operations: +extract32 111,1101,010,op1.2,xxxx,1111,xxxx,10,op2.2,xxxx +on op1,op2 +00,00 qadd +00,01 qdadd +00,10 qsub +00,11 qdsub +01,00 rev +01,01 rev16 +01,10 rbit +01,11 revsh +10,00 sel +11,00 clz + +if_then_hints: +extract16 1011,1111,opA.4,opB.4 +on opA,opB +0000,0000 nop +0001,0000 yield +0010,0000 wfe +0011,0000 wfi +0100,0000 sev +xxxx,~0000 it +xxxx,xxxx it_related_encodings + +cond_branch_superv_call: +extract16 1101,Opcode.4 +on Opcode +~111x b +1110 udf +1111 svc + +//----------------------------------------------------------------------------- +// TERMINALS +//----------------------------------------------------------------------------- + +load_lit_pool: +Encoding T1 ARMv4T, ARMv5T*, ARMv6*, ARMv7 +fmt LDR<c> <Rt>,<label> +extract16 01001,Rt.3,imm8.8 +pcode t = UInt(Rt); imm32 = ZeroExtend(imm8:'00', 32); add = TRUE; Rt = UInt(Rt); +Encoding T2 ARMv6T2, ARMv7 +fmt LDR<c> <Rt>,<label> +extract32 11111,00,0,U.1,10,1,1111,Rt.4,imm12.12 +pcode t = UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1'); if t == 15 && InITBlock() && !LastInITBlock() then UNPREDICTABLE; Rt = UInt(Rt); + +lsl_immediate: +Encoding T1 ARMv4T, ARMv5T*, ARMv6*, ARMv7 +fmt LSLS <Rd>,<Rm>,#<shift_n> +fmt LSL<c> <Rd>,<Rm>,#<shift_n> +extract16 000,00,imm5.5,Rm.3,Rd.3 +pcode if imm5 == '00000' then SEE MOV (register); d = UInt(Rd); m = UInt(Rm); setflags = !InITBlock(); (-, shift_n) = DecodeImmShift('00', imm5); +Encoding T2 ARMv6T2, ARMv7 +fmt LSL{S}<c> <Rd>,<Rm>,#<shift_n> +extract32 11101,01,0010,S.1,1111,(0),imm3.3,Rd.4,imm2.2,00,Rm.4 +pcode if (imm3:imm2) == '00000' then SEE MOV (register); d = UInt(Rd); m = UInt(Rm); setflags = (S == '1'); (-, shift_n) = DecodeImmShift('00', imm3:imm2); if BadReg(d) || BadReg(m) then UNPREDICTABLE; + +lsr_immediate: +Encoding T1 ARMv4T, ARMv5T*, ARMv6*, ARMv7 +fmt LSRS <Rd>,<Rm>,#<shift_n> +fmt LSR<c> <Rd>,<Rm>,#<shift_n> +extract16 000,01,imm5.5,Rm.3,Rd.3 +pcode d = UInt(Rd); m = UInt(Rm); setflags = !InITBlock(); (-, shift_n) = DecodeImmShift('01', imm5); +Encoding T2 ARMv6T2, ARMv7 +fmt LSR{S}<c> <Rd>,<Rm>,#<shift_n> +extract32 11101,01,0010,S.1,1111,(0),imm3.3,Rd.4,imm2.2,01,Rm.4 +pcode d = UInt(Rd); m = UInt(Rm); setflags = (S == '1'); (-, shift_n) = DecodeImmShift('01', imm3:imm2); if BadReg(d) || BadReg(m) then UNPREDICTABLE; + +asr_immediate: +Encoding T1 ARMv4T, ARMv5T*, ARMv6*, ARMv7 +fmt ASRS <Rd>,<Rm>,#<shift_n> +fmt ASR<c> <Rd>,<Rm>,#<shift_n> +extract16 000,10,imm5.5,Rm.3,Rd.3 +pcode d = UInt(Rd); m = UInt(Rm); setflags = !InITBlock(); (-, shift_n) = DecodeImmShift('10', imm5); +Encoding T2 ARMv6T2, ARMv7 +fmt ASR{S}<c> <Rd>,<Rm>,#<shift_n> +extract32 11101,01,0010,S.1,1111,(0),imm3.3,Rd.4,imm2.2,10,Rm.4 +pcode d = UInt(Rd); m = UInt(Rm); setflags = (S == '1'); (-, shift_n) = DecodeImmShift('10', imm3:imm2); if BadReg(d) || BadReg(m) then UNPREDICTABLE; + +add_register: +Encoding T1 ARMv4T, ARMv5T*, ARMv6*, ARMv7 +fmt ADDS <Rd>,<Rn>,<Rm> +fmt ADD<c> <Rd>,<Rn>,<Rm> +extract16 000,11,0,0,Rm.3,Rn.3,Rd.3 +pcode d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = !InITBlock(); (shift_t, shift_n) = (SRType_LSL, 0); +Encoding T2 ARMv6T2, ARMv7, ARMv4T, ARMv5T*, ARMv6*, ARMv7 +fmt ADD<c> <Rdn>,<Rm> +extract16 010001,00,DN.1,Rm.4,Rdn.3 +pcode if (DN:Rdn) == '1101' || Rm == '1101' then SEE ADD (SP plus register); Rdn = UInt(DN:Rdn); d = UInt(DN:Rdn); n = d; m = UInt(Rm); setflags = FALSE; (shift_t, shift_n) = (SRType_LSL, 0); if n == 15 && m == 15 then UNPREDICTABLE; if d == 15 && InITBlock() && !LastInITBlock() then UNPREDICTABLE; +Encoding T3 ARMv6T2, ARMv7 +fmt ADD{S}<c> <Rd>,<Rn>,<Rm>{,<shift>} +extract32 11101,01,1000,S.1,Rn.4,(0),imm3.3,Rd.4,imm2.2,type.2,Rm.4 +pcode if Rd == '1111' && S == '1' then SEE CMN (register); if Rn == '1101' then SEE ADD (SP plus register); d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = (S == '1'); (shift_t, shift_n) = DecodeImmShift(type, imm3:imm2); if BadReg(d) || n == 15 || BadReg(m) then UNPREDICTABLE; + +sub_register: +Encoding T1 ARMv4T, ARMv5T*, ARMv6*, ARMv7 +fmt SUBS <Rd>,<Rn>,<Rm> +fmt SUB<c> <Rd>,<Rn>,<Rm> +extract16 000,11,0,1,Rm.3,Rn.3,Rd.3 +pcode d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = !InITBlock(); (shift_t, shift_n) = (SRType_LSL, 0); +Encoding T2 ARMv6T2, ARMv7 +fmt SUB{S}<c> <Rd>,<Rn>,<Rm>{,<shift>} +extract32 11101,01,1101,S.1,Rn.4,(0),imm3.3,Rd.4,imm2.2,type.2,Rm.4 +pcode if Rd == '1111' && S == '1' then SEE CMP (register); if Rn == '1101' then SEE SUB (SP minus register); d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = (S == '1'); (shift_t, shift_n) = DecodeImmShift(type, imm3:imm2); if BadReg(d) || n == 15 || BadReg(m) then UNPREDICTABLE; + +add_immediate: +Encoding T1 ARMv4T, ARMv5T*, ARMv6*, ARMv7 +fmt ADDS <Rd>,<Rn>,#<imm3> +fmt ADD<c> <Rd>,<Rn>,#<imm3> +extract16 000,11,1,0,imm3.3,Rn.3,Rd.3 +pcode d = UInt(Rd); n = UInt(Rn); setflags = !InITBlock(); imm32 = ZeroExtend(imm3, 32); +Encoding T2 ARMv4T, ARMv5T*, ARMv6*, ARMv7 +fmt ADDS <Rdn>,#<imm8> +fmt ADD<c> <Rdn>,#<imm8> +extract16 001,10,Rdn.3,imm8.8 +pcode d = UInt(Rdn); n = UInt(Rdn); setflags = !InITBlock(); imm32 = ZeroExtend(imm8, 32); +Encoding T3 ARMv6T2, ARMv7 +fmt ADD{S}<c> <Rd>,<Rn>,#<imm32> +extract32 11110,i.1,0,1000,S.1,Rn.4,0,imm3.3,Rd.4,imm8.8 +pcode if Rd == '1111' && S == '1' then SEE CMN (immediate); if Rn == '1101' then SEE ADD (SP plus immediate); d = UInt(Rd); n = UInt(Rn); setflags = (S == '1'); imm32 = ThumbExpandImm(i:imm3:imm8); if BadReg(d) || n == 15 then UNPREDICTABLE; +Encoding T4 ARMv6T2, ARMv7 +fmt ADDW<c> <Rd>,<Rn>,#<imm32> +extract32 11110,i.1,1,0000,0,Rn.4,0,imm3.3,Rd.4,imm8.8 +pcode if Rn == '1111' then SEE ADR; if Rn == '1101' then SEE ADD (SP plus immediate); d = UInt(Rd); n = UInt(Rn); setflags = FALSE; imm32 = ZeroExtend(i:imm3:imm8, 32); if BadReg(d) then UNPREDICTABLE; + +sub_immediate: +Encoding T1 ARMv4T, ARMv5T*, ARMv6*, ARMv7 +fmt SUBS <Rd>,<Rn>,#<imm3> +fmt SUB<c> <Rd>,<Rn>,#<imm3> +extract16 000,11,1,1,imm3.3,Rn.3,Rd.3 +pcode d = UInt(Rd); n = UInt(Rn); setflags = !InITBlock(); imm32 = ZeroExtend(imm3, 32); +Encoding T2 ARMv4T, ARMv5T*, ARMv6*, ARMv7 +fmt SUBS <Rdn>,#<imm8> +fmt SUB<c> <Rdn>,#<imm8> +extract16 001,11,Rdn.3,imm8.8 +pcode d = UInt(Rdn); n = UInt(Rdn); setflags = !InITBlock(); imm32 = ZeroExtend(imm8, 32); +Encoding T3 ARMv6T2, ARMv7 +fmt SUB{S}<c> <Rd>,<Rn>,#<imm32> +extract32 11110,i.1,0,1101,S.1,Rn.4,0,imm3.3,Rd.4,imm8.8 +pcode d = UInt(Rd); n = UInt(Rn); setflags = (S == '1'); imm32 = ThumbExpandImm(i:imm3:imm8); if d == 13 || (d == 15 && S == '0') || n == 15 then UNPREDICTABLE; +Encoding T4 ARMv6T2, ARMv7 +fmt SUBW<c> <Rd>,<Rn>,#<imm32> +extract32 11110,i.1,1,0101,0,Rn.4,0,imm3.3,Rd.4,imm8.8 +pcode d = UInt(Rd); n = UInt(Rn); setflags = FALSE; imm32 = ZeroExtend(i:imm3:imm8, 32); if d == 13 || d == 15 then UNPREDICTABLE; + +mov_immediate: +Encoding T1 ARMv4T, ARMv5T*, ARMv6*, ARMv7 +fmt MOVS <Rd>,#<imm8> +fmt MOV<c> <Rd>,#<imm8> +extract16 001,00,Rd.3,imm8.8 +pcode d = UInt(Rd); setflags = !InITBlock(); imm32 = ZeroExtend(imm8, 32) +Encoding T2 ARMv6T2, ARMv7 +fmt MOV{S}<c> <Rd>,#<imm32> +extract32 11110,i.1,0,0010,S.1,1111,0,imm3.3,Rd.4,imm8.8 +pcode d = UInt(Rd); setflags = (S == '1'); (imm32, carry) = ThumbExpandImm_C(i:imm3:imm8, APSR.C); if BadReg(d) then UNPREDICTABLE; +Encoding T3 ARMv6T2, ARMv7 +fmt MOVW<c> <Rd>,#<imm32> +extract32 11110,i.1,10,0,1,0,0,imm4.4,0,imm3.3,Rd.4,imm8.8 +pcode d = UInt(Rd); setflags = FALSE; imm32 = ZeroExtend(imm4:i:imm3:imm8, 32); if BadReg(d) then UNPREDICTABLE; + +cmp_immediate: +Encoding T1 ARMv4T, ARMv5T*, ARMv6*, ARMv7 +fmt CMP<c> <Rn>,#<imm8> +extract16 001,01,Rn.3,imm8.8 +pcode n = UInt(Rn); imm32 = ZeroExtend(imm8, 32); +Encoding T2 ARMv6T2, ARMv7 +fmt CMP<c> <Rn>,#<imm32> +extract32 11110,i.1,0,1101,1,Rn.4,0,imm3.3,1111,imm8.8 +pcode n = UInt(Rn); imm32 = ThumbExpandImm(i:imm3:imm8); if n == 15 then UNPREDICTABLE; + +mov_register: +Encoding T1 ARMv6*, ARMv7 +fmt MOV<c> <Rd>,<Rm> +extract16 010001,10,D.1,Rm.4,Rd.3 +pcode d = UInt(D:Rd); m = UInt(Rm); setflags = FALSE; if d == 15 && InITBlock() && !LastInITBlock() then UNPREDICTABLE; Rd = UInt(D:Rd); +Encoding T2 ARMv4T, ARMv5T*, ARMv6*, ARMv7 +fmt MOVS <Rd>,<Rm> +extract16 000,00,00000,Rm.3,Rd.3 +pcode d = UInt(Rd); m = UInt(Rm); setflags = TRUE; if InITBlock() then UNPREDICTABLE; +Encoding T3 ARMv6T2, ARMv7 +fmt MOV{S}<c> <Rd>,<Rm> +extract32 11101,01,0010,S.1,1111,(0),000,Rd.4,0000,Rm.4 +pcode d = UInt(Rd); m = UInt(Rm); setflags = (S == '1'); if (d == 13 || BadReg(m)) && setflags then UNPREDICTABLE; if (d == 13 && BadReg(m)) || d == 15 then UNPREDICTABLE; + +//----------------------------------------------------------------------------- + +and_register: +Encoding T1 ARMv4T, ARMv5T*, ARMv6*, ARMv7 +fmt ANDS <Rdn>,<Rm> +fmt AND<c> <Rdn>,<Rm> +extract16 010000,0000,Rm.3,Rdn.3 +pcode d = UInt(Rdn); n = UInt(Rdn); m = UInt(Rm); setflags = !InITBlock(); (shift_t, shift_n) = (SRType_LSL, 0); +Encoding T2 ARMv6T2, ARMv7 +fmt AND{S}<c> <Rd>,<Rn>,<Rm>{,<shift>} +extract32 11101,01,0000,S.1,Rn.4,(0),imm3.3,Rd.4,imm2.2,type.2,Rm.4 +pcode d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = (S == '1'); (shift_t, shift_n) = DecodeImmShift(type, imm3:imm2); if BadReg(d) || BadReg(n) || BadReg(m) then UNPREDICTABLE; + +eor_register: +Encoding T1 ARMv4T, ARMv5T*, ARMv6*, ARMv7 +fmt EORS <Rdn>,<Rm> +fmt EOR<c> <Rdn>,<Rm> +extract16 010000,0001,Rm.3,Rdn.3 +pcode d = UInt(Rdn); n = UInt(Rdn); m = UInt(Rm); setflags = !InITBlock(); (shift_t, shift_n) = (SRType_LSL, 0); +Encoding T2 ARMv6T2, ARMv7 +fmt EOR{S}<c> <Rd>,<Rn>,<Rm>{,<shift>} +extract32 11101,01,0100,S.1,Rn.4,(0),imm3.3,Rd.4,imm2.2,type.2,Rm.4 +pcode if Rd == '1111' && S == '1' then SEE TEQ (register); d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = (S == '1'); (shift_t, shift_n) = DecodeImmShift(type, imm3:imm2); if BadReg(d) || BadReg(n) || BadReg(m) then UNPREDICTABLE; + +lsl_register: +Encoding T1 ARMv4T, ARMv5T*, ARMv6*, ARMv7 +fmt LSLS <Rdn>,<Rm> +fmt LSL<c> <Rdn>,<Rm> +extract16 010000,0010,Rm.3,Rdn.3 +pcode d = UInt(Rdn); n = UInt(Rdn); m = UInt(Rm); setflags = !InITBlock(); +Encoding T2 ARMv6T2, ARMv7 +fmt LSL{S}<c> <Rd>,<Rn>,<Rm> +extract32 11111,010,0,00,S.1,Rn.4,1111,Rd.4,0,000,Rm.4 +pcode d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = (S == '1'); if BadReg(d) || BadReg(n) || BadReg(m) then UNPREDICTABLE; + +lsr_register: +Encoding T1 ARMv4T, ARMv5T*, ARMv6*, ARMv7 +fmt LSRS <Rdn>,<Rm> +fmt LSR<c> <Rdn>,<Rm> +extract16 010000,0011,Rm.3,Rdn.3 +pcode d = UInt(Rdn); n = UInt(Rdn); m = UInt(Rm); setflags = !InITBlock(); +Encoding T2 ARMv6T2, ARMv7 +fmt LSR{S}<c> <Rd>,<Rn>,<Rm> +extract32 11111,010,0,01,S.1,Rn.4,1111,Rd.4,0,000,Rm.4 +pcode d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = (S == '1'); if BadReg(d) || BadReg(n) || BadReg(m) then UNPREDICTABLE; + +asr_register: +Encoding T1 ARMv4T, ARMv5T*, ARMv6*, ARMv7 +fmt ASRS <Rdn>,<Rm> +fmt ASR<c> <Rdn>,<Rm> +extract16 010000,0100,Rm.3,Rdn.3 +pcode d = UInt(Rdn); n = UInt(Rdn); m = UInt(Rm); setflags = !InITBlock(); +Encoding T2 ARMv6T2, ARMv7 +fmt ASR{S}<c> <Rd>,<Rn>,<Rm> +extract32 11111,010,0,10,S.1,Rn.4,1111,Rd.4,0,000,Rm.4 +pcode d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = (S == '1'); if BadReg(d) || BadReg(n) || BadReg(m) then UNPREDICTABLE; + +adc_register: +Encoding T1 ARMv4T, ARMv5T*, ARMv6*, ARMv7 +fmt ADCS <Rdn>,<Rm> +fmt ADC<c> <Rdn>,<Rm> +extract16 010000,0101,Rm.3,Rdn.3 +pcode d = UInt(Rdn); n = UInt(Rdn); m = UInt(Rm); setflags = !InITBlock(); (shift_t, shift_n) = (SRType_LSL, 0); +Encoding T2 ARMv6T2, ARMv7 +fmt ADC{S}<c> <Rd>,<Rn>,<Rm>{,<shift>} +extract32 11101,01,1010,S.1,Rn.4,(0),imm3.3,Rd.4,imm2.2,type.2,Rm.4 +pcode d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = (S == '1'); (shift_t, shift_n) = DecodeImmShift(type, imm3:imm2); if BadReg(d) || BadReg(n) || BadReg(m) then UNPREDICTABLE; + +sbc_register: +Encoding T1 ARMv4T, ARMv5T*, ARMv6*, ARMv7 +fmt SBCS <Rdn>,<Rm> +fmt SBC<c> <Rdn>,<Rm> +extract16 010000,0110,Rm.3,Rdn.3 +pcode d = UInt(Rdn); n = UInt(Rdn); m = UInt(Rm); setflags = !InITBlock(); (shift_t, shift_n) = (SRType_LSL, 0); +Encoding T2 ARMv6T2, ARMv7 +fmt SBC{S}<c> <Rd>,<Rn>,<Rm>{,<shift>} +extract32 11101,01,1011,S.1,Rn.4,(0),imm3.3,Rd.4,imm2.2,type.2,Rm.4 +pcode d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = (S == '1'); (shift_t, shift_n) = DecodeImmShift(type, imm3:imm2); if BadReg(d) || BadReg(n) || BadReg(m) then UNPREDICTABLE; + +ror_register: +Encoding T1 ARMv4T, ARMv5T*, ARMv6*, ARMv7 +fmt RORS <Rdn>,<Rm> +fmt ROR<c> <Rdn>,<Rm> +extract16 010000,0111,Rm.3,Rdn.3 +pcode d = UInt(Rdn); n = UInt(Rdn); m = UInt(Rm); setflags = !InITBlock(); +Encoding T2 ARMv6T2, ARMv7 +fmt ROR{S}<c> <Rd>,<Rn>,<Rm> +extract32 11111,010,0,11,S.1,Rn.4,1111,Rd.4,0,000,Rm.4 +pcode d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = (S == '1'); if BadReg(d) || BadReg(n) || BadReg(m) then UNPREDICTABLE; + +tst_register: +Encoding T1 ARMv4T, ARMv5T*, ARMv6*, ARMv7 +fmt TST<c> <Rn>,<Rm> +extract16 010000,1000,Rm.3,Rn.3 +pcode n = UInt(Rn); m = UInt(Rm); (shift_t, shift_n) = (SRType_LSL, 0); +Encoding T2 ARMv6T2, ARMv7 +fmt TST<c> <Rn>,<Rm>{,<shift>} +extract32 11101,01,0000,1,Rn.4,(0),imm3.3,1111,imm2.2,type.2,Rm.4 +pcode n = UInt(Rn); m = UInt(Rm); (shift_t, shift_n) = DecodeImmShift(type, imm3:imm2); if BadReg(n) || BadReg(m) then UNPREDICTABLE; + +rsb_immediate: +Encoding T1 ARMv4T, ARMv5T*, ARMv6*, ARMv7 +fmt RSBS <Rd>,<Rn>,#0 +fmt RSB<c> <Rd>,<Rn>,#0 +extract16 010000,1001,Rn.3,Rd.3 +pcode d = UInt(Rd); n = UInt(Rn); setflags = !InITBlock(); imm32 = Zeros(32); +Encoding T2 ARMv6T2, ARMv7 +fmt RSB{S}<c> <Rd>,<Rn>,#<imm32> +extract32 11110,i.1,0,1110,S.1,Rn.4,0,imm3.3,Rd.4,imm8.8 +pcode d = UInt(Rd); n = UInt(Rn); setflags = (S == '1'); imm32 = ThumbExpandImm(i:imm3:imm8); if BadReg(d) || BadReg(n) then UNPREDICTABLE; + +cmp_register: +Encoding T1 ARMv4T, ARMv5T*, ARMv6*, ARMv7 +fmt CMP<c> <Rn>,<Rm> +extract16 010000,1010,Rm.3,Rn.3 +pcode n = UInt(Rn); m = UInt(Rm); (shift_t, shift_n) = (SRType_LSL, 0); +Encoding T2 ARMv4T, ARMv5T*, ARMv6*, ARMv7 +fmt CMP<c> <Rn>,<Rm> +extract16 010001,01,N.1,Rm.4,Rn.3 +pcode n = UInt(N:Rn); m = UInt(Rm); (shift_t, shift_n) = (SRType_LSL, 0); if n < 8 && m < 8 then UNPREDICTABLE; if n == 15 || m == 15 then UNPREDICTABLE; Rn = UInt(N:Rn); +Encoding T3 ARMv6T2, ARMv7 +fmt CMP<c> <Rn>,<Rm>{,<shift>} +extract32 11101,01,1101,1,Rn.4,(0),imm3.3,1111,imm2.2,type.2,Rm.4 +pcode n = UInt(Rn); m = UInt(Rm); (shift_t, shift_n) = DecodeImmShift(type, imm3:imm2); if n == 15 || BadReg(m) then UNPREDICTABLE; + +rsb_register: +Encoding T1 ARMv6T2, ARMv7 +fmt RSB{S}<c> <Rd>,<Rn>,<Rm>{,<shift>} +extract32 11101,01,1110,S.1,Rn.4,(0),imm3.3,Rd.4,imm2.2,type.2,Rm.4 +pcode d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = (S == '1'); (shift_t, shift_n) = DecodeImmShift(type, imm3:imm2); if BadReg(d) || BadReg(n) || BadReg(m) then UNPREDICTABLE; + +cmn_register: +Encoding T1 ARMv4T, ARMv5T*, ARMv6*, ARMv7 +fmt CMN<c> <Rn>,<Rm> +extract16 010000,1011,Rm.3,Rn.3 +pcode n = UInt(Rn); m = UInt(Rm); (shift_t, shift_n) = (SRType_LSL, 0); +Encoding T2 ARMv6T2, ARMv7 +fmt CMN<c> <Rn>,<Rm>{,<shift>} +extract32 11101,01,1000,1,Rn.4,(0),imm3.3,1111,imm2.2,type.2,Rm.4 +pcode n = UInt(Rn); m = UInt(Rm); (shift_t, shift_n) = DecodeImmShift(type, imm3:imm2); if n == 15 || BadReg(m) then UNPREDICTABLE; + +orr_register: +Encoding T1 ARMv4T, ARMv5T*, ARMv6*, ARMv7 +fmt ORRS <Rdn>,<Rm> +fmt ORR<c> <Rdn>,<Rm> +extract16 010000,1100,Rm.3,Rdn.3 +pcode d = UInt(Rdn); n = UInt(Rdn); m = UInt(Rm); setflags = !InITBlock(); (shift_t, shift_n) = (SRType_LSL, 0); +Encoding T2 ARMv6T2, ARMv7 +fmt ORR{S}<c> <Rd>,<Rn>,<Rm>{,<shift>} +extract32 11101,01,0010,S.1,Rn.4,(0),imm3.3,Rd.4,imm2.2,type.2,Rm.4 +pcode if Rn == '1111' then SEE MOV (register); d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = (S == '1'); (shift_t, shift_n) = DecodeImmShift(type, imm3:imm2); if BadReg(d) || n == 13 || BadReg(m) then UNPREDICTABLE; + +mul_register: +Encoding T1 ARMv4T, ARMv5T*, ARMv6*, ARMv7 +fmt MULS <Rdm>,<Rn>,<Rdm> +fmt MUL<c> <Rdm>,<Rn>,<Rdm> +extract16 010000,1101,Rn.3,Rdm.3 +pcode d = UInt(Rdm); n = UInt(Rn); m = UInt(Rdm); setflags = !InITBlock(); if ArchVersion() < 6 && d == n then UNPREDICTABLE; +Encoding T2 ARMv6T2, ARMv7 +fmt MUL<c> <Rd>,<Rn>,<Rm> +extract32 11111,0110,000,Rn.4,1111,Rd.4,0000,Rm.4 +pcode d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = FALSE; if BadReg(d) || BadReg(n) || BadReg(m) then UNPREDICTABLE; + +bic_register: +Encoding T1 ARMv4T, ARMv5T*, ARMv6*, ARMv7 +fmt BICS <Rdn>,<Rm> +fmt BIC<c> <Rdn>,<Rm> +extract16 010000,1110,Rm.3,Rdn.3 +pcode d = UInt(Rdn); n = UInt(Rdn); m = UInt(Rm); setflags = !InITBlock(); (shift_t, shift_n) = (SRType_LSL, 0); +Encoding T2 ARMv6T2, ARMv7 +fmt BIC{S}<c> <Rd>,<Rn>,<Rm>{,<shift>} +extract32 11101,01,0001,S.1,Rn.4,(0),imm3.3,Rd.4,imm2.2,type.2,Rm.4 +pcode d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = (S == '1'); (shift_t, shift_n) = DecodeImmShift(type, imm3:imm2); if BadReg(d) || BadReg(n) || BadReg(m) then UNPREDICTABLE; + +mvn_register: +Encoding T1 ARMv4T, ARMv5T*, ARMv6*, ARMv7 +fmt MVNS <Rd>,<Rm> +fmt MVN<c> <Rd>,<Rm> +extract16 010000,1111,Rm.3,Rd.3 +pcode d = UInt(Rd); m = UInt(Rm); setflags = !InITBlock(); (shift_t, shift_n) = (SRType_LSL, 0); +Encoding T2 ARMv6T2, ARMv7 +fmt MVN{S}<c> <Rd>,<Rm>{,<shift>} +extract32 11101,01,0011,S.1,1111,(0),imm3.3,Rd.4,imm2.2,type.2,Rm.4 +pcode d = UInt(Rd); m = UInt(Rm); setflags = (S == '1'); (shift_t, shift_n) = DecodeImmShift(type, imm3:imm2); if BadReg(d) || BadReg(m) then UNPREDICTABLE; + +//----------------------------------------------------------------------------- + +bx: +Encoding T1 ARMv4T, ARMv5T*, ARMv6*, ARMv7 +fmt BX<c> <Rm> +extract16 010001,11,0,Rm.4,(0)(0)(0) +pcode m = UInt(Rm); if InITBlock() && !LastInITBlock() then UNPREDICTABLE; + +blx: +Encoding T1 ARMv5T*, ARMv6*, ARMv7 +fmt BLX<c> <Rm> +extract16 010001,11,1,Rm.4,(0)(0)(0) +pcode m = UInt(Rm); if m == 15 then UNPREDICTABLE; if InITBlock() && !LastInITBlock() then UNPREDICTABLE; + +//----------------------------------------------------------------------------- + +add_sp_plus_register: +Encoding T1 ARMv4T, ARMv5T*, ARMv6*, ARMv7 +fmt ADD<c> <Rdm>,SP,<Rdm> +extract16 01000100,DM.1,1101,Rdm.3 +pcode Rdm = UInt(DM:Rdm); m = UInt(DM:Rdm); setflags = FALSE; (shift_t, shift_n) = (SRType_LSL, 0); +Encoding T2 ARMv4T, ARMv5T*, ARMv6*, ARMv7 +fmt ADD<c> SP,<Rm> +extract16 01000100,1,Rm.4,101 +pcode d = 13; m = UInt(Rm); setflags = FALSE; (shift_t, shift_n) = (SRType_LSL, 0); +Encoding T3 ARMv6T2, ARMv7 +fmt ADD{S}<c> <Rd>,SP,<Rm>{,<shift>} +extract32 11101011000,S.1,1101,0,imm3.3,Rd.4,imm2.2,type.2,Rm.4 +pcode d = UInt(Rd); m = UInt(Rm); setflags = (S == '1'); (shift_t, shift_n) = DecodeImmShift(type, imm3:imm2); if d == 13 && (shift_t != SRType_LSL || shift_n > 3) then UNPREDICTABLE; if d == 15 || BadReg(m) then UNPREDICTABLE; + +add_sp_plus_immediate: +Encoding T1 ARMv4T, ARMv5T*, ARMv6*, ARMv7 +fmt ADD<c> <Rd>,SP,#<imm32> +extract16 1010,1,Rd.3,imm8.8 +pcode d = UInt(Rd); setflags = FALSE; imm32 = ZeroExtend(imm8:'00', 32); +Encoding T2 ARMv4T, ARMv5T*, ARMv6*, ARMv7 +fmt ADD<c> SP,#<imm32> +extract16 1011,0000,0,imm7.7 +pcode d = 13; setflags = FALSE; imm32 = ZeroExtend(imm7:'00', 32); +Encoding T3 ARMv6T2, ARMv7 +fmt ADD{S}<c> <Rd>,SP,#<imm32> +extract32 11110,i.1,0,1000,S.1,1101,0,imm3.3,Rd.4,imm8.8 +pcode if Rd == '1111' && S == '1' then SEE CMN (immediate); d = UInt(Rd); setflags = (S == '1'); imm32 = ThumbExpandImm(i:imm3:imm8); if d == 15 then UNPREDICTABLE; +Encoding T4 ARMv6T2, ARMv7 +fmt ADDW<c> <Rd>,SP,#<imm32> +extract32 11110,i.1,1,0000,0,1101,0,imm3.3,Rd.4,imm8.8 +pcode d = UInt(Rd); setflags = FALSE; imm32 = ZeroExtend(i:imm3:imm8, 32); if d == 15 then UNPREDICTABLE; + +sub_sp_minus_immediate: +Encoding T1 ARMv4T, ARMv5T*, ARMv6*, ARMv7 +fmt SUB<c> SP,#<imm32> +extract16 1011,0000,1,imm7.7 +pcode d = 13; setflags = FALSE; imm32 = ZeroExtend(imm7:'00', 32); +Encoding T2 ARMv6T2, ARMv7 +fmt SUB{S}<c> <Rd>,SP,#<imm32> +extract32 11110,i.1,0,1101,S.1,1101,0,imm3.3,Rd.4,imm8.8 +pcode if Rd == '1111' && S == '1' then SEE CMP (immediate); d = UInt(Rd); setflags = (S == '1'); imm32 = ThumbExpandImm(i:imm3:imm8); if d == 15 then UNPREDICTABLE; +Encoding T3 ARMv6T2, ARMv7 +fmt SUBW<c> <Rd>,SP,#<imm32> +extract32 11110,i.1,1,0101,0,1101,0,imm3.3,Rd.4,imm8.8 +pcode d = UInt(Rd); setflags = FALSE; imm32 = ZeroExtend(i:imm3:imm8, 32); if d == 15 then UNPREDICTABLE; + +sub_sp_minus_register: +Encoding T1 ARMv6T2, ARMv7 +fmt SUB{S}<c> <Rd>,SP,<Rm>{,<shift>} +extract32 11101,0,1,1101,S.1,1101,(0),imm3.3,Rd.4,imm2.2,type.2,Rm.4 +pcode_start +d = UInt(Rd); m = UInt(Rm); setflags = (S == '1'); +(shift_t, shift_n) = DecodeImmShift(type, imm3:imm2); +if d == 13 && (shift_t != SRType_LSL || shift_n > 3) then UNPREDICTABLE; +if d == 15 || BadReg(m) then UNPREDICTABLE; +pcode_end + +//----------------------------------------------------------------------------- + +str_register: +Encoding T1 ARMv4T, ARMv5T*, ARMv6*, ARMv7 +fmt STR<c> <Rt>,[<Rn>,<Rm>] +extract16 0101,000,Rm.3,Rn.3,Rt.3 +pcode t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); index = TRUE; add = TRUE; wback = FALSE; (shift_t, shift_n) = (SRType_LSL, 0); +Encoding T2 ARMv6T2, ARMv7 +fmt STR<c> <Rt>,[<Rn>,<Rm>{,<shift>}] +extract32 11111,00,0,0,10,0,Rn.4,Rt.4,0,00000,imm2.2,Rm.4 +pcode if Rn == '1111' then UNDEFINED; t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); index = TRUE; add = TRUE; wback = FALSE; (shift_t, shift_n) = (SRType_LSL, UInt(imm2)); if t == 15 || BadReg(m) then UNPREDICTABLE; + +strh_register: +Encoding T1 ARMv4T, ARMv5T*, ARMv6*, ARMv7 +fmt STRH<c> <Rt>,[<Rn>,<Rm>] +extract16 0101,001,Rm.3,Rn.3,Rt.3 +pcode t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); index = TRUE; add = TRUE; wback = FALSE; (shift_t, shift_n) = (SRType_LSL, 0); +Encoding T2 ARMv6T2, ARMv7 +fmt STRH<c> <Rt>,[<Rn>,<Rm>{,<shift>}] +extract32 11111,00,0,0,01,0,Rn.4,Rt.4,0,00000,imm2.2,Rm.4 +pcode if Rn == '1111' then UNDEFINED; t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); index = TRUE; add = TRUE; wback = FALSE; (shift_t, shift_n) = (SRType_LSL, UInt(imm2)); if BadReg(t) || BadReg(m) then UNPREDICTABLE; + +strb_register: +Encoding T1 ARMv4T, ARMv5T*, ARMv6*, ARMv7 +fmt STRB<c> <Rt>,[<Rn>,<Rm>] +extract16 0101,010,Rm.3,Rn.3,Rt.3 +pcode t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); index = TRUE; add = TRUE; wback = FALSE; (shift_t, shift_n) = (SRType_LSL, 0); +Encoding T2 ARMv6T2, ARMv7 +fmt STRB<c> <Rt>,[<Rn>,<Rm>{,<shift>}] +extract32 11111,00,0,0,00,0,Rn.4,Rt.4,0,00000,imm2.2,Rm.4 +pcode if Rn == '1111' then UNDEFINED; t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); index = TRUE; add = TRUE; wback = FALSE; (shift_t, shift_n) = (SRType_LSL, UInt(imm2)); if BadReg(t) || BadReg(m) then UNPREDICTABLE; + +ldr_register: +Encoding T1 ARMv4T, ARMv5T*, ARMv6*, ARMv7 +fmt LDR<c> <Rt>,[<Rn>,<Rm>] +extract16 0101,100,Rm.3,Rn.3,Rt.3 +pcode t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); index = TRUE; add = TRUE; wback = FALSE; (shift_t, shift_n) = (SRType_LSL, 0); +Encoding T2 ARMv6T2, ARMv7 +fmt LDR<c> <Rt>,[<Rn>,<Rm>{,<shift>}] +extract32 11111,00,0,0,10,1,Rn.4,Rt.4,0,00000,imm2.2,Rm.4 +pcode if Rn == '1111' then SEE LDR (literal); t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); index = TRUE; add = TRUE; wback = FALSE; (shift_t, shift_n) = (SRType_LSL, UInt(imm2)); if BadReg(m) then UNPREDICTABLE; if t == 15 && InITBlock() && !LastInITBlock() then UNPREDICTABLE; + +ldrh_register: +Encoding T1 ARMv4T, ARMv5T*, ARMv6*, ARMv7 +fmt LDRH<c> <Rt>,[<Rn>,<Rm>] +extract16 0101,101,Rm.3,Rn.3,Rt.3 +pcode t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); index = TRUE; add = TRUE; wback = FALSE; (shift_t, shift_n) = (SRType_LSL, 0); +Encoding T2 ARMv6T2, ARMv7 +fmt LDRH<c> <Rt>,[<Rn>,<Rm>{,<shift>}] +extract32 11111,00,0,0,01,1,Rn.4,Rt.4,0,00000,imm2.2,Rm.4 +pcode if Rn == '1111' then SEE LDRH (literal); if Rt == '1111' then SEE "nop"; t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); index = TRUE; add = TRUE; wback = FALSE; (shift_t, shift_n) = (SRType_LSL, UInt(imm2)); if t == 13 || BadReg(m) then UNPREDICTABLE; + +ldrb_register: +Encoding T1 ARMv4T, ARMv5T*, ARMv6*, ARMv7 +fmt LDRB<c> <Rt>,[<Rn>,<Rm>] +extract16 0101,110,Rm.3,Rn.3,Rt.3 +pcode t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); index = TRUE; add = TRUE; wback = FALSE; (shift_t, shift_n) = (SRType_LSL, 0); +Encoding T2 ARMv6T2, ARMv7 +fmt LDRB<c> <Rt>,[<Rn>,<Rm>{,<shift>}] +extract32 11111,00,0,0,00,1,Rn.4,Rt.4,0,00000,imm2.2,Rm.4 +pcode if Rt == '1111' then SEE PLD; if Rn == '1111' then SEE LDRB (literal); t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); index = TRUE; add = TRUE; wback = FALSE; (shift_t, shift_n) = (SRType_LSL, UInt(imm2)); if t == 13 || BadReg(m) then UNPREDICTABLE; + +ldrsh_register: +Encoding T1 ARMv4T, ARMv5T*, ARMv6*, ARMv7 +fmt LDRSH<c> <Rt>,[<Rn>,<Rm>] +extract16 0101,111,Rm.3,Rn.3,Rt.3 +pcode t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); index = TRUE; add = TRUE; wback = FALSE; (shift_t, shift_n) = (SRType_LSL, 0); +Encoding T2 ARMv6T2, ARMv7 +fmt LDRSH<c> <Rt>,[<Rn>,<Rm>{,<shift>}] +extract32 11111,00,1,0,01,1,Rn.4,Rt.4,0,00000,imm2.2,Rm.4 +pcode if Rn == '1111' then SEE LDRSH (literal); if Rt == '1111' then SEE "nop"; t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); index = TRUE; add = TRUE; wback = FALSE; (shift_t, shift_n) = (SRType_LSL, UInt(imm2)); if t == 13 || BadReg(m) then UNPREDICTABLE; + +strb_immediate: +Encoding T1 ARMv4T, ARMv5T*, ARMv6*, ARMv7 +fmt STRB<c> <Rt>,[<Rn>,#<imm5>] +extract16 011,1,0,imm5.5,Rn.3,Rt.3 +pcode t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm5, 32); index = TRUE; add = TRUE; wback = FALSE; +Encoding T2 ARMv6T2, ARMv7 +fmt STRB<c> <Rt>,[<Rn>,#<imm12>] +extract32 11111,00,0,1,00,0,Rn.4,Rt.4,imm12.12 +pcode if Rn == '1111' then UNDEFINED; t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); index = TRUE; add = TRUE; wback = FALSE; if BadReg(t) then UNPREDICTABLE; +Encoding T3 ARMv6T2, ARMv7 +fmt STRB<c> <Rt>,[<Rn>,#-<imm8>] +fmt STRB<c> <Rt>,[<Rn>,#<+/-><imm32>]! +fmt STRB<c> <Rt>,[<Rn>],#<+/-><imm32> +extract32 11111,00,0,0,00,0,Rn.4,Rt.4,1,P.1,U.1,W.1,imm8.8 +pcode if P == '1' && U == '1' && W == '0' then SEE STRBT; if Rn == '1111' || (P == '0' && W == '0') then UNDEFINED; t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32); index = (P == '1'); add = (U == '1'); wback = (W == '1'); if BadReg(t) || (wback && n == t) then UNPREDICTABLE; + +ldrb_literal: +Encoding T1 ARMv6T2, ARMv7 +fmt LDRB<c> <Rt>,<label> +extract32 11111,00,0,U.1,00,1,1111,Rt.4,imm12.12 +pcode if Rt == '1111' then SEE PLD; t = UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1'); if t == 13 then UNPREDICTABLE; + +ldrb_immediate: +Encoding T1 ARMv4T, ARMv5T*, ARMv6*, ARMv7 +fmt LDRB<c> <Rt>,[<Rn>{,#<imm5>}] +extract16 011,1,1,imm5.5,Rn.3,Rt.3 +pcode t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm5, 32); index = TRUE; add = TRUE; wback = FALSE; +Encoding T2 ARMv6T2, ARMv7 +fmt LDRB<c> <Rt>,[<Rn>{,#<imm12>}] +extract32 11111,00,0,1,00,1,Rn.4,Rt.4,imm12.12 +pcode if Rt == '1111' then SEE PLD; if Rn == '1111' then SEE LDRB (literal); t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); index = TRUE; add = TRUE; wback = FALSE; if t == 13 then UNPREDICTABLE; +Encoding T3 ARMv6T2, ARMv7 +fmt LDRB<c> <Rt>,[<Rn>,#-<imm8>] +fmt LDRB<c> <Rt>,[<Rn>,#<+/-><imm32>]! +fmt LDRB<c> <Rt>,[<Rn>],#<+/-><imm32> +extract32 11111,00,0,0,00,1,Rn.4,Rt.4,1,P.1,U.1,W.1,imm8.8 +pcode if Rt == '1111' && P == '1' && U == '0' && W == '0' then SEE PLD; if Rn == '1111' then SEE LDRB (literal); if P == '1' && U == '1' && W == '0' then SEE LDRBT; if P == '0' && W == '0' then UNDEFINED; t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32); index = (P == '1'); add = (U == '1'); wback = (W == '1'); if BadReg(t) || (wback && n == t) then UNPREDICTABLE; + +ldrbt: +Encoding T1 ARMv6T2, ARMv7 +fmt LDRBT<c> <Rt>,[<Rn>,#<imm8>] +extract32 11111,00,0,0,00,1,Rn.4,Rt.4,1,110,imm8.8 +pcode if Rn == '1111' then SEE LDRB (literal); t = UInt(Rt); n = UInt(Rn); postindex = FALSE; add = TRUE; register_form = FALSE; imm32 = ZeroExtend(imm8, 32); if BadReg(t) then UNPREDICTABLE; + +ldrsbt: +Encoding T1 ARMv6T2, ARMv7 +fmt LDRSBT<c> <Rt>,[<Rn>,#<imm8>] +extract32 11111,00,1,0,00,1,Rn.4,Rt.4,1,110,imm8.8 +pcode if Rn == '1111' then SEE LDRSB (literal); t = UInt(Rt); n = UInt(Rn); postindex = FALSE; add = TRUE; register_form = FALSE; imm32 = ZeroExtend(imm8, 32); if BadReg(t) then UNPREDICTABLE; + +ldrsb_literal: +Encoding T1 ARMv6T2, ARMv7 +fmt LDRSB<c> <Rt>,<label> +extract32 11111,00,1,U.1,00,1,1111,Rt.4,imm12.12 +pcode if Rt == '1111' then SEE PLI (register); t = UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1'); if t == 13 then UNPREDICTABLE; + +ldrsb_immediate: +Encoding T1 ARMv6T2, ARMv7 +fmt LDRSB<c> <Rt>,[<Rn>,#<imm12>] +extract32 11111,00,1,1,00,1,Rn.4,Rt.4,imm12.12 +pcode if Rt == '1111' then SEE PLI (register); if Rn == '1111' then SEE LDRSB (literal); t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); index = TRUE; add = TRUE; wback = FALSE; if t == 13 then UNPREDICTABLE; +Encoding T2 ARMv6T2, ARMv7 +fmt LDRSB<c> <Rt>,[<Rn>,#-<imm8>] +fmt LDRSB<c> <Rt>,[<Rn>,#<+/-><imm8>]! +fmt LDRSB<c> <Rt>,[<Rn>],#<+/-><imm8> +extract32 11111,00,1,0,00,1,Rn.4,Rt.4,1,P.1,U.1,W.1,imm8.8 +pcode if Rt == '1111' && P == '1' && U == '0' && W == '0' then SEE PLI (register); if Rn == '1111' then SEE LDRSB (literal); if P == '1' && U == '1' && W == '0' then SEE LDRSBT; if P == '0' && W == '0' then UNDEFINED; t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32); index = (P == '1'); add = (U == '1'); wback = (W == '1'); if BadReg(t) || (wback && n == t) then UNPREDICTABLE; + +ldrsb_register: +Encoding T1 ARMv4T, ARMv5T*, ARMv6*, ARMv7 +fmt LDRSB<c> <Rt>,[<Rn>,<Rm>] +extract16 0101,011,Rm.3,Rn.3,Rt.3 +pcode t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); index = TRUE; add = TRUE; wback = FALSE; (shift_t, shift_n) = (SRType_LSL, 0); +Encoding T2 ARMv6T2, ARMv7 +fmt LDRSB<c> <Rt>,[<Rn>,<Rm>{,<shift>}] +extract32 11111,00,1,0,00,1,Rn.4,Rt.4,0,00000,imm2.2,Rm.4 +pcode if Rt == '1111' then SEE PLI (register); if Rn == '1111' then SEE LDRSB (literal); t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); index = TRUE; add = TRUE; wback = FALSE; (shift_t, shift_n) = (SRType_LSL, UInt(imm2)); if t == 13 || BadReg(m) then UNPREDICTABLE; + +strh_immediate: +Encoding T1 ARMv4T, ARMv5T*, ARMv6*, ARMv7 +fmt STRH<c> <Rt>,[<Rn>{,#<imm32>}] +extract16 1000,0,imm5.5,Rn.3,Rt.3 +pcode t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm5:'0', 32); index = TRUE; add = TRUE; wback = FALSE; +Encoding T2 ARMv6T2, ARMv7 +fmt STRH<c> <Rt>,[<Rn>{,#<imm32>}] +extract32 11111,00,0,1,01,0,Rn.4,Rt.4,imm12.12 +pcode if Rn == '1111' then UNDEFINED; t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); index = TRUE; add = TRUE; wback = FALSE; if BadReg(t) then UNPREDICTABLE; +Encoding T3 ARMv6T2, ARMv7 +fmt STRH<c> <Rt>,[<Rn>,#-<imm32>] +fmt STRH<c> <Rt>,[<Rn>,#<+/-><imm32>]! +fmt STRH<c> <Rt>,[<Rn>],#<+/-><imm32> +extract32 11111,00,0,0,01,0,Rn.4,Rt.4,1,P.1,U.1,W.1,imm8.8 +pcode if P == '1' && U == '1' && W == '0' then SEE STRHT; if Rn == '1111' || (P == '0' && W == '0') then UNDEFINED; t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32); index = (P == '1'); add = (U == '1'); wback = (W == '1'); if BadReg(t) || (wback && n == t) then UNPREDICTABLE; + +ldrh_immediate: +Encoding T1 ARMv4T, ARMv5T*, ARMv6*, ARMv7 +fmt LDRH<c> <Rt>,[<Rn>{,#<imm32>}] +extract16 1000,1,imm5.5,Rn.3,Rt.3 +pcode t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm5:'0', 32); index = TRUE; add = TRUE; wback = FALSE; +Encoding T2 ARMv6T2, ARMv7 +fmt LDRH<c> <Rt>,[<Rn>{,#<imm32>}] +extract32 11111,00,0,1,01,1,Rn.4,Rt.4,imm12.12 +pcode if Rt == '1111' then SEE "nop"; if Rn == '1111' then SEE LDRH (literal); t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); index = TRUE; add = TRUE; wback = FALSE; if t == 13 then UNPREDICTABLE; +Encoding T3 ARMv6T2, ARMv7 +fmt LDRH<c> <Rt>,[<Rn>,#-<imm32>] +fmt LDRH<c> <Rt>,[<Rn>,#<+/-><imm32>]! +fmt LDRH<c> <Rt>,[<Rn>],#<+/-><imm32> +extract32 11111,00,0,0,01,1,Rn.4,Rt.4,1,P.1,U.1,W.1,imm8.8 +pcode if Rn == '1111' then SEE LDRH (literal); if Rt == '1111' && P == '1' && U == '0' && W == '0' then SEE "nop"; if P == '1' && U == '1' && W == '0' then SEE LDRHT; if P == '0' && W == '0' then UNDEFINED; t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32); index = (P == '1'); add = (U == '1'); wback = (W == '1'); if BadReg(t) || (wback && n == t) then UNPREDICTABLE; + +str_immediate: +Encoding T1 ARMv4T, ARMv5T*, ARMv6*, ARMv7 +fmt STR<c> <Rt>,[<Rn>{,#<imm32>}] +extract16 011,0,0,imm5.5,Rn.3,Rt.3 +pcode t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm5:'00', 32); index = TRUE; add = TRUE; wback = FALSE; +Encoding T2 ARMv4T, ARMv5T*, ARMv6*, ARMv7 +fmt STR<c> <Rt>,[SP,#<imm32>] +extract16 1001,0,Rt.3,imm8.8 +pcode t = UInt(Rt); n = 13; imm32 = ZeroExtend(imm8:'00', 32); index = TRUE; add = TRUE; wback = FALSE; +Encoding T3 ARMv6T2, ARMv7 +fmt STR<c> <Rt>,[<Rn>,#<imm32>] +extract32 11111,00,0,1,10,0,Rn.4,Rt.4,imm12.12 +pcode if Rn == '1111' then UNDEFINED; t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); index = TRUE; add = TRUE; wback = FALSE; if t == 15 then UNPREDICTABLE; +Encoding T4 ARMv6T2, ARMv7 +fmt STR<c> <Rt>,[<Rn>,#-<imm8>] +fmt STR<c> <Rt>,[<Rn>,#<+/-><imm32>]! +fmt STR<c> <Rt>,[<Rn>],#<+/-><imm32> +extract32 11111,00,0,0,10,0,Rn.4,Rt.4,1,P.1,U.1,W.1,imm8.8 +pcode if P == '1' && U == '1' && W == '0' then SEE STRT; if Rn == '1101' && P == '1' && U == '0' && W == '1' && imm8 == '00000100' then SEE PUSH; if Rn == '1111' || (P == '0' && W == '0') then UNDEFINED; t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32); index = (P == '1'); add = (U == '1'); wback = (W == '1'); if t == 15 || (wback && n == t) then UNPREDICTABLE; + +ldr_immediate: +Encoding T1 ARMv4T, ARMv5T*, ARMv6*, ARMv7 +fmt LDR<c> <Rt>,[<Rn>{,#<imm32>}] +extract16 011,0,1,imm5.5,Rn.3,Rt.3 +pcode t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm5:'00', 32); index = TRUE; add = TRUE; wback = FALSE; +Encoding T2 ARMv4T, ARMv5T*, ARMv6*, ARMv7 +fmt LDR<c> <Rt>,[SP{,#<imm32>}] +extract16 1001,1,Rt.3,imm8.8 +pcode t = UInt(Rt); n = 13; imm32 = ZeroExtend(imm8:'00', 32); index = TRUE; add = TRUE; wback = FALSE; +Encoding T3 ARMv6T2, ARMv7 +fmt LDR<c> <Rt>,[<Rn>{,#<imm32>}] +extract32 11111,00,0,1,10,1,Rn.4,Rt.4,imm12.12 +pcode if Rn == '1111' then SEE LDR (literal); t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); index = TRUE; add = TRUE; wback = FALSE; if t == 15 && InITBlock() && !LastInITBlock() then UNPREDICTABLE; +Encoding T4 ARMv6T2, ARMv7 +fmt LDR<c> <Rt>,[<Rn>,#-<imm32>] +fmt LDR<c> <Rt>,[<Rn>,#<+/-><imm32>]! +fmt LDR<c> <Rt>,[<Rn>],#<+/-><imm32> +extract32 11111,00,0,0,10,1,Rn.4,Rt.4,1,P.1,U.1,W.1,imm8.8 +pcode if Rn == '1111' then SEE LDR (literal); if P == '1' && U == '1' && W == '0' then SEE LDRT; if Rn == '1101' && P == '0' && U == '1' && W == '1' && imm8 == '00000100' then SEE POP; if P == '0' && W == '0' then UNDEFINED; t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32); index = (P == '1'); add = (U == '1'); wback = (W == '1'); if (wback && n == t) || (t == 15 && InITBlock() && !LastInITBlock()) then UNPREDICTABLE; + +//----------------------------------------------------------------------------- + +adr: +Encoding T1 ARMv4T, ARMv5T*, ARMv6*, ARMv7 +fmt ADR<c> <Rd>,#<imm32> +extract16 1010,0,Rd.3,imm8.8 +pcode d = UInt(Rd); imm32 = ZeroExtend(imm8:'00', 32); add = TRUE; +Encoding T2 ARMv6T2, ARMv7 +fmt SUBW<c> <Rd>,PC,#<imm32> +extract32 11110,i.1,10101,0,1111,0,imm3.3,Rd.4,imm8.8 +pcode d = UInt(Rd); imm32 = ZeroExtend(i:imm3:imm8, 32); add = FALSE; if BadReg(d) then UNPREDICTABLE; +Encoding T3 ARMv6T2, ARMv7 +fmt ADDW <Rd>,PC,#<imm32> +extract32 11110,i.1,10000,0,1111,0,imm3.3,Rd.4,imm8.8 +pcode d = UInt(Rd); imm32 = ZeroExtend(i:imm3:imm8, 32); add = TRUE; if BadReg(d) then UNPREDICTABLE; + + +//----------------------------------------------------------------------------- + +setend: +Encoding T1 ARMv6*, ARMv7 +fmt SETEND <E> +extract16 1011,0110,010,(1),E.1,(0)(0)(0) +pcode set_bigend = (E == '1'); if InITBlock() then UNPREDICTABLE; + +cps: +Encoding T1 ARMv6*, ARMv7 +fmt CPS<effect> <iflags> +extract16 1011,0110,011,im.1,(0),A.1,I.1,F.1 +pcode_start +enable = (im == '0'); +disable = (im == '1'); +changemode = FALSE; +affectA = (A == '1'); +affectI = (I == '1'); +affectF = (F == '1'); +if InITBlock() then UNPREDICTABLE; +pcode_end +Encoding T2 ARMv6T2, ARMv7 +fmt CPS<effect> <iflags>{,#<mode>} +extract32 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 +pcode_start +//if imod == '00' && M == '0' then SEE "Hint instructions"; +if mode != '00000' && M == '0' then UNPREDICTABLE; +if (imod<1>=='1' && A:I:F=='000') || (imod<1> == '0' && A:I:F != '000') then UNPREDICTABLE; +enable = (imod == '10') +disable = (imod == '11') +changemode = (M == '1') +affectA = (A == '1') +affectI = (I == '1') +affectF = (F == '1') +if imod == '01' || InITBlock() then UNPREDICTABLE +pcode_end + +// split this one to avoid the optional "N" in CB{N}Z +cbnz_cbz: +Encoding T1 ARMv6T2, ARMv7 +fmt CBNZ <Rn>,#<imm32> +extract16 1011,1,0,i.1,1,imm5.5,Rn.3 +pcode n = UInt(Rn); imm32 = ZeroExtend(i:imm5:'0', 32)+4; if InITBlock() then UNPREDICTABLE; +Encoding T1 ARMv6T2, ARMv7 +fmt CBZ <Rn>,#<imm32> +extract16 1011,0,0,i.1,1,imm5.5,Rn.3 +pcode n = UInt(Rn); imm32 = ZeroExtend(i:imm5:'0', 32)+4; if InITBlock() then UNPREDICTABLE; + +sxth: +Encoding T1 ARMv6*, ARMv7 +fmt SXTH<c> <Rd>,<Rm> +extract16 1011,0010,00,Rm.3,Rd.3 +pcode d = UInt(Rd); m = UInt(Rm); rotation = 0; +Encoding T2 ARMv6T2, ARMv7 +fmt SXTH<c> <Rd>,<Rm>{,<rotation>} +extract32 11111,010,0,000,1111,1111,Rd.4,1,(0),rotate.2,Rm.4 +pcode d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000'); if BadReg(d) || BadReg(m) then UNPREDICTABLE; + +sxtb: +Encoding T1 ARMv6*, ARMv7 +fmt SXTB<c> <Rd>,<Rm> +extract16 1011,0010,01,Rm.3,Rd.3 +pcode d = UInt(Rd); m = UInt(Rm); rotation = 0; +Encoding T2 ARMv6T2, ARMv7 +fmt SXTB<c> <Rd>,<Rm>{,<rotation>} +extract32 11111,010,0,100,1111,1111,Rd.4,1,(0),rotate.2,Rm.4 +pcode d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000'); if BadReg(d) || BadReg(m) then UNPREDICTABLE; + +uxth: +Encoding T1 ARMv6*, ARMv7 +fmt UXTH<c> <Rd>,<Rm> +extract16 1011,0010,10,Rm.3,Rd.3 +pcode d = UInt(Rd); m = UInt(Rm); rotation = 0; +Encoding T2 ARMv6T2, ARMv7 +fmt UXTH<c> <Rd>,<Rm>{,<rotation>} +extract32 11111,010,0,001,1111,1111,Rd.4,1,(0),rotate.2,Rm.4 +pcode d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000'); if BadReg(d) || BadReg(m) then UNPREDICTABLE; + +uxtb: +Encoding T1 ARMv6*, ARMv7 +fmt UXTB<c> <Rd>,<Rm> +extract16 1011,0010,11,Rm.3,Rd.3 +pcode d = UInt(Rd); m = UInt(Rm); rotation = 0; +Encoding T2 ARMv6T2, ARMv7 +fmt UXTB<c> <Rd>,<Rm>{,<rotation>} +extract32 11111,010,0,101,1111,1111,Rd.4,1,(0),rotate.2,Rm.4 +pcode d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000'); if BadReg(d) || BadReg(m) then UNPREDICTABLE; + +push: +Encoding T1 ARMv4T, ARMv5T*, ARMv6*, ARMv7 +fmt PUSH<c> <registers> +extract16 1011,0,10,M.1,register_list.8 +pcode registers = '0':M:'000000':register_list; if BitCount(registers) < 1 then UNPREDICTABLE; +Encoding T2 ARMv6T2, ARMv7 +fmt PUSH<c> <registers> +extract32 11101,00,xx0,1,0,1101,(0),M.1,(0),register_list.13 +pcode registers = '0':M:'0':register_list; if BitCount(registers) < 2 then UNPREDICTABLE; +Encoding T3 ARMv6T2, ARMv7 +fmt PUSH<c> <registers> +extract32 11111,00,0,0,10,0,1101,Rt.4,1,101,00000100 +pcode t = UInt(Rt); registers = Zeros(16); registers<t> = '1'; if BadReg(t) then UNPREDICTABLE; + +rev: +Encoding T1 ARMv6*, ARMv7 +fmt REV<c> <Rd>,<Rm> +extract16 1011,1010,00,Rm.3,Rd.3 +pcode d = UInt(Rd); m = UInt(Rm); +Encoding T2 ARMv6*, ARMv7 +fmt REV<c>.W <Rd>,<Rm> +extract32 11111,010,1,001,Rm.4,1111,Rd.4,1,000,Rm.4 +pcode if !Consistent(Rm) then UNPREDICTABLE; d = UInt(Rd); m = UInt(Rm); if BadReg(d) || BadReg(m) then UNPREDICTABLE; + +rev16: +Encoding T1 ARMv6*, ARMv7 +fmt REV16<c> <Rd>,<Rm> +extract16 1011,1010,01,Rm.3,Rd.3 +pcode d = UInt(Rd); m = UInt(Rm); +Encoding T2 ARMv6T2, ARMv7 +fmt REV16<c>.W <Rd>,<Rm> +extract32 11111,010,1,001,Rm.4,1111,Rd.4,1,001,Rm.4 +pcode_start +if !Consistent(Rm) then UNPREDICTABLE; +d = UInt(Rd); m = UInt(Rm); +if BadReg(d) || BadReg(m) then UNPREDICTABLE; +nop +pcode_end + +revsh: +Encoding T1 ARMv6*, ARMv7 +fmt REVSH<c> <Rd>,<Rm> +extract16 1011,1010,11,Rm.3,Rd.3 +pcode d = UInt(Rd); m = UInt(Rm); +Encoding T2 ARMv6T2, ARMv7 +fmt REVSH<c>.W <Rd>,<Rm> +extract32 11111,010,1,001,Rm.4,1111,Rd.4,1,011,Rm.4 +pcode if !Consistent(Rm) then UNPREDICTABLE; d = UInt(Rd); m = UInt(Rm); if BadReg(d) || BadReg(m) then UNPREDICTABLE; + +pop: +Encoding T1 ARMv4T, ARMv5T*, ARMv6*, ARMv7 +fmt POP<c> <registers> +extract16 1011,1,10,P.1,register_list.8 +pcode registers = P:'0000000':register_list; if BitCount(registers) < 1 then UNPREDICTABLE; +Encoding T2 ARMv6T2, ARMv7 +fmt POP<c> <registers> +extract32 11101,00,010,1,1,1101,P.1,M.1,(0),register_list.13 +pcode registers = P:M:'0':register_list; if BitCount(registers) < 2 || (P == '1' && M == '1') then UNPREDICTABLE; if registers<15> == '1' && InITBlock() && !LastInITBlock() then UNPREDICTABLE; +Encoding T3 ARMv6T2, ARMv7 +fmt POP<c> <registers> +extract32 11111,00,0,0,10,1,1101,Rt.4,1,011,00000100 +pcode t = UInt(Rt); registers = Zeros(16); registers<t> = '1'; if t == 13 || (t == 15 && InITBlock() && !LastInITBlock()) then UNPREDICTABLE; + +bkpt: +Encoding T1 ARMv5T*, ARMv6*, ARMv7 +fmt BKPT #<imm32> +extract16 1011,1110,imm8.8 +pcode imm32 = ZeroExtend(imm8, 32); + +//----------------------------------------------------------------------------- + +it: +Encoding T1 ARMv6T2, ARMv7 +fmt IT<mask> <firstcond> +extract16 1011,1111,firstcond.4,mask.4 +pcode_start +if mask == '0000' then SEE it_related_encodings; +if firstcond == '1111' then UNPREDICTABLE; +if firstcond == '1110' && BitCount(mask) != 1 then UNPREDICTABLE; +if InITBlock() then UNPREDICTABLE; +pcode_end + +it_related_encodings: +Encoding T1 ARMv6T2, ARMv7 +fmt HINT #<imm> +extract16 1011,1111,imm.4,xxxx +pcode nop + +hint_undoc: +Encoding T1 ARMv6T2, ARMv7 +fmt HINT #<op2> +extract32 111,10,0111010,xxxx,10,x,0,x,op1.3,op2.8 +pcode nop + +nop: +Encoding T1 ARMv6T2, ARMv7 +fmt NOP<c> +extract16 1011,1111,0000,0000 +pcode nop; +Encoding T2 ARMv6T2, ARMv7 +fmt NOP<c>.W +extract32 11110,0,111,01,0,(1)(1)(1)(1),10,(0),0,(0),000,00000000 +pcode nop; + +yield: +Encoding T1 ARMv7 +fmt YIELD<c> +extract16 1011,1111,0001,0000 +pcode nop; +Encoding T2 ARMv7 +fmt YIELD<c>.W +extract32 11110,0,111,01,0,(1)(1)(1)(1),10,(0),0,(0),000,00000001 +pcode nop; + +wfe: +Encoding T1 ARMv7 +fmt WFE<c> +extract16 1011,1111,0010,0000 +pcode nop; +Encoding T2 ARMv7 +fmt WFE<c>.W +extract32 11110,0,111,01,0,(1)(1)(1)(1),10,(0),0,(0),000,00000010 +pcode nop; + +wfi: +Encoding T1 ARMv7 +fmt WFI<c> +extract16 1011,1111,0011,0000 +pcode nop; +Encoding T2 ARMv7 +fmt WFI<c>.W +extract32 11110,0,111,01,0,(1)(1)(1)(1),10,(0),0,(0),000,00000011 +pcode nop; + +sev: +Encoding T1 ARMv7 +fmt SEV<c> +extract16 1011,1111,0100,0000 +pcode nop; +Encoding T2 ARMv7 +fmt SEV<c>.W +extract32 11110,0,111,01,0,(1)(1)(1)(1),10,(0),0,(0),000,00000100 +pcode nop; + +// on ARMv6T2, this is NOP +// option is decoded by the "debug system" +dbg: +Encoding T1 ARMv7 +fmt DBG<c> #<option> +extract32 11110,0,111,01,0,(1)(1)(1)(1),10,(0),0,(0),000,1111,option.4 +pcode nop; + +//----------------------------------------------------------------------------- + +stm: +Encoding T1 ARMv4T, ARMv5T*, ARMv6*, ARMv7 +fmt STM<c> <Rn>!,<registers> +extract16 1100,0,Rn.3,register_list.8 +pcode n = UInt(Rn); registers = '00000000':register_list; wback = TRUE; if BitCount(registers) < 1 then UNPREDICTABLE; +Encoding T2 ARMv6T2, ARMv7 +fmt STM<c> <Rn>{!},<registers> +extract32 11101,00,010,W.1,0,Rn.4,(0),M.1,register_list.14 +pcode n = UInt(Rn); registers = '0':M:register_list; wback = (W == '1'); if n == 15 || BitCount(registers) < 2 then UNPREDICTABLE; if wback && registers<n> == '1' then UNPREDICTABLE; + +ldm: +Encoding T1 ARMv4T, ARMv5T*, ARMv6*, ARMv7 +fmt LDM<c> <Rn>{!},<registers> +extract16 1100,1,Rn.3,register_list.8 +pcode n = UInt(Rn); registers = '00000000':register_list; wback = (registers<n> == '0'); if BitCount(registers) < 1 then UNPREDICTABLE; +Encoding T2 ARMv6T2, ARMv7 +fmt LDM<c> <Rn>{!},<registers> +extract32 11101,00,010,W.1,1,Rn.4,P.1,M.1,register_list.14 +pcode if W == '1' && Rn == '1101' then SEE POP; n = UInt(Rn); registers = P:M:register_list; wback = (W == '1'); if n == 15 || BitCount(registers) < 2 || (P == '1' && M == '1') then UNPREDICTABLE; if registers<15> == '1' && InITBlock() && !LastInITBlock() then UNPREDICTABLE; if wback && registers<n> == '1' then UNPREDICTABLE; + +//----------------------------------------------------------------------------- + +b: +Encoding T1 ARMv4T, ARMv5T*, ARMv6*, ARMv7 +fmt B<c> #<imm32> +extract16 1101,cond.4,imm8.8 +pcode if cond == '1110' then UNDEFINED; if cond == '1111' then SEE SVC; imm32 = SignExtend(imm8:'0', 32); if InITBlock() then UNPREDICTABLE; +Encoding T2 ARMv4T, ARMv5T*, ARMv6*, ARMv7 +fmt B<c> #<imm32> +extract16 11100,imm11.11 +pcode imm32 = SignExtend(imm11:'0', 32); if InITBlock() && !LastInITBlock() then UNPREDICTABLE; +Encoding T3 ARMv6T2, ARMv7 +fmt B<c> #<imm32> +extract32 11110,S.1,cond.4,imm6.6,10,J1.1,0,K1.1,imm11.11 +pcode imm32 = SignExtend(S:K1:J1:imm6:imm11:'0', 32); if InITBlock() then UNPREDICTABLE; +Encoding T4 ARMv6T2, ARMv7 +fmt B<c> #<imm32> +extract32 11110,S.1,imm10.10,10,J1.1,1,K1.1,imm11.11 +pcode I1 = NOT(J1 EOR S); X1 = NOT(K1 EOR S); imm32 = SignExtend(S:I1:X1:imm10:imm11:'0', 32); if InITBlock() && !LastInITBlock() then UNPREDICTABLE; + +svc: +Encoding T1 ARMv4T, ARMv5T*, ARMv6*, ARMv7 +fmt SVC<c> #<imm8> +extract16 1101,1111,imm8.8 +pcode imm32 = ZeroExtend(imm8, 32); + +udf: +Encoding T1 ARMv4T, ARMv5T*, ARMv6*, ARMv7 +fmt UDF<c> #<imm8> +extract16 1101,1110,imm8.8 +pcode imm32 = ZeroExtend(imm8,32); +Encoding T2 ARMv6T2, ARMv7 +fmt UDF<c>.W #<imm16> +extract32 111,10,1111111,imm4.4,1,010,imm12.12 +pcode imm32 = ZeroExtend(imm4:imm12,32); + +//----------------------------------------------------------------------------- + +srs: +Encoding T1 ARMv6T2, ARMv7 +fmt SRSDB<c> SP{!},#<mode> +extract32 11101,00,00,0,W.1,0,(1)(1)(0)(1),(1)(1),(0)(0)(0)(0)(0)(0)(0)(0)(0),mode.5 +pcode wback = (W == '1'); increment = FALSE; wordhigher = FALSE; if !IsSecure() && mode == '10110' then UNPREDICTABLE; if !IsSecure() && mode == '10001' && NSACR.RFR == '1' then UNPREDICTABLE; +Encoding T2 ARMv6T2, ARMv7 +fmt SRS{IA}<c> SP{!},#<mode> +extract32 11101,00,11,0,W.1,0,(1)(1)(0)(1),(1)(1),(0)(0)(0)(0)(0)(0)(0)(0)(0),mode.5 +pcode wback = (W == '1'); increment = TRUE; wordhigher = FALSE; if !IsSecure() && mode == '10110' then UNPREDICTABLE; if !IsSecure() && mode == '10001' && NSACR.RFR == '1' then UNPREDICTABLE; +Encoding A1 ARMv6*, ARMv7 +fmt SRS{<amode>} SP{!},#<mode> +extract32 1111,100,P.1,U.1,1,W.1,0,(1)(1)(0)(1),(0)(0)(0)(0),(0)(1)(0)(1),(0)(0)(0),mode.5 +pcode wback = (W == '1'); inc = (U == '1'); wordhigher = (P == U); if !IsSecure() && mode == '10110' then UNPREDICTABLE; if !IsSecure() && mode == '10001' && NSACR.RFR == '1' then UNPREDICTABLE; + +rfe: +Encoding T1 ARMv6T2, ARMv7 +fmt RFEDB<c> <Rn>{!} +extract32 11101,00,00,0,W.1,1,Rn.4,(1)(1),(0)(0)(0)(0)(0)(0)(0)(0)(0)(0)(0)(0)(0)(0) +pcode n = UInt(Rn); wback = (W == '1'); increment = FALSE; wordhigher = FALSE; if n == 15 then UNPREDICTABLE; if InITBlock() && !LastInITBlock() then UNPREDICTABLE; +Encoding T2 ARMv6T2, ARMv7 +fmt RFE{IA}<c> <Rn>{!} +extract32 11101,00,11,0,W.1,1,Rn.4,(1)(1),(0)(0)(0)(0)(0)(0)(0)(0)(0)(0)(0)(0)(0)(0) +pcode n = UInt(Rn); wback = (W == '1'); increment = TRUE; wordhigher = FALSE; if n == 15 then UNPREDICTABLE; if InITBlock() && !LastInITBlock() then UNPREDICTABLE; +Encoding A1 ARMv6*, ARMv7 +fmt RFE{<amode>} <Rn>{!} +extract32 1111,100,P.1,U.1,0,W.1,1,Rn.4,(0)(0)(0)(0),(1)(0)(1)(0),(0)(0)(0)(0)(0)(0)(0)(0) +pcode n = UInt(Rn); wback = (W == '1'); inc = (U == '1'); wordhigher = (P == U); if n == 15 then UNPREDICTABLE; + +stmdb: +Encoding T1 ARMv6T2, ARMv7 +fmt STMDB<c> <Rn>{!},<registers> +extract32 11101,00,100,W.1,0,Rn.4,(0),M.1,register_list.14 +pcode if W == '1' && Rn == '1101' then SEE PUSH; n = UInt(Rn); registers = '0':M:register_list; wback = (W == '1'); if n == 15 || BitCount(registers) < 2 then UNPREDICTABLE; if wback && registers<n> == '1' then UNPREDICTABLE; + +ldmdb: +Encoding T1 ARMv6T2, ARMv7 +fmt LDMDB<c> <Rn>{!},<registers> +extract32 11101,00,100,W.1,1,Rn.4,P.1,M.1,register_list.14 +pcode n = UInt(Rn); registers = P:M:register_list; wback = (W == '1'); if n == 15 || BitCount(registers) < 2 || (P == '1' && M == '1') then UNPREDICTABLE; if registers<15> == '1' && InITBlock() && !LastInITBlock() then UNPREDICTABLE; if wback && registers<n> == '1' then UNPREDICTABLE; + +//----------------------------------------------------------------------------- + +strex: +Encoding T1 ARMv6T2, ARMv7 +fmt STREX<c> <Rd>,<Rt>,[<Rn>{,#<imm32>}] +extract32 11101,00,0,0,1,0,0,Rn.4,Rt.4,Rd.4,imm8.8 +pcode d = UInt(Rd); t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8:'00', 32); if BadReg(d) || BadReg(t) || n == 15 then UNPREDICTABLE; if d == n || d == t then UNPREDICTABLE; + +ldrex: +Encoding T1 ARMv6T2, ARMv7 +fmt LDREX<c> <Rt>,[<Rn>{,#<imm32>}] +extract32 11101,00,0,0,1,0,1,Rn.4,Rt.4,(1)(1)(1)(1),imm8.8 +pcode t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8:'00', 32); if BadReg(t) || n == 15 then UNPREDICTABLE; + +strd_immediate: +Encoding T1 ARMv6T2, ARMv7 +fmt STRD<c> <Rt>,<Rt2>,[<Rn>{,#<+/-><imm32>}] +fmt STRD<c> <Rt>,<Rt2>,[<Rn>,#<+/-><imm32>]! +fmt STRD<c> <Rt>,<Rt2>,[<Rn>],#<+/-><imm32> +extract32 11101,00,P.1,U.1,1,W.1,0,Rn.4,Rt.4,Rt2.4,imm8.8 +pcode t = UInt(Rt); t2 = UInt(Rt2); n = UInt(Rn); imm32 = ZeroExtend(imm8:'00', 32); index = (P == '1'); add = (U == '1'); wback = (W == '1'); if wback && (n == t || n == t2) then UNPREDICTABLE; if n == 15 || BadReg(t) || BadReg(t2) then UNPREDICTABLE; + +ldrd_immediate: +Encoding T1 ARMv6T2, ARMv7 +fmt LDRD<c> <Rt>,<Rt2>,[<Rn>{,#<+/-><imm32>}] +fmt LDRD<c> <Rt>,<Rt2>,[<Rn>,#<+/-><imm32>]! +fmt LDRD<c> <Rt>,<Rt2>,[<Rn>],#<+/-><imm32> +extract32 11101,00,P.1,U.1,1,W.1,1,Rn.4,Rt.4,Rt2.4,imm8.8 +pcode if Rn == '1111' then SEE LDRD (literal); t = UInt(Rt); t2 = UInt(Rt2); n = UInt(Rn); imm32 = ZeroExtend(imm8:'00', 32); index = (P == '1'); add = (U == '1'); wback = (W == '1'); if wback && (n == t || n == t2) then UNPREDICTABLE; if BadReg(t) || BadReg(t2) || t == t2 then UNPREDICTABLE; + +ldrd_literal: +Encoding T1 ARMv6T2, ARMv7 +fmt LDRD<c> <Rt>,<Rt2>,<label> +extract32 11101,00,P.1,U.1,1,(0),1,1111,Rt.4,Rt2.4,imm8.8 +pcode t = UInt(Rt); t2 = UInt(Rt2); imm32 = ZeroExtend(imm8:'00', 32); add = (U == '1'); if BadReg(t) || BadReg(t2) || t == t2 then UNPREDICTABLE; + +strexb: +Encoding T1 ARMv7 +fmt STREXB<c> <Rd>,<Rt>,[<Rn>] +extract32 11101,000110,0,Rn.4,Rt.4,(1)(1)(1)(1),0100,Rd.4 +pcode d = UInt(Rd); t = UInt(Rt); n = UInt(Rn); if BadReg(d) || BadReg(t) || n == 15 then UNPREDICTABLE; if d == n || d == t then UNPREDICTABLE; + +strexh: +Encoding T1 ARMv7 +fmt STREXH<c> <Rd>,<Rt>,[<Rn>] +extract32 11101,000110,0,Rn.4,Rt.4,(1)(1)(1)(1),0101,Rd.4 +pcode d = UInt(Rd); t = UInt(Rt); n = UInt(Rn); if BadReg(d) || BadReg(t) || n == 15 then UNPREDICTABLE; if d == n || d == t then UNPREDICTABLE; + +strexd: +Encoding T1 ARMv7 +fmt STREXD<c> <Rd>,<Rt>,<Rt2>,[<Rn>] +extract32 11101,000110,0,Rn.4,Rt.4,Rt2.4,0111,Rd.4 +pcode d = UInt(Rd); t = UInt(Rt); t2 = UInt(Rt2); n = UInt(Rn); if BadReg(d) || BadReg(t) || BadReg(t2) || n == 15 then UNPREDICTABLE; if d == n || d == t || d == t2 then UNPREDICTABLE; + +tbb_tbh: +Encoding T1 ARMv6T2, ARMv7 +fmt TBB<c> [<Rn>,<Rm>] +extract32 11101,00,0,1,1,0,1,Rn.4,(1)(1)(1)(1),(0)(0)(0)(0),000,0,Rm.4 +pcode n = UInt(Rn); m = UInt(Rm); if n == 13 || BadReg(m) then UNPREDICTABLE; if InITBlock() && !LastInITBlock() then UNPREDICTABLE; +Encoding T2 ARMv6T2, ARMv7 +fmt TBH<c> [<Rn>,<Rm>,LSL #1] +extract32 11101,00,0,1,1,0,1,Rn.4,(1)(1)(1)(1),(0)(0)(0)(0),000,1,Rm.4 +pcode n = UInt(Rn); m = UInt(Rm); if n == 13 || BadReg(m) then UNPREDICTABLE; if InITBlock() && !LastInITBlock() then UNPREDICTABLE; + +ldrexb: +Encoding T1 ARMv7 +fmt LDREXB<c> <Rt>,[<Rn>] +extract32 11101,000110,1,Rn.4,Rt.4,(1)(1)(1)(1),0100,(1)(1)(1)(1) +pcode t = UInt(Rt); n = UInt(Rn); if BadReg(t) || n == 15 then UNPREDICTABLE; + +ldrexh: +Encoding T1 ARMv7 +fmt LDREXH<c> <Rt>,[<Rn>] +extract32 11101,000110,1,Rn.4,Rt.4,(1)(1)(1)(1),0101,(1)(1)(1)(1) +pcode t = UInt(Rt); n = UInt(Rn); if BadReg(t) || n == 15 then UNPREDICTABLE; + +ldrexd: +Encoding T1 ARMv7 +fmt LDREXD<c> <Rt>,<Rt2>,[<Rn>] +extract32 11101,000110,1,Rn.4,Rt.4,Rt2.4,0111,(1)(1)(1)(1) +pcode t = UInt(Rt); t2 = UInt(Rt2); n = UInt(Rn); if BadReg(t) || BadReg(t2) || t == t2 || n == 15 then UNPREDICTABLE; + +stlb: +Encoding T1 ARMv7 +fmt STLB<c> <Rt>,[<Rn>] +extract32 111,0100,01,1,00,Rn.4,Rt.4,(1)(1)(1)(1),1000,(1)(1)(1)(1) +pcode t = UInt(Rt); n = UInt(Rn); if BadReg(t) || n == 15 then UNPREDICTABLE; + +stlh: +Encoding T1 ARMv7 +fmt STLH<c> <Rt>,[<Rn>] +extract32 111,0100,01,1,00,Rn.4,Rt.4,(1)(1)(1)(1),1001,(1)(1)(1)(1) +pcode t = UInt(Rt); n = UInt(Rn); if BadReg(t) || n == 15 then UNPREDICTABLE; + +stl: +Encoding T1 ARMv7 +fmt STL<c> <Rt>,[<Rn>] +extract32 111,0100,01,1,00,Rn.4,Rt.4,(1)(1)(1)(1),1010,(1)(1)(1)(1) +pcode t = UInt(Rt); n = UInt(Rn); if BadReg(t) || n == 15 then UNPREDICTABLE; + +stlexb: +Encoding T1 ARMv7 +fmt STLEXB<c> <Rd>,<Rt>,[<Rn>] +extract32 111,0100,01,1,00,Rn.4,Rt.4,(1)(1)(1)(1),1100,Rd.4 +pcode d = UInt(Rd); t = UInt(Rt); n = UInt(Rn); if BadReg(d) || BadReg(t) || n == 15 then UNPREDICTABLE; if d == n || d == t then UNPREDICTABLE; + +stlexh: +Encoding T1 ARMv7 +fmt STLEXH<c> <Rd>,<Rt>,[<Rn>] +extract32 111,0100,01,1,00,Rn.4,Rt.4,(1)(1)(1)(1),1101,Rd.4 +pcode d = UInt(Rd); t = UInt(Rt); n = UInt(Rn); if BadReg(d) || BadReg(t) || n == 15 then UNPREDICTABLE; if d == n || d == t then UNPREDICTABLE; + +stlex: +Encoding T1 ARMv7 +fmt STLEX<c> <Rd>,<Rt>,[<Rn>] +extract32 111,0100,01,1,00,Rn.4,Rt.4,(1)(1)(1)(1),1110,Rd.4 +pcode d = UInt(Rd); t = UInt(Rt); n = UInt(Rn); if BadReg(d) || BadReg(t) || n == 15 then UNPREDICTABLE; if d == n || d == t then UNPREDICTABLE; + +ldab: +Encoding T1 ARMv7 +fmt LDAB<c> <Rt>,[<Rn>] +extract32 11101,000110,1,Rn.4,Rt.4,(1)(1)(1)(1),1000,(1)(1)(1)(1) +pcode t = UInt(Rt); n = UInt(Rn); if BadReg(t) || n == 15 then UNPREDICTABLE; + +ldah: +Encoding T1 ARMv7 +fmt LDAH<c> <Rt>,[<Rn>] +extract32 11101,000110,1,Rn.4,Rt.4,(1)(1)(1)(1),1001,(1)(1)(1)(1) +pcode t = UInt(Rt); n = UInt(Rn); if BadReg(t) || n == 15 then UNPREDICTABLE; + +lda: +Encoding T1 ARMv7 +fmt LDA<c> <Rt>,[<Rn>] +extract32 11101,000110,1,Rn.4,Rt.4,(1)(1)(1)(1),1010,(1)(1)(1)(1) +pcode t = UInt(Rt); n = UInt(Rn); if BadReg(t) || n == 15 then UNPREDICTABLE; + +ldaexb: +Encoding T1 ARMv7 +fmt LDAEXB<c> <Rt>,[<Rn>] +extract32 11101,000110,1,Rn.4,Rt.4,(1)(1)(1)(1),1100,(1)(1)(1)(1) +pcode t = UInt(Rt); n = UInt(Rn); if BadReg(t) || n == 15 then UNPREDICTABLE; + +ldaexh: +Encoding T1 ARMv7 +fmt LDAEXH<c> <Rt>,[<Rn>] +extract32 11101,000110,1,Rn.4,Rt.4,(1)(1)(1)(1),1101,(1)(1)(1)(1) +pcode t = UInt(Rt); n = UInt(Rn); if BadReg(t) || n == 15 then UNPREDICTABLE; + +ldaex: +Encoding T1 ARMv7 +fmt LDAEX<c> <Rt>,[<Rn>] +extract32 11101,000110,1,Rn.4,Rt.4,(1)(1)(1)(1),1110,(1)(1)(1)(1) +pcode t = UInt(Rt); n = UInt(Rn); if BadReg(t) || n == 15 then UNPREDICTABLE; + +//----------------------------------------------------------------------------- + +orn_register: +Encoding T1 ARMv6T2, ARMv7 +fmt ORN{S}<c> <Rd>,<Rn>,<Rm>{,<shift>} +extract32 11101,01,0011,S.1,Rn.4,(0),imm3.3,Rd.4,imm2.2,type.2,Rm.4 +pcode if Rn == '1111' then SEE MVN (register); d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = (S == '1'); (shift_t, shift_n) = DecodeImmShift(type, imm3:imm2); if BadReg(d) || n == 13 || BadReg(m) then UNPREDICTABLE; + +teq_register: +Encoding T1 ARMv6T2, ARMv7 +fmt TEQ<c> <Rn>,<Rm>{,<shift>} +extract32 11101,01,0100,1,Rn.4,(0),imm3.3,1111,imm2.2,type.2,Rm.4 +pcode n = UInt(Rn); m = UInt(Rm); (shift_t, shift_n) = DecodeImmShift(type, imm3:imm2); if BadReg(n) || BadReg(m) then UNPREDICTABLE; + +pkh: +Encoding T1 ARMv6T2, ARMv7 +fmt PKHBT<c> <Rd>,<Rn>,<Rm>{,<shift>} +extract32 11101,01,0110,0,Rn.4,(0),imm3.3,Rd.4,imm2.2,0,0,Rm.4 +pcode tb = 0; d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); tbform = (tb == '1'); (shift_t, shift_n) = DecodeImmShift(tb:'0', imm3:imm2); if BadReg(d) || BadReg(n) || BadReg(m) then UNPREDICTABLE; +Encoding T1 ARMv6T2, ARMv7 +fmt PKHTB<c> <Rd>,<Rn>,<Rm>{,<shift>} +extract32 11101,01,0110,0,Rn.4,(0),imm3.3,Rd.4,imm2.2,1,0,Rm.4 +pcode tb = 1; d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); tbform = (tb == '1'); (shift_t, shift_n) = DecodeImmShift(tb:'0', imm3:imm2); if BadReg(d) || BadReg(n) || BadReg(m) then UNPREDICTABLE; + + +//----------------------------------------------------------------------------- + +stc_stc2: +Encoding T1 ARMv6T2, ARMv7 +fmt STC<c> <coproc>,<CRd>,[<Rn>{,#<+/-><imm32>}] +fmt STC<c> <coproc>,<CRd>,[<Rn>,#<+/-><imm32>]! +fmt STC<c> <coproc>,<CRd>,[<Rn>],#<+/-><imm32> +fmt STC<c> <coproc>,<CRd>,[<Rn>],<coproc_option> +extract32 1110,110,P.1,U.1,0,W.1,0,Rn.4,CRd.4,coproc.4,imm8.8 +pcode D=0; if P == '0' && U == '0' && D == '0' && W == '0' then UNDEFINED; if P == '0' && U == '0' && D == '1' && W == '0' then SEE MCRR, MCRR2; if coproc == '1010' || coproc == '1011' then SEE "nop"; n = UInt(Rn); cp = UInt(coproc); imm32 = ZeroExtend(imm8:'00', 32); index = (P == '1'); add = (U == '1'); wback = (W == '1'); if n == 15 && (wback || CurrentInstrSet() != InstrSet_ARM) then UNPREDICTABLE; +Encoding T1 ARMv6T2, ARMv7 +fmt STCL<c> <coproc>,<CRd>,[<Rn>{,#<+/-><imm32>}] +fmt STCL<c> <coproc>,<CRd>,[<Rn>,#<+/-><imm32>]! +fmt STCL<c> <coproc>,<CRd>,[<Rn>],#<+/-><imm32> +fmt STCL<c> <coproc>,<CRd>,[<Rn>],<coproc_option> +extract32 1110,110,P.1,U.1,1,W.1,0,Rn.4,CRd.4,coproc.4,imm8.8 +pcode D=1; if P == '0' && U == '0' && D == '0' && W == '0' then UNDEFINED; if P == '0' && U == '0' && D == '1' && W == '0' then SEE MCRR, MCRR2; if coproc == '1010' || coproc == '1011' then SEE "nop"; n = UInt(Rn); cp = UInt(coproc); imm32 = ZeroExtend(imm8:'00', 32); index = (P == '1'); add = (U == '1'); wback = (W == '1'); if n == 15 && (wback || CurrentInstrSet() != InstrSet_ARM) then UNPREDICTABLE; +Encoding T2 ARMv6T2, ARMv7 +fmt STC2<c> <coproc>,<CRd>,[<Rn>{,#<+/-><imm32>}] +fmt STC2<c> <coproc>,<CRd>,[<Rn>,#<+/-><imm32>]! +fmt STC2<c> <coproc>,<CRd>,[<Rn>],#<+/-><imm32> +fmt STC2<c> <coproc>,<CRd>,[<Rn>],<coproc_option> +extract32 1111,110,P.1,U.1,0,W.1,0,Rn.4,CRd.4,coproc.4,imm8.8 +pcode D=0; if P == '0' && U == '0' && D == '0' && W == '0' then UNDEFINED; if P == '0' && U == '0' && D == '1' && W == '0' then SEE MCRR, MCRR2; n = UInt(Rn); cp = UInt(coproc); imm32 = ZeroExtend(imm8:'00', 32); index = (P == '1'); add = (U == '1'); wback = (W == '1'); if n == 15 && (wback || CurrentInstrSet() != InstrSet_ARM) then UNPREDICTABLE; +Encoding T2 ARMv6T2, ARMv7 +fmt STC2L<c> <coproc>,<CRd>,[<Rn>{,#<+/-><imm32>}] +fmt STC2L<c> <coproc>,<CRd>,[<Rn>,#<+/-><imm32>]! +fmt STC2L<c> <coproc>,<CRd>,[<Rn>],#<+/-><imm32> +fmt STC2L<c> <coproc>,<CRd>,[<Rn>],<coproc_option> +extract32 1111,110,P.1,U.1,D.1,W.1,0,Rn.4,CRd.4,coproc.4,imm8.8 +pcode D=1; if P == '0' && U == '0' && D == '0' && W == '0' then UNDEFINED; if P == '0' && U == '0' && D == '1' && W == '0' then SEE MCRR, MCRR2; n = UInt(Rn); cp = UInt(coproc); imm32 = ZeroExtend(imm8:'00', 32); index = (P == '1'); add = (U == '1'); wback = (W == '1'); if n == 15 && (wback || CurrentInstrSet() != InstrSet_ARM) then UNPREDICTABLE; + +ldc_immediate: +Encoding T1 ARMv6T2, ARMv7 +fmt LDC<c> <coproc>,<CRd>,[<Rn>{,#<+/-><imm32>}] +fmt LDC<c> <coproc>,<CRd>,[<Rn>,#<+/-><imm32>]! +fmt LDC<c> <coproc>,<CRd>,[<Rn>],#<+/-><imm32> +fmt LDC<c> <coproc>,<CRd>,[<Rn>],<coproc_option> +extract32 1110,110,P.1,U.1,0,W.1,1,Rn.4,CRd.4,coproc.4,imm8.8 +pcode D=0; if Rn == '1111' then SEE LDC (literal); if P == '0' && U == '0' && D == '0' && W == '0' then UNDEFINED; if P == '0' && U == '0' && D == '1' && W == '0' then SEE MRRC, MRRC2; if coproc == '1010' || coproc == '1011' then SEE "nop"; n = UInt(Rn); cp = UInt(coproc); imm32 = ZeroExtend(imm8:'00', 32); index = (P == '1'); add = (U == '1'); wback = (W == '1'); +Encoding T1L ARMv6T2, ARMv7 +fmt LDCL<c> <coproc>,<CRd>,[<Rn>{,#<+/-><imm32>}] +fmt LDCL<c> <coproc>,<CRd>,[<Rn>,#<+/-><imm32>]! +fmt LDCL<c> <coproc>,<CRd>,[<Rn>],#<+/-><imm32> +fmt LDCL<c> <coproc>,<CRd>,[<Rn>],<coproc_option> +extract32 1110,110,P.1,U.1,1,W.1,1,Rn.4,CRd.4,coproc.4,imm8.8 +pcode D=1; if Rn == '1111' then SEE LDC (literal); if P == '0' && U == '0' && D == '0' && W == '0' then UNDEFINED; if P == '0' && U == '0' && D == '1' && W == '0' then SEE MRRC, MRRC2; if coproc == '1010' || coproc == '1011' then SEE "nop"; n = UInt(Rn); cp = UInt(coproc); imm32 = ZeroExtend(imm8:'00', 32); index = (P == '1'); add = (U == '1'); wback = (W == '1'); +Encoding T2 ARMv6T2, ARMv7 +fmt LDC2<c> <coproc>,<CRd>,[<Rn>{,#<+/-><imm32>}] +fmt LDC2<c> <coproc>,<CRd>,[<Rn>,#<+/-><imm32>]! +fmt LDC2<c> <coproc>,<CRd>,[<Rn>],#<+/-><imm32> +fmt LDC2<c> <coproc>,<CRd>,[<Rn>],<coproc_option> +extract32 1111,110,P.1,U.1,0,W.1,1,Rn.4,CRd.4,coproc.4,imm8.8 +pcode_start +D=0; +if Rn == '1111' then SEE LDC (literal); +if P == '0' && U == '0' && D == '0' && W == '0' then UNDEFINED; +if P == '0' && U == '0' && D == '1' && W == '0' then SEE MRRC, MRRC2; +n = UInt(Rn); +cp = UInt(coproc); +imm32 = ZeroExtend(imm8:'00', 32); +index = (P == '1'); +add = (U == '1'); +wback = (W == '1'); +pcode_end +Encoding T2L ARMv6T2, ARMv7 +fmt LDC2L<c> <coproc>,<CRd>,[<Rn>{,#<+/-><imm32>}] +fmt LDC2L<c> <coproc>,<CRd>,[<Rn>,#<+/-><imm32>]! +fmt LDC2L<c> <coproc>,<CRd>,[<Rn>],#<+/-><imm32> +fmt LDC2L<c> <coproc>,<CRd>,[<Rn>],<imm8> +extract32 1111,110,P.1,U.1,1,W.1,1,Rn.4,CRd.4,coproc.4,imm8.8 +pcode D=1; if Rn == '1111' then SEE LDC (literal); if P == '0' && U == '0' && D == '0' && W == '0' then UNDEFINED; if P == '0' && U == '0' && D == '1' && W == '0' then SEE MRRC, MRRC2; n = UInt(Rn); cp = UInt(coproc); imm32 = ZeroExtend(imm8:'00', 32); index = (P == '1'); add = (U == '1'); wback = (W == '1'); + +ldc_literal: +Encoding T1 ARMv6T2, ARMv7 +fmt LDC<c> <coproc>,<CRd>,<label> +fmt LDC<c> <coproc>,<CRd>,<label>! +fmt LDC<c> <coproc>,<CRd>,[PC],#<+/-><imm32> +fmt LDC<c> <coproc>,<CRd>,[PC],<imm8> +extract32 1110,110,P.1,U.1,0,W.1,1,1111,CRd.4,coproc.4,imm8.8 +pcode D=0; if P == '0' && U == '0' && D == '0' && W == '0' then UNDEFINED; if P == '0' && U == '0' && D == '1' && W == '0' then SEE MRRC, MRRC2; if coproc == '1010' || coproc == '1011' then SEE "nop"; index = (P == '1'); add = (U == '1'); cp = UInt(coproc); imm32 = ZeroExtend(imm8:'00', 32); if W == '1' || (P == '0' && CurrentInstrSet() != InstrSet_ARM) then UNPREDICTABLE; +Encoding T1 ARMv6T2, ARMv7 +fmt LDCL<c> <coproc>,<CRd>,<label> +fmt LDCL<c> <coproc>,<CRd>,<label>! +fmt LDCL<c> <coproc>,<CRd>,[PC],#<+/-><imm32> +fmt LDCL<c> <coproc>,<CRd>,[PC],<imm8> +extract32 1110,110,P.1,U.1,1,W.1,1,1111,CRd.4,coproc.4,imm8.8 +pcode D=1; if P == '0' && U == '0' && D == '0' && W == '0' then UNDEFINED; if P == '0' && U == '0' && D == '1' && W == '0' then SEE MRRC, MRRC2; if coproc == '1010' || coproc == '1011' then SEE "nop"; index = (P == '1'); add = (U == '1'); cp = UInt(coproc); imm32 = ZeroExtend(imm8:'00', 32); if W == '1' || (P == '0' && CurrentInstrSet() != InstrSet_ARM) then UNPREDICTABLE; +Encoding T2 ARMv6T2, ARMv7 +fmt LDC2<c> <coproc>,<CRd>,<label> +fmt LDC2<c> <coproc>,<CRd>,<label>! +fmt LDC2<c> <coproc>,<CRd>,[PC],#<+/-><imm32> +fmt LDC2<c> <coproc>,<CRd>,[PC],<imm8> +extract32 1111,110,P.1,U.1,0,W.1,1,1111,CRd.4,coproc.4,imm8.8 +pcode D=0; if P == '0' && U == '0' && D == '0' && W == '0' then UNDEFINED; if P == '0' && U == '0' && D == '1' && W == '0' then SEE MRRC, MRRC2; index = (P == '1'); add = (U == '1'); cp = UInt(coproc); imm32 = ZeroExtend(imm8:'00', 32); if W == '1' || (P == '0' && CurrentInstrSet() != InstrSet_ARM) then UNPREDICTABLE; +Encoding T2 ARMv6T2, ARMv7 +fmt LDC2L<c> <coproc>,<CRd>,<label> +fmt LDC2L<c> <coproc>,<CRd>,<label>! +fmt LDC2L<c> <coproc>,<CRd>,[PC],#<+/-><imm32> +fmt LDC2L<c> <coproc>,<CRd>,[PC],<imm8> +extract32 1111,110,P.1,U.1,1,W.1,1,1111,CRd.4,coproc.4,imm8.8 +pcode D=1; if P == '0' && U == '0' && D == '0' && W == '0' then UNDEFINED; if P == '0' && U == '0' && D == '1' && W == '0' then SEE MRRC, MRRC2; index = (P == '1'); add = (U == '1'); cp = UInt(coproc); imm32 = ZeroExtend(imm8:'00', 32); if W == '1' || (P == '0' && CurrentInstrSet() != InstrSet_ARM) then UNPREDICTABLE; + +mcrr_mcrr2: +Encoding T1 ARMv6T2, ARMv7 +fmt MCRR<c> <coproc>,#<opc1>,<Rt>,<Rt2>,<CRm> +extract32 1110,110,0,0,1,0,0,Rt2.4,Rt.4,coproc.4,opc1.4,CRm.4 +pcode if coproc == '1010' || coproc == '1011' then SEE "nop"; t = UInt(Rt); t2 = UInt(Rt2); cp = UInt(coproc); if t == 15 || t2 == 15 then UNPREDICTABLE; if (t == 13 || t2 == 13) && (CurrentInstrSet() != InstrSet_ARM) then UNPREDICTABLE; +Encoding T2 ARMv6T2, ARMv7 +fmt MCRR2<c> <coproc>,#<opc1>,<Rt>,<Rt2>,<CRm> +extract32 1111,110,0,0,1,0,0,Rt2.4,Rt.4,coproc.4,opc1.4,CRm.4 +pcode t = UInt(Rt); t2 = UInt(Rt2); cp = UInt(coproc); if t == 15 || t2 == 15 then UNPREDICTABLE; if (t == 13 || t2 == 13) && (CurrentInstrSet() != InstrSet_ARM) then UNPREDICTABLE; + +mrrc_mrrc2: +Encoding T1 ARMv6T2, ARMv7 +fmt MRRC<c> <coproc>,#<opc1>,<Rt>,<Rt2>,<CRm> +extract32 1110,110,0,0,1,0,1,Rt2.4,Rt.4,coproc.4,opc1.4,CRm.4 +pcode if coproc == '1010' || coproc == '1011' then SEE "nop"; t = UInt(Rt); t2 = UInt(Rt2); cp = UInt(coproc); if t == 15 || t2 == 15 || t == t2 then UNPREDICTABLE; if (t == 13 || t2 == 13) && (CurrentInstrSet() != InstrSet_ARM) then UNPREDICTABLE; +Encoding T2 ARMv6T2, ARMv7 +fmt MRRC2<c> <coproc>,#<opc1>,<Rt>,<Rt2>,<CRm> +extract32 1111,110,0,0,1,0,1,Rt2.4,Rt.4,coproc.4,opc1.4,CRm.4 +pcode t = UInt(Rt); t2 = UInt(Rt2); cp = UInt(coproc); if t == 15 || t2 == 15 || t == t2 then UNPREDICTABLE; if (t == 13 || t2 == 13) && (CurrentInstrSet() != InstrSet_ARM) then UNPREDICTABLE; + +cdp_cdp2: +Encoding T1 ARMv6T2, ARMv7 +fmt CDP<c> <coproc>,#<opc1>,<CRd>,<CRn>,<CRm>,#<opc2> +extract32 1110,1110,opc1.4,CRn.4,CRd.4,coproc.4,opc2.3,0,CRm.4 +pcode if coproc == '1010' || coproc == '1011' then SEE "nop"; cp = UInt(coproc); +Encoding T2 ARMv6T2, ARMv7 +fmt CDP2<c> <coproc>,#<opc1>,<CRd>,<CRn>,<CRm>,#<opc2> +extract32 1111,1110,opc1.4,CRn.4,CRd.4,coproc.4,opc2.3,0,CRm.4 +pcode cp = UInt(coproc); + +//----------------------------------------------------------------------------- +and_immediate: +Encoding T1 ARMv6T2, ARMv7 +fmt AND{S}<c> <Rd>,<Rn>,#<imm32> +extract32 11110,i.1,0,0000,S.1,Rn.4,0,imm3.3,Rd.4,imm8.8 +pcode if Rd == '1111' && S == '1' then SEE TST (immediate); d = UInt(Rd); n = UInt(Rn); setflags = (S == '1'); (imm32, carry) = ThumbExpandImm_C(i:imm3:imm8, APSR.C); if BadReg(d) || BadReg(n) then UNPREDICTABLE; + +tst_immediate: +Encoding T1 ARMv6T2, ARMv7 +fmt TST<c> <Rn>,#<imm32> +extract32 11110,i.1,0,0000,1,Rn.4,0,imm3.3,1111,imm8.8 +pcode n = UInt(Rn); (imm32, carry) = ThumbExpandImm_C(i:imm3:imm8, APSR.C); if BadReg(n) then UNPREDICTABLE; + +bic_immediate: +Encoding T1 ARMv6T2, ARMv7 +fmt BIC{S}<c> <Rd>,<Rn>,#<imm32> +extract32 11110,i.1,0,0001,S.1,Rn.4,0,imm3.3,Rd.4,imm8.8 +pcode d = UInt(Rd); n = UInt(Rn); setflags = (S == '1'); (imm32, carry) = ThumbExpandImm_C(i:imm3:imm8, APSR.C); if BadReg(d) || BadReg(n) then UNPREDICTABLE; + +orr_immediate: +Encoding T1 ARMv6T2, ARMv7 +fmt ORR{S}<c> <Rd>,<Rn>,#<imm32> +extract32 11110,i.1,0,0010,S.1,Rn.4,0,imm3.3,Rd.4,imm8.8 +pcode if Rn == '1111' then SEE MOV (immediate); d = UInt(Rd); n = UInt(Rn); setflags = (S == '1'); (imm32, carry) = ThumbExpandImm_C(i:imm3:imm8, APSR.C); if BadReg(d) || n == 13 then UNPREDICTABLE; + +orn_immediate: +Encoding T1 ARMv6T2, ARMv7 +fmt ORN{S}<c> <Rd>,<Rn>,#<imm32> +extract32 11110,i.1,0,0011,S.1,Rn.4,0,imm3.3,Rd.4,imm8.8 +pcode if Rn == '1111' then SEE MVN (immediate); d = UInt(Rd); n = UInt(Rn); setflags = (S == '1'); (imm32, carry) = ThumbExpandImm_C(i:imm3:imm8, APSR.C); if BadReg(d) || n == 13 then UNPREDICTABLE; + +mvn_immediate: +Encoding T1 ARMv6T2, ARMv7 +fmt MVN{S}<c> <Rd>,#<imm32> +extract32 11110,i.1,0,0011,S.1,1111,0,imm3.3,Rd.4,imm8.8 +pcode d = UInt(Rd); setflags = (S == '1'); (imm32, carry) = ThumbExpandImm_C(i:imm3:imm8, APSR.C); if BadReg(d) then UNPREDICTABLE; + +eor_immediate: +Encoding T1 ARMv6T2, ARMv7 +fmt EOR{S}<c> <Rd>,<Rn>,#<imm32> +extract32 11110,i.1,0,0100,S.1,Rn.4,0,imm3.3,Rd.4,imm8.8 +pcode if Rd == '1111' && S == '1' then SEE TEQ (immediate); d = UInt(Rd); n = UInt(Rn); setflags = (S == '1'); (imm32, carry) = ThumbExpandImm_C(i:imm3:imm8, APSR.C); if BadReg(d) || BadReg(n) then UNPREDICTABLE; + +teq_immediate: +Encoding T1 ARMv6T2, ARMv7 +fmt TEQ<c> <Rn>,#<imm32> +extract32 11110,i.1,0,0100,1,Rn.4,0,imm3.3,1111,imm8.8 +pcode n = UInt(Rn); (imm32, carry) = ThumbExpandImm_C(i:imm3:imm8, APSR.C); if BadReg(n) then UNPREDICTABLE; + +cmn_immediate: +Encoding T1 ARMv6T2, ARMv7 +fmt CMN<c> <Rn>,#<imm32> +extract32 11110,i.1,0,1000,1,Rn.4,0,imm3.3,1111,imm8.8 +pcode n = UInt(Rn); imm32 = ThumbExpandImm(i:imm3:imm8); if n == 15 then UNPREDICTABLE; + +adc_immediate: +Encoding T1 ARMv6T2, ARMv7 +fmt ADC{S}<c> <Rd>,<Rn>,#<imm32> +extract32 11110,i.1,0,1010,S.1,Rn.4,0,imm3.3,Rd.4,imm8.8 +pcode d = UInt(Rd); n = UInt(Rn); setflags = (S == '1'); imm32 = ThumbExpandImm(i:imm3:imm8); if BadReg(d) || BadReg(n) then UNPREDICTABLE; + +sbc_immediate: +Encoding T1 ARMv6T2, ARMv7 +fmt SBC{S}<c> <Rd>,<Rn>,#<imm32> +extract32 11110,i.1,0,1011,S.1,Rn.4,0,imm3.3,Rd.4,imm8.8 +pcode d = UInt(Rd); n = UInt(Rn); setflags = (S == '1'); imm32 = ThumbExpandImm(i:imm3:imm8); if BadReg(d) || BadReg(n) then UNPREDICTABLE; + +//----------------------------------------------------------------------------- + +movt: +Encoding T1 ARMv6T2, ARMv7 +fmt MOVT<c> <Rd>,#<imm16> +extract32 11110,i.1,10,1,1,0,0,imm4.4,0,imm3.3,Rd.4,imm8.8 +pcode d = UInt(Rd); imm16 = imm4:i:imm3:imm8; if BadReg(d) then UNPREDICTABLE; + +ssat: +Encoding T1 ARMv6T2, ARMv7 +fmt SSAT<c> <Rd>,#<saturate_to>,<Rn>{,<shift>} +extract32 11110,(0),11,00,sh.1,0,Rn.4,0,imm3.3,Rd.4,imm2.2,(0),sat_imm.5 +pcode if sh == '1' && (imm3:imm2) == '00000' then SEE SSAT16; d = UInt(Rd); n = UInt(Rn); saturate_to = UInt(sat_imm)+1; (shift_t, shift_n) = DecodeImmShift(sh:'0', imm3:imm2); if BadReg(d) || BadReg(n) then UNPREDICTABLE; + +ssat16: +Encoding T1 ARMv6T2, ARMv7 +fmt SSAT16<c> <Rd>,#<saturate_to>,<Rn> +extract32 11110,(0),11,001,0,Rn.4,0,000,Rd.4,00,(0)(0),sat_imm.4 +pcode d = UInt(Rd); n = UInt(Rn); saturate_to = UInt(sat_imm)+1; if BadReg(d) || BadReg(n) then UNPREDICTABLE; + +sbfx: +Encoding T1 ARMv6T2, ARMv7 +fmt SBFX<c> <Rd>,<Rn>,#<lsbit>,#<width> +extract32 11110,(0),11,010,0,Rn.4,0,imm3.3,Rd.4,imm2.2,(0),widthm1.5 +pcode d = UInt(Rd); n = UInt(Rn); lsbit = UInt(imm3:imm2); width = UInt(widthm1)+1; if BadReg(d) || BadReg(n) then UNPREDICTABLE; + +// low order bits {0,1,...,N} are copied from source +// destination bits are specified as {lsbit, lsbit+1, ..., msbit} +// Rd<msbit:lsbit> = Rn<msbit-lsbit:0> +// +// instruction encodes only: msb lsbit +// width is calculated from that + +bfi: +Encoding T1 ARMv6T2, ARMv7 +fmt BFI<c> <Rd>,<Rn>,#<lsbit>,#<width> +extract32 11110,(0),11,011,0,Rn.4,0,imm3.3,Rd.4,imm2.2,(0),msb.5 +pcode if Rn == '1111' then SEE BFC; d = UInt(Rd); n = UInt(Rn); msbit = UInt(msb); lsbit = UInt(imm3:imm2); width=msbit - lsbit + 1; if BadReg(d) || n == 13 then UNPREDICTABLE; + +bfc: +Encoding T1 ARMv6T2, ARMv7 +fmt BFC<c> <Rd>,#<lsbit>,#<width> +extract32 11110,(0),11,011,0,1111,0,imm3.3,Rd.4,imm2.2,(0),msb.5 +pcode d = UInt(Rd); msbit = UInt(msb); lsbit = UInt(imm3:imm2); width=msbit-lsbit+1; if BadReg(d) then UNPREDICTABLE; + +usat: +Encoding T1 ARMv6T2, ARMv7 +fmt USAT<c> <Rd>,#<saturate_to>,<Rn>{,<shift>} +extract32 11110,(0),11,10,sh.1,0,Rn.4,0,imm3.3,Rd.4,imm2.2,(0),sat_imm.5 +pcode_start +if sh == '1' && (imm3:imm2) == '00000' then SEE USAT16; +d = UInt(Rd); +n = UInt(Rn); +saturate_to = UInt(sat_imm); +(shift_t, shift_n) = DecodeImmShift(sh:'0', imm3:imm2); +if BadReg(d) || BadReg(n) then UNPREDICTABLE; +pcode_end + +usat16: +Encoding T1 ARMv6T2, ARMv7 +fmt USAT16<c> <Rd>,#<saturate_to>,<Rn> +extract32 11110,(0),11,101,0,Rn.4,0,000,Rd.4,00,(0)(0),sat_imm.4 +pcode d = UInt(Rd); n = UInt(Rn); saturate_to = UInt(sat_imm); if BadReg(d) || BadReg(n) then UNPREDICTABLE; + +ubfx: +Encoding T1 ARMv6T2, ARMv7 +fmt UBFX<c> <Rd>,<Rn>,#<lsbit>,#<width> +extract32 11110,(0),11,110,0,Rn.4,0,imm3.3,Rd.4,imm2.2,(0),widthm1.5 +pcode d = UInt(Rd); n = UInt(Rn); lsbit = UInt(imm3:imm2); width = UInt(widthm1)+1; if BadReg(d) || BadReg(n) then UNPREDICTABLE; + +//----------------------------------------------------------------------------- + +msr_reg_app: +Encoding T1 ARMv6T2, ARMv7 +fmt MSR<c> <spec_reg>,<Rn> +extract32 11110,0,1110,0,0,Rn.4,10,(0),0,mask.2,00,SYSm.8 +pcode_start +n = UInt(Rn); +write_nzcvq = (mask<1> == '1'); +write_g = (mask<0> == '1'); +if mask==0 then UNPREDICTABLE; +if n == 15 then UNPREDICTABLE; +pcode_end + +msr_reg_sys: +Encoding T1 ARMv6T2, ARMv7 +fmt MSR<c> <spec_reg>,<Rn> +extract32 11110,0,1110,0,R.1,Rn.4,10,(0),0,mask.4,SYSm.8 +pcode_start +n = UInt(Rn); +write_spsr = (R == '1'); +if mask == '0000' then UNPREDICTABLE; +if BadReg(n) then UNPREDICTABLE; +pcode_end + +//----------------------------------------------------------------------------- + +enterx_leavex: +Encoding T1 ThumbEE +fmt ENTERX +extract32 11110011101,1,(1)(1)(1)(1),10,(0),0,(1)(1)(1)(1),000,1,(1)(1)(1)(1) +pcode if InITBlock() then NOT_PERMITTED; +Encoding T1 ThumbEE +fmt LEAVEX +extract32 11110011101,1,(1)(1)(1)(1),10,(0),0,(1)(1)(1)(1),000,0,(1)(1)(1)(1) +pcode if InITBlock() then NOT_PERMITTED; + +clrex: +Encoding T1 ARMv7 +fmt CLREX<c> +extract32 11110,0,111,01,1,(1)(1)(1)(1),10,(0),0,(1)(1)(1)(1),0010,(1)(1)(1)(1) +pcode nop; + +dsb: +Encoding T1 ARMv7 +fmt DSB<c> <barrier_option> +extract32 11110,0,111,01,1,(1)(1)(1)(1),10,(0),0,(1)(1)(1)(1),0100,barrier_option.4 +pcode nop; + +dmb: +Encoding T1 ARMv7 +fmt DMB<c> <barrier_option> +extract32 11110,0,111,01,1,(1)(1)(1)(1),10,(0),0,(1)(1)(1)(1),0101,barrier_option.4 +pcode nop; + +isb: +Encoding T1 ARMv7 +fmt ISB<c> <barrier_option> +extract32 11110,0,111,01,1,(1)(1)(1)(1),10,(0),0,(1)(1)(1)(1),0110,barrier_option.4 +pcode nop; + +//----------------------------------------------------------------------------- + +bxj: +Encoding T1 ARMv6T2, ARMv7 +fmt BXJ<c> <Rm> +extract32 11110,0,1111,00,Rm.4,10,(0),0,(1)(1)(1)(1),(0)(0)(0)(0)(0)(0)(0)(0) +pcode m = UInt(Rm); if BadReg(m) then UNPREDICTABLE; if InITBlock() && !LastInITBlock() then UNPREDICTABLE; + +subs_pc_lr_related: +Encoding T1 ARMv6T2, ARMv7 +fmt SUBS<c> PC,LR,#<imm8> +extract32 11110,0,1111,0,1,(1)(1)(1)(0),10,(0),0,(1)(1)(1)(1),imm8.8 +pcode n = 14; imm32 = ZeroExtend(imm8, 32); register_form = FALSE; opcode = '0010'; if InITBlock() && !LastInITBlock() then UNPREDICTABLE; + +// notice addition of "R.1" here instead of 0, to differentiate +// normal mrs at A8.6.102 and system mrs at B6.1.5 +mrs: +Encoding T1 ARMv6T2, ARMv7 +fmt MRS<c> <Rd>,<spec_reg> +extract32 11110,0,1111,1,R.1,(1)(1)(1)(1),10,(0),0,Rd.4,SYSm.8 +pcode_start +d = UInt(Rd); +read_spsr = (R == '1'); +if BadReg(d) then UNPREDICTABLE; +pcode_end + +smc: +Encoding T1 SECURITY_EXTENSIONS +fmt SMC<c> #<imm4> +extract32 11110,1111111,imm4.4,1000,(0)(0)(0)(0)(0)(0)(0)(0)(0)(0)(0)(0) +pcode imm32 = ZeroExtend(imm4, 32); if InITBlock() && !LastInITBlock() then UNPREDICTABLE; + +// encodings split for the dual arch cases, J1==K1==1 and otherwise + +bl_blx_immediate: +Encoding T1 ARMv4T, ARMv5T*, ARMv6*, ARMv7 +fmt BL<c> #<imm32> +extract32 11110,S.1,imm10.10,11,1,1,1,imm11.11 +pcode I1 = NOT(1 EOR S); X1 = NOT(1 EOR S); imm32 = SignExtend(S:I1:X1:imm10:imm11:'0', 32); toARM = FALSE; if InITBlock() && !LastInITBlock() then UNPREDICTABLE; +Encoding T1 ARMv6T2, ARMv7 +fmt BL<c> #<imm32> +extract32 11110,S.1,imm10.10,11,J1.1,1,K1.1,imm11.11 +pcode I1 = NOT(J1 EOR S); X1 = NOT(K1 EOR S); imm32 = SignExtend(S:I1:X1:imm10:imm11:'0', 32); toARM = FALSE; if InITBlock() && !LastInITBlock() then UNPREDICTABLE; +Encoding T2 ARMv5T*, ARMv6*, ARMv7 +fmt BLX<c> #<imm32> +extract32 11110,S.1,imm10H.10,11,1,0,1,imm10L.10,0 +pcode if CurrentInstrSet() == InstrSet_ThumbEE then UNDEFINED; I1 = NOT(1 EOR S); X1 = NOT(1 EOR S); imm32 = SignExtend(S:I1:X1:imm10H:imm10L:'00', 32); toARM = TRUE; if InITBlock() && !LastInITBlock() then UNPREDICTABLE; +Encoding T2 ARMv6T2, ARMv7 +fmt BLX<c> #<imm32> +extract32 11110,S.1,imm10H.10,11,J1.1,0,K1.1,imm10L.10,0 +pcode if CurrentInstrSet() == InstrSet_ThumbEE then UNDEFINED; I1 = NOT(J1 EOR S); X1 = NOT(K1 EOR S); imm32 = SignExtend(S:I1:X1:imm10H:imm10L:'00', 32); toARM = TRUE; if InITBlock() && !LastInITBlock() then UNPREDICTABLE; + +//----------------------------------------------------------------------------- + +strbt: +Encoding T1 ARMv6T2, ARMv7 +fmt STRBT<c> <Rt>,[<Rn>,#<imm8>] +extract32 11111,00,0,0,00,0,Rn.4,Rt.4,1,110,imm8.8 +pcode_start +if Rn == '1111' then UNDEFINED; +t = UInt(Rt); +n = UInt(Rn); +postindex = FALSE; +add = TRUE; +register_form = FALSE; +imm32 = ZeroExtend(imm8, 32); +if BadReg(t) then UNPREDICTABLE; +pcode_end + +strht: +Encoding T1 ARMv6T2, ARMv7 +fmt STRHT<c> <Rt>,[<Rn>,#<imm8>] +extract32 11111,00,0,0,01,0,Rn.4,Rt.4,1,110,imm8.8 +pcode if Rn == '1111' then UNDEFINED; t = UInt(Rt); n = UInt(Rn); postindex = FALSE; add = TRUE; register_form = FALSE; imm32 = ZeroExtend(imm8, 32); if BadReg(t) then UNPREDICTABLE; + +strt: +Encoding T1 ARMv6T2, ARMv7 +fmt STRT<c> <Rt>,[<Rn>,#<imm8>] +extract32 11111,00,0,0,10,0,Rn.4,Rt.4,1,110,imm8.8 +pcode if Rn == '1111' then UNDEFINED; t = UInt(Rt); n = UInt(Rn); postindex = FALSE; add = TRUE; register_form = FALSE; imm32 = ZeroExtend(imm8, 32); if BadReg(t) then UNPREDICTABLE; + +//----------------------------------------------------------------------------- + +// pld is [p]re[l]oad [d]ata +// pli is [p]re[l]oad [i]nstruction + +pld: +extract32 11111,00,0,x,0,x,x,Rn.4,1111,bits.5 +on Rn,bits +1111,xxxxx pld_literal +xxxx,xxxxx pld_pldw_immediate +xxxx,00000 pld_pldw_register + +// 11111,00,0,U.1,0,(0),1,1111,1111,imm12.12 +// +// 11111,00,0, 1,0, 0,1,Rn.4,1111,imm12.12 +// 11111,00,0, 1,0, 1,1,Rn.4,1111,imm12.12 +// 11111,00,0, 0,0, 0,1,Rn.4,1111,1,100,imm8.8 +// 11111,00,0, 0,0, 1,1,Rn.4,1111,1,100,imm8.8 +// +// 11111,00,0, 0,0, 0,1,Rn.4,1111,0,00000,imm2.2,Rm.4 +// 11111,00,0, 0,0, 1,1,Rn.4,1111,0,00000,imm2.2,Rm.4 + +pld_literal: +Encoding T1 ARMv6T2, ARMv7 +fmt PLD<c> <label> +extract32 11111,00,0,U.1,0,(0),1,1111,1111,imm12.12 +pcode imm32 = ZeroExtend(imm12, 32); add = (U == '1'); + +pld_pldw_immediate: +Encoding T1 ARMv6T2, ARMv7 +fmt PLD<c> [<Rn>,#<imm12>] +extract32 11111,00,0,1,0,0,1,Rn.4,1111,imm12.12 +pcode if Rn == '1111' then SEE PLD (literal); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); add = TRUE; +Encoding T1 ARMv7_WITH_MP +fmt PLDW<c> [<Rn>,#<imm12>] +extract32 11111,00,0,1,0,1,1,Rn.4,1111,imm12.12 +pcode if Rn == '1111' then SEE PLD (literal); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); add = TRUE; +Encoding T2 ARMv6T2, ARMv7 +fmt PLD<c> [<Rn>,#-<imm8>] +extract32 11111,00,0,0,0,0,1,Rn.4,1111,1,100,imm8.8 +pcode if Rn == '1111' then SEE PLD (literal); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32); add = FALSE; +Encoding T2 ARMv7_WITH_MP +fmt PLDW<c> [<Rn>,#-<imm8>] +extract32 11111,00,0,0,0,1,1,Rn.4,1111,1,100,imm8.8 +pcode if Rn == '1111' then SEE PLD (literal); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32); add = FALSE; + +pld_pldw_register: +Encoding T1 ARMv6T2, ARMv7 +fmt PLD<c> [<Rn>,<Rm>{,<shift>}] +extract32 11111,00,0,0,0,0,1,Rn.4,1111,0,00000,imm2.2,Rm.4 +pcode if Rn == '1111' then SEE PLD (literal); n = UInt(Rn); m = UInt(Rm); add = TRUE; (shift_t, shift_n) = (SRType_LSL, UInt(imm2)); if BadReg(m) then UNPREDICTABLE; +Encoding T1 ARMv7_WITH_MP +fmt PLDW<c> [<Rn>,<Rm>{,<shift>}] +extract32 11111,00,0,0,0,1,1,Rn.4,1111,0,00000,imm2.2,Rm.4 +pcode if Rn == '1111' then SEE PLD (literal); n = UInt(Rn); m = UInt(Rm); add = TRUE; (shift_t, shift_n) = (SRType_LSL, UInt(imm2)); if BadReg(m) then UNPREDICTABLE; + +pli_immediate_literal: +Encoding T1 ARMv7 +fmt PLI<c> [<Rn>,#<imm12>] +extract32 11111,00,1,1,00,1,Rn.4,1111,imm12.12 +pcode n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); add = TRUE; +Encoding T2 ARMv7 +fmt PLI<c> [<Rn>,#-<imm8>] +extract32 11111,00,1,0,00,1,Rn.4,1111,1,100,imm8.8 +pcode n = UInt(Rn); imm32 = ZeroExtend(imm8, 32); add = FALSE; +Encoding T3 ARMv7 +fmt PLI<c> <label> +extract32 11111,00,1,U.1,00,1,1111,1111,imm12.12 +pcode n = 15; imm32 = ZeroExtend(imm12, 32); add = (U == '1'); + +pli_register: +Encoding T1 ARMv7 +fmt PLI<c> [<Rn>,<Rm>{,<shift>}] +extract32 11111,00,1,0,00,1,Rn.4,1111,0,00000,imm2.2,Rm.4 +pcode if Rn == '1111' then SEE PLI (immediate, literal); n = UInt(Rn); m = UInt(Rm); add = TRUE; (shift_t, shift_n) = (SRType_LSL, UInt(imm2)); if BadReg(m) then UNPREDICTABLE; + +//----------------------------------------------------------------------------- + +ldrh_literal: +Encoding T1 ARMv6T2, ARMv7 +fmt LDRH<c> <Rt>,<label> +extract32 11111,00,0,U.1,01,1,1111,Rt.4,imm12.12 +pcode if Rt == '1111' then SEE "nop"; t = UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1'); if t == 13 then UNPREDICTABLE; + +ldrht: +Encoding T1 ARMv6T2, ARMv7 +fmt LDRHT<c> <Rt>,[<Rn>{,#<+/-><imm32>}] +extract32 11111,00,0,0,01,1,Rn.4,Rt.4,1,110,imm8.8 +pcode if Rn == '1111' then SEE LDRH (literal); t = UInt(Rt); n = UInt(Rn); postindex = FALSE; add = TRUE; register_form = FALSE; imm32 = ZeroExtend(imm8, 32); if BadReg(t) then UNPREDICTABLE; + +ldrsh_literal: +Encoding T1 ARMv6T2, ARMv7 +fmt LDRSH<c> <Rt>,<label> +extract32 11111,00,1,U.1,01,1,1111,Rt.4,imm12.12 +pcode if Rt == '1111' then SEE "nop"; t = UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1'); if t == 13 then UNPREDICTABLE; + +ldrsh_immediate: +Encoding T1 ARMv6T2, ARMv7 +fmt LDRSH<c> <Rt>,[<Rn>,#<+/-><imm32>] +extract32 11111,00,1,1,01,1,Rn.4,Rt.4,imm12.12 +pcode if Rn == '1111' then SEE LDRSH (literal); if Rt == '1111' then SEE "nop"; t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); index = TRUE; add = TRUE; wback = FALSE; if t == 13 then UNPREDICTABLE; +Encoding T2 ARMv6T2, ARMv7 +fmt LDRSH<c> <Rt>,[<Rn>,#<+/-><imm32>] +fmt LDRSH<c> <Rt>,[<Rn>,#<+/-><imm32>]! +fmt LDRSH<c> <Rt>,[<Rn>],#<+/-><imm32> +extract32 11111,00,1,0,01,1,Rn.4,Rt.4,1,P.1,U.1,W.1,imm8.8 +pcode if Rn == '1111' then SEE LDRSH (literal); if Rt == '1111' && P == '1' && U == '0' && W == '0' then SEE "nop"; if P == '1' && U == '1' && W == '0' then SEE LDRSHT; if P == '0' && W == '0' then UNDEFINED; t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32); index = (P == '1'); add = (U == '1'); wback = (W == '1'); if BadReg(t) || (wback && n == t) then UNPREDICTABLE; + +ldrsht: +Encoding T1 ARMv6T2, ARMv7 +fmt LDRSHT<c> <Rt>,[<Rn>{,#<+/-><imm32>}] +extract32 11111,00,1,0,01,1,Rn.4,Rt.4,1,110,imm8.8 +pcode if Rn == '1111' then SEE LDRSH (literal); t = UInt(Rt); n = UInt(Rn); postindex = FALSE; add = TRUE; register_form = FALSE; imm32 = ZeroExtend(imm8, 32); if BadReg(t) then UNPREDICTABLE; + +//----------------------------------------------------------------------------- + +ldrt: +Encoding T1 ARMv6T2, ARMv7 +fmt LDRT<c> <Rt>,[<Rn>{,#<+/-><imm32>}] +extract32 11111,00,0,0,10,1,Rn.4,Rt.4,1,110,imm8.8 +pcode if Rn == '1111' then SEE LDR (literal); t = UInt(Rt); n = UInt(Rn); postindex = FALSE; add = TRUE; register_form = FALSE; imm32 = ZeroExtend(imm8, 32); if BadReg(t) then UNPREDICTABLE; + +ldr_literal: +Encoding T1 ARMv4T, ARMv5T*, ARMv6*, ARMv7 +fmt LDR<c> <Rt>,<label> +extract16 01001,Rt.3,imm8.8 +pcode t = UInt(Rt); imm32 = ZeroExtend(imm8:'00', 32); add = TRUE; +Encoding T2 ARMv6T2, ARMv7 +fmt LDR<c> <Rt>,<label> +extract32 11111,00,0,U.1,10,1,1111,Rt.4,imm12.12 +pcode t = UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1'); if t == 15 && InITBlock() && !LastInITBlock() then UNPREDICTABLE; + +//----------------------------------------------------------------------------- + +sxtah: +Encoding T1 ARMv6T2, ARMv7 +fmt SXTAH<c> <Rd>,<Rn>,<Rm>{,<rotation>} +extract32 11111,010,0,000,Rn.4,1111,Rd.4,1,(0),rotate.2,Rm.4 +pcode if Rn == '1111' then SEE SXTH; d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); rotation = UInt(rotate:'000'); if BadReg(d) || n == 13 || BadReg(m) then UNPREDICTABLE; + +uxtah: +Encoding T1 ARMv6T2, ARMv7 +fmt UXTAH<c> <Rd>,<Rn>,<Rm>{,<rotation>} +extract32 11111,010,0,001,Rn.4,1111,Rd.4,1,(0),rotate.2,Rm.4 +pcode if Rn == '1111' then SEE UXTH; d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); rotation = UInt(rotate:'000'); if BadReg(d) || n == 13 || BadReg(m) then UNPREDICTABLE; + +sxtab16: +Encoding T1 ARMv6T2, ARMv7 +fmt SXTAB16<c> <Rd>,<Rn>,<Rm>{,<rotation>} +extract32 11111,010,0,010,Rn.4,1111,Rd.4,1,(0),rotate.2,Rm.4 +pcode if Rn == '1111' then SEE SXTB16; d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); rotation = UInt(rotate:'000'); if BadReg(d) || n == 13 || BadReg(m) then UNPREDICTABLE; + +sxtb16: +Encoding T1 ARMv6T2, ARMv7 +fmt SXTB16<c> <Rd>,<Rm>{,<rotation>} +extract32 11111,010,0,010,1111,1111,Rd.4,1,(0),rotate.2,Rm.4 +pcode d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000'); if BadReg(d) || BadReg(m) then UNPREDICTABLE; + +uxtab16: +Encoding T1 ARMv6T2, ARMv7 +fmt UXTAB16<c> <Rd>,<Rn>,<Rm>{,<rotation>} +extract32 11111,010,0,011,Rn.4,1111,Rd.4,1,(0),rotate.2,Rm.4 +pcode if Rn == '1111' then SEE UXTB16; d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); rotation = UInt(rotate:'000'); if BadReg(d) || n == 13 || BadReg(m) then UNPREDICTABLE; + +uxtb16: +Encoding T1 ARMv6T2, ARMv7 +fmt UXTB16<c> <Rd>,<Rm>{,<rotation>} +extract32 11111,010,0,011,1111,1111,Rd.4,1,(0),rotate.2,Rm.4 +pcode d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000'); if BadReg(d) || BadReg(m) then UNPREDICTABLE; + +sxtab: +Encoding T1 ARMv6T2, ARMv7 +fmt SXTAB<c> <Rd>,<Rn>,<Rm>{,<rotation>} +extract32 11111,010,0,100,Rn.4,1111,Rd.4,1,(0),rotate.2,Rm.4 +pcode_start +if Rn == '1111' then SEE SXTB; +d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); +rotation = UInt(rotate:'000'); +if BadReg(d) || n == 13 || BadReg(m) then UNPREDICTABLE; +pcode_end + +uxtab: +Encoding T1 ARMv6T2, ARMv7 +fmt UXTAB<c> <Rd>,<Rn>,<Rm>{,<rotation>} +extract32 11111,010,0,101,Rn.4,1111,Rd.4,1,(0),rotate.2,Rm.4 +pcode if Rn == '1111' then SEE UXTB; d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); rotation = UInt(rotate:'000'); if BadReg(d) || n == 13 || BadReg(m) then UNPREDICTABLE; + +//----------------------------------------------------------------------------- + +sadd16: +Encoding T1 ARMv6T2, ARMv7 +fmt SADD16<c> <Rd>,<Rn>,<Rm> +extract32 11111,010,1,001,Rn.4,1111,Rd.4,0,000,Rm.4 +pcode d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); if BadReg(d) || BadReg(n) || BadReg(m) then UNPREDICTABLE; + +sasx: +Encoding T1 ARMv6T2, ARMv7 +fmt SASX<c> <Rd>,<Rn>,<Rm> +extract32 11111,010,1,010,Rn.4,1111,Rd.4,0,000,Rm.4 +pcode d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); if BadReg(d) || BadReg(n) || BadReg(m) then UNPREDICTABLE; + +ssax: +Encoding T1 ARMv6T2, ARMv7 +fmt SSAX<c> <Rd>,<Rn>,<Rm> +extract32 11111,010,1,110,Rn.4,1111,Rd.4,0,000,Rm.4 +pcode d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); if BadReg(d) || BadReg(n) || BadReg(m) then UNPREDICTABLE; + +ssub16: +Encoding T1 ARMv6T2, ARMv7 +fmt SSUB16<c> <Rd>,<Rn>,<Rm> +extract32 11111,010,1,101,Rn.4,1111,Rd.4,0,000,Rm.4 +pcode d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); if BadReg(d) || BadReg(n) || BadReg(m) then UNPREDICTABLE; + +sadd8: +Encoding T1 ARMv6T2, ARMv7 +fmt SADD8<c> <Rd>,<Rn>,<Rm> +extract32 11111,010,1,000,Rn.4,1111,Rd.4,0,000,Rm.4 +pcode d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); if BadReg(d) || BadReg(n) || BadReg(m) then UNPREDICTABLE; + +ssub8: +Encoding T1 ARMv6T2, ARMv7 +fmt SSUB8<c> <Rd>,<Rn>,<Rm> +extract32 11111,010,1,100,Rn.4,1111,Rd.4,0,000,Rm.4 +pcode d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); if BadReg(d) || BadReg(n) || BadReg(m) then UNPREDICTABLE; + +qadd16: +Encoding T1 ARMv6T2, ARMv7 +fmt QADD16<c> <Rd>,<Rn>,<Rm> +extract32 11111,010,1,001,Rn.4,1111,Rd.4,0,001,Rm.4 +pcode d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); if BadReg(d) || BadReg(n) || BadReg(m) then UNPREDICTABLE; + +qasx: +Encoding T1 ARMv6T2, ARMv7 +fmt QASX<c> <Rd>,<Rn>,<Rm> +extract32 11111,010,1,010,Rn.4,1111,Rd.4,0,001,Rm.4 +pcode d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); if BadReg(d) || BadReg(n) || BadReg(m) then UNPREDICTABLE; + +qsax: +Encoding T1 ARMv6T2, ARMv7 +fmt QSAX<c> <Rd>,<Rn>,<Rm> +extract32 11111,010,1,110,Rn.4,1111,Rd.4,0,001,Rm.4 +pcode d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); if BadReg(d) || BadReg(n) || BadReg(m) then UNPREDICTABLE; + +qsub16: +Encoding T1 ARMv6T2, ARMv7 +fmt QSUB16<c> <Rd>,<Rn>,<Rm> +extract32 11111,010,1,101,Rn.4,1111,Rd.4,0,001,Rm.4 +pcode d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); if BadReg(d) || BadReg(n) || BadReg(m) then UNPREDICTABLE; + +qadd8: +Encoding T1 ARMv6T2, ARMv7 +fmt QADD8<c> <Rd>,<Rn>,<Rm> +extract32 11111,010,1,000,Rn.4,1111,Rd.4,0,001,Rm.4 +pcode d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); if BadReg(d) || BadReg(n) || BadReg(m) then UNPREDICTABLE; + +qsub8: +Encoding T1 ARMv6T2, ARMv7 +fmt QSUB8<c> <Rd>,<Rn>,<Rm> +extract32 11111,010,1,100,Rn.4,1111,Rd.4,0,001,Rm.4 +pcode d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); if BadReg(d) || BadReg(n) || BadReg(m) then UNPREDICTABLE; + +shadd16: +Encoding T1 ARMv6T2, ARMv7 +fmt SHADD16<c> <Rd>,<Rn>,<Rm> +extract32 11111,010,1,001,Rn.4,1111,Rd.4,0,010,Rm.4 +pcode d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); if BadReg(d) || BadReg(n) || BadReg(m) then UNPREDICTABLE; + +shasx: +Encoding T1 ARMv6T2, ARMv7 +fmt SHASX<c> <Rd>,<Rn>,<Rm> +extract32 11111,010,1,010,Rn.4,1111,Rd.4,0,010,Rm.4 +pcode d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); if BadReg(d) || BadReg(n) || BadReg(m) then UNPREDICTABLE; + +shsax: +Encoding T1 ARMv6T2, ARMv7 +fmt SHSAX<c> <Rd>,<Rn>,<Rm> +extract32 11111,010,1,110,Rn.4,1111,Rd.4,0,010,Rm.4 +pcode d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); if BadReg(d) || BadReg(n) || BadReg(m) then UNPREDICTABLE; + +shsub16: +Encoding T1 ARMv6T2, ARMv7 +fmt SHSUB16<c> <Rd>,<Rn>,<Rm> +extract32 11111,010,1,101,Rn.4,1111,Rd.4,0,010,Rm.4 +pcode d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); if BadReg(d) || BadReg(n) || BadReg(m) then UNPREDICTABLE; + +shadd8: +Encoding T1 ARMv6T2, ARMv7 +fmt SHADD8<c> <Rd>,<Rn>,<Rm> +extract32 11111,010,1,000,Rn.4,1111,Rd.4,0,010,Rm.4 +pcode d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); if BadReg(d) || BadReg(n) || BadReg(m) then UNPREDICTABLE; + +shsub8: +Encoding T1 ARMv6T2, ARMv7 +fmt SHSUB8<c> <Rd>,<Rn>,<Rm> +extract32 11111,010,1,100,Rn.4,1111,Rd.4,0,010,Rm.4 +pcode d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); if BadReg(d) || BadReg(n) || BadReg(m) then UNPREDICTABLE; + +//----------------------------------------------------------------------------- + +uadd16: +Encoding T1 ARMv6T2, ARMv7 +fmt UADD16<c> <Rd>,<Rn>,<Rm> +extract32 11111,010,1,001,Rn.4,1111,Rd.4,0,100,Rm.4 +pcode d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); if BadReg(d) || BadReg(n) || BadReg(m) then UNPREDICTABLE; + +uasx: +Encoding T1 ARMv6T2, ARMv7 +fmt UASX<c> <Rd>,<Rn>,<Rm> +extract32 11111,010,1,010,Rn.4,1111,Rd.4,0,100,Rm.4 +pcode d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); if BadReg(d) || BadReg(n) || BadReg(m) then UNPREDICTABLE; + +usax: +Encoding T1 ARMv6T2, ARMv7 +fmt USAX<c> <Rd>,<Rn>,<Rm> +extract32 11111,010,1,110,Rn.4,1111,Rd.4,0,100,Rm.4 +pcode d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); if BadReg(d) || BadReg(n) || BadReg(m) then UNPREDICTABLE; + +usub16: +Encoding T1 ARMv6T2, ARMv7 +fmt USUB16<c> <Rd>,<Rn>,<Rm> +extract32 11111,010,1,101,Rn.4,1111,Rd.4,0,100,Rm.4 +pcode d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); if BadReg(d) || BadReg(n) || BadReg(m) then UNPREDICTABLE; + +uadd8: +Encoding T1 ARMv6T2, ARMv7 +fmt UADD8<c> <Rd>,<Rn>,<Rm> +extract32 11111,010,1,000,Rn.4,1111,Rd.4,0,100,Rm.4 +pcode d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); if BadReg(d) || BadReg(n) || BadReg(m) then UNPREDICTABLE; + +usub8: +Encoding T1 ARMv6T2, ARMv7 +fmt USUB8<c> <Rd>,<Rn>,<Rm> +extract32 11111,010,1,100,Rn.4,1111,Rd.4,0,100,Rm.4 +pcode d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); if BadReg(d) || BadReg(n) || BadReg(m) then UNPREDICTABLE; + +uqadd16: +Encoding T1 ARMv6T2, ARMv7 +fmt UQADD16<c> <Rd>,<Rn>,<Rm> +extract32 11111,010,1,001,Rn.4,1111,Rd.4,0,101,Rm.4 +pcode d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); if BadReg(d) || BadReg(n) || BadReg(m) then UNPREDICTABLE; + +uqasx: +Encoding T1 ARMv6T2, ARMv7 +fmt UQASX<c> <Rd>,<Rn>,<Rm> +extract32 11111,010,1,010,Rn.4,1111,Rd.4,0,101,Rm.4 +pcode d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); if BadReg(d) || BadReg(n) || BadReg(m) then UNPREDICTABLE; + +uqsax: +Encoding T1 ARMv6T2, ARMv7 +fmt UQSAX<c> <Rd>,<Rn>,<Rm> +extract32 11111,010,1,110,Rn.4,1111,Rd.4,0,101,Rm.4 +pcode d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); if BadReg(d) || BadReg(n) || BadReg(m) then UNPREDICTABLE; + +uqsub16: +Encoding T1 ARMv6T2, ARMv7 +fmt UQSUB16<c> <Rd>,<Rn>,<Rm> +extract32 11111,010,1,101,Rn.4,1111,Rd.4,0,101,Rm.4 +pcode d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); if BadReg(d) || BadReg(n) || BadReg(m) then UNPREDICTABLE; + +uqadd8: +Encoding T1 ARMv6T2, ARMv7 +fmt UQADD8<c> <Rd>,<Rn>,<Rm> +extract32 11111,010,1,000,Rn.4,1111,Rd.4,0,101,Rm.4 +pcode d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); if BadReg(d) || BadReg(n) || BadReg(m) then UNPREDICTABLE; + +uqsub8: +Encoding T1 ARMv6T2, ARMv7 +fmt UQSUB8<c> <Rd>,<Rn>,<Rm> +extract32 11111,010,1,100,Rn.4,1111,Rd.4,0,101,Rm.4 +pcode d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); if BadReg(d) || BadReg(n) || BadReg(m) then UNPREDICTABLE; + +uhadd16: +Encoding T1 ARMv6T2, ARMv7 +fmt UHADD16<c> <Rd>,<Rn>,<Rm> +extract32 11111,010,1,001,Rn.4,1111,Rd.4,0,110,Rm.4 +pcode d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); if BadReg(d) || BadReg(n) || BadReg(m) then UNPREDICTABLE; + +uhasx: +Encoding T1 ARMv6T2, ARMv7 +fmt UHASX<c> <Rd>,<Rn>,<Rm> +extract32 11111,010,1,010,Rn.4,1111,Rd.4,0,110,Rm.4 +pcode d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); if BadReg(d) || BadReg(n) || BadReg(m) then UNPREDICTABLE; + +uhsax: +Encoding T1 ARMv6T2, ARMv7 +fmt UHSAX<c> <Rd>,<Rn>,<Rm> +extract32 11111,010,1,110,Rn.4,1111,Rd.4,0,110,Rm.4 +pcode d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); if BadReg(d) || BadReg(n) || BadReg(m) then UNPREDICTABLE; + +uhsub16: +Encoding T1 ARMv6T2, ARMv7 +fmt UHSUB16<c> <Rd>,<Rn>,<Rm> +extract32 11111,010,1,101,Rn.4,1111,Rd.4,0,110,Rm.4 +pcode d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); if BadReg(d) || BadReg(n) || BadReg(m) then UNPREDICTABLE; + +uhadd8: +Encoding T1 ARMv6T2, ARMv7 +fmt UHADD8<c> <Rd>,<Rn>,<Rm> +extract32 11111,010,1,000,Rn.4,1111,Rd.4,0,110,Rm.4 +pcode d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); if BadReg(d) || BadReg(n) || BadReg(m) then UNPREDICTABLE; + +uhsub8: +Encoding T1 ARMv6T2, ARMv7 +fmt UHSUB8<c> <Rd>,<Rn>,<Rm> +extract32 11111,010,1,100,Rn.4,1111,Rd.4,0,110,Rm.4 +pcode d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); if BadReg(d) || BadReg(n) || BadReg(m) then UNPREDICTABLE; + +//----------------------------------------------------------------------------- + +mla: +Encoding T1 ARMv6T2, ARMv7 +fmt MLA<c> <Rd>,<Rn>,<Rm>,<Ra> +extract32 11111,0110,000,Rn.4,Ra.4,Rd.4,0000,Rm.4 +pcode if Ra == '1111' then SEE MUL; d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); a= UInt(Ra); setflags = FALSE; if BadReg(d) || BadReg(n) || BadReg(m) || a == 13 then UNPREDICTABLE; + +mul: +Encoding T1 ARMv4T, ARMv5T*, ARMv6*, ARMv7 +fmt MULS <Rdm>,<Rn>,<Rdm> +extract16 010000,1101,Rn.3,Rdm.3 +pcode d = UInt(Rdm); n = UInt(Rn); m = UInt(Rdm); setflags = !InITBlock(); if ArchVersion() < 6 && d == n then UNPREDICTABLE; +Encoding T2 ARMv6T2, ARMv7 +fmt MUL<c> <Rd>,<Rn>,<Rm> +extract32 11111,0110,000,Rn.4,1111,Rd.4,0000,Rm.4 +pcode d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = FALSE; if BadReg(d) || BadReg(n) || BadReg(m) then UNPREDICTABLE; + +mls: +Encoding T1 ARMv6T2, ARMv7 +fmt MLS<c> <Rd>,<Rn>,<Rm>,<Ra> +extract32 11111,0110,000,Rn.4,Ra.4,Rd.4,0001,Rm.4 +pcode d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); a = UInt(Ra); +pcode if BadReg(d) || BadReg(n) || BadReg(m) || BadReg(a) then UNPREDICTABLE; + +smlabb_smlabt_smlatb_smlatt: +Encoding T1 ARMv6T2, ARMv7 +fmt SMLABB<c> <Rd>,<Rn>,<Rm>,<Ra> +extract32 11111,0110,001,Rn.4,Ra.4,Rd.4,00,0,0,Rm.4 +pcode if Ra == '1111' then SEE SMULBB, SMULBT, SMULTB, SMULTT; d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); a = UInt(Ra); if BadReg(d) || BadReg(n) || BadReg(m) || a == 13 then UNPREDICTABLE; +Encoding T1 ARMv6T2, ARMv7 +fmt SMLABT<c> <Rd>,<Rn>,<Rm>,<Ra> +extract32 11111,0110,001,Rn.4,Ra.4,Rd.4,00,0,1,Rm.4 +pcode if Ra == '1111' then SEE SMULBB, SMULBT, SMULTB, SMULTT; d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); a = UInt(Ra); if BadReg(d) || BadReg(n) || BadReg(m) || a == 13 then UNPREDICTABLE; +Encoding T1 ARMv6T2, ARMv7 +fmt SMLATB<c> <Rd>,<Rn>,<Rm>,<Ra> +extract32 11111,0110,001,Rn.4,Ra.4,Rd.4,00,1,0,Rm.4 +pcode if Ra == '1111' then SEE SMULBB, SMULBT, SMULTB, SMULTT; d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); a = UInt(Ra); if BadReg(d) || BadReg(n) || BadReg(m) || a == 13 then UNPREDICTABLE; +Encoding T1 ARMv6T2, ARMv7 +fmt SMLATT<c> <Rd>,<Rn>,<Rm>,<Ra> +extract32 11111,0110,001,Rn.4,Ra.4,Rd.4,00,1,1,Rm.4 +pcode if Ra == '1111' then SEE SMULBB, SMULBT, SMULTB, SMULTT; d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); a = UInt(Ra); if BadReg(d) || BadReg(n) || BadReg(m) || a == 13 then UNPREDICTABLE; + +smulbb_smulbt_smultb_smultt: +Encoding T1 ARMv6T2, ARMv7 +fmt SMULBB<c> <Rd>,<Rn>,<Rm> +extract32 11111,0110,001,Rn.4,1111,Rd.4,00,00,Rm.4 +pcode d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); if BadReg(d) || BadReg(n) || BadReg(m) then UNPREDICTABLE; +Encoding T1 ARMv6T2, ARMv7 +fmt SMULBT<c> <Rd>,<Rn>,<Rm> +extract32 11111,0110,001,Rn.4,1111,Rd.4,00,01,Rm.4 +pcode d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); if BadReg(d) || BadReg(n) || BadReg(m) then UNPREDICTABLE; +Encoding T1 ARMv6T2, ARMv7 +fmt SMULTB<c> <Rd>,<Rn>,<Rm> +extract32 11111,0110,001,Rn.4,1111,Rd.4,00,10,Rm.4 +pcode d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); if BadReg(d) || BadReg(n) || BadReg(m) then UNPREDICTABLE; +Encoding T1 ARMv6T2, ARMv7 +fmt SMULTT<c> <Rd>,<Rn>,<Rm> +extract32 11111,0110,001,Rn.4,1111,Rd.4,00,11,Rm.4 +pcode d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); if BadReg(d) || BadReg(n) || BadReg(m) then UNPREDICTABLE; + +smlad: +Encoding T1 ARMv6T2, ARMv7 +fmt SMLAD<c> <Rd>,<Rn>,<Rm>,<Ra> +extract32 11111,0110,010,Rn.4,Ra.4,Rd.4,000,0,Rm.4 +pcode M=0; if Ra == '1111' then SEE SMUAD; d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); a = UInt(Ra); m_swap = (M == '1'); if BadReg(d) || BadReg(n) || BadReg(m) || a == 13 then UNPREDICTABLE; +Encoding T1 ARMv6T2, ARMv7 +fmt SMLADX<c> <Rd>,<Rn>,<Rm>,<Ra> +extract32 11111,0110,010,Rn.4,Ra.4,Rd.4,000,1,Rm.4 +pcode M=1; if Ra == '1111' then SEE SMUAD; d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); a = UInt(Ra); m_swap = (M == '1'); if BadReg(d) || BadReg(n) || BadReg(m) || a == 13 then UNPREDICTABLE; + +smuad: +Encoding T1 ARMv6T2, ARMv7 +fmt SMUAD<c> <Rd>,<Rn>,<Rm> +extract32 11111,0110,010,Rn.4,1111,Rd.4,000,0,Rm.4 +pcode M=0; d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); m_swap = (M == '1'); if BadReg(d) || BadReg(n) || BadReg(m) then UNPREDICTABLE; +Encoding T1 ARMv6T2, ARMv7 +fmt SMUADX<c> <Rd>,<Rn>,<Rm> +extract32 11111,0110,010,Rn.4,1111,Rd.4,000,1,Rm.4 +pcode M=1; d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); m_swap = (M == '1'); if BadReg(d) || BadReg(n) || BadReg(m) then UNPREDICTABLE; + +smlawb_smlawt: +Encoding T1 ARMv6T2, ARMv7 +fmt SMLAWB<c> <Rd>,<Rn>,<Rm>,<Ra> +extract32 11111,0110,011,Rn.4,Ra.4,Rd.4,000,0,Rm.4 +pcode M=0; if Ra == '1111' then SEE SMULWB, SMULWT; d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); a = UInt(Ra); m_high = (M == '1'); if BadReg(d) || BadReg(n) || BadReg(m) || a == 13 then UNPREDICTABLE; +Encoding T1 ARMv6T2, ARMv7 +fmt SMLAWT<c> <Rd>,<Rn>,<Rm>,<Ra> +extract32 11111,0110,011,Rn.4,Ra.4,Rd.4,000,1,Rm.4 +pcode M=1; if Ra == '1111' then SEE SMULWB, SMULWT; d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); a = UInt(Ra); m_high = (M == '1'); if BadReg(d) || BadReg(n) || BadReg(m) || a == 13 then UNPREDICTABLE; + +smulwb_smulwt: +Encoding T1 ARMv6T2, ARMv7 +fmt SMULWB<c> <Rd>,<Rn>,<Rm> +extract32 11111,0110,011,Rn.4,1111,Rd.4,000,0,Rm.4 +pcode M=0; d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); m_high = (M == '1'); if BadReg(d) || BadReg(n) || BadReg(m) then UNPREDICTABLE; +Encoding T1 ARMv6T2, ARMv7 +fmt SMULWT<c> <Rd>,<Rn>,<Rm> +extract32 11111,0110,011,Rn.4,1111,Rd.4,000,1,Rm.4 +pcode M=1; d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); m_high = (M == '1'); if BadReg(d) || BadReg(n) || BadReg(m) then UNPREDICTABLE; + +smlsd: +Encoding T1 ARMv6T2, ARMv7 +fmt SMLSD<c> <Rd>,<Rn>,<Rm>,<Ra> +extract32 11111,0110,100,Rn.4,Ra.4,Rd.4,000,0,Rm.4 +pcode M=0; if Ra == '1111' then SEE SMUSD; d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); a = UInt(Ra); m_swap = (M == '1'); if BadReg(d) || BadReg(n) || BadReg(m) || a == 13 then UNPREDICTABLE; +Encoding T1 ARMv6T2, ARMv7 +fmt SMLSDX<c> <Rd>,<Rn>,<Rm>,<Ra> +extract32 11111,0110,100,Rn.4,Ra.4,Rd.4,000,1,Rm.4 +pcode M=1; if Ra == '1111' then SEE SMUSD; d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); a = UInt(Ra); m_swap = (M == '1'); if BadReg(d) || BadReg(n) || BadReg(m) || a == 13 then UNPREDICTABLE; + +smusd: +Encoding T1 ARMv6T2, ARMv7 +fmt SMUSD<c> <Rd>,<Rn>,<Rm> +extract32 11111,0110,100,Rn.4,1111,Rd.4,000,0,Rm.4 +pcode M=0; d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); m_swap = (M == '1'); if BadReg(d) || BadReg(n) || BadReg(m) then UNPREDICTABLE; +Encoding T1 ARMv6T2, ARMv7 +fmt SMUSDX<c> <Rd>,<Rn>,<Rm> +extract32 11111,0110,100,Rn.4,1111,Rd.4,000,1,Rm.4 +pcode M=1; d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); m_swap = (M == '1'); if BadReg(d) || BadReg(n) || BadReg(m) then UNPREDICTABLE; + +smmla: +Encoding T1 ARMv6T2, ARMv7 +fmt SMMLA<c> <Rd>,<Rn>,<Rm>,<Ra> +extract32 11111,0110,101,Rn.4,Ra.4,Rd.4,000,0,Rm.4 +pcode R=0; if Ra == '1111' then SEE SMMUL; d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); a = UInt(Ra); round = (R == '1'); if BadReg(d) || BadReg(n) || BadReg(m) || a == 13 then UNPREDICTABLE; +Encoding T1 ARMv6T2, ARMv7 +fmt SMMLAR<c> <Rd>,<Rn>,<Rm>,<Ra> +extract32 11111,0110,101,Rn.4,Ra.4,Rd.4,000,1,Rm.4 +pcode R=1; if Ra == '1111' then SEE SMMUL; d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); a = UInt(Ra); round = (R == '1'); if BadReg(d) || BadReg(n) || BadReg(m) || a == 13 then UNPREDICTABLE; + +smmul: +Encoding T1 ARMv6T2, ARMv7 +fmt SMMUL<c> <Rd>,<Rn>,<Rm> +extract32 11111,0110,101,Rn.4,1111,Rd.4,000,0,Rm.4 +pcode R=0; d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); round = (R == '1'); if BadReg(d) || BadReg(n) || BadReg(m) then UNPREDICTABLE; +Encoding T1 ARMv6T2, ARMv7 +fmt SMMULR<c> <Rd>,<Rn>,<Rm> +extract32 11111,0110,101,Rn.4,1111,Rd.4,000,1,Rm.4 +pcode R=1; d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); round = (R == '1'); if BadReg(d) || BadReg(n) || BadReg(m) then UNPREDICTABLE; + +smmls: +Encoding T1 ARMv6T2, ARMv7 +fmt SMMLS<c> <Rd>,<Rn>,<Rm>,<Ra> +extract32 11111,0110,110,Rn.4,Ra.4,Rd.4,000,0,Rm.4 +pcode R=0; d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); a = UInt(Ra); round = (R == '1'); if BadReg(d) || BadReg(n) || BadReg(m) || BadReg(a) then UNPREDICTABLE; +Encoding T1 ARMv6T2, ARMv7 +fmt SMMLSR<c> <Rd>,<Rn>,<Rm>,<Ra> +extract32 11111,0110,110,Rn.4,Ra.4,Rd.4,000,1,Rm.4 +pcode R=1; d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); a = UInt(Ra); round = (R == '1'); if BadReg(d) || BadReg(n) || BadReg(m) || BadReg(a) then UNPREDICTABLE; + +usad8: +Encoding T1 ARMv6T2, ARMv7 +fmt USAD8<c> <Rd>,<Rn>,<Rm> +extract32 11111,0110,111,Rn.4,1111,Rd.4,0000,Rm.4 +pcode d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); +pcode if BadReg(d) || BadReg(n) || BadReg(m) then UNPREDICTABLE; + +usada8: +Encoding T1 ARMv6T2, ARMv7 +fmt USADA8<c> <Rd>,<Rn>,<Rm>,<Ra> +extract32 11111,0110,111,Rn.4,Ra.4,Rd.4,0000,Rm.4 +pcode if Ra == '1111' then SEE USAD8; d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); a = UInt(Ra); if BadReg(d) || BadReg(n) || BadReg(m) || BadReg(a) then UNPREDICTABLE; + + +//----------------------------------------------------------------------------- + +smull: +Encoding T1 ARMv6T2, ARMv7 +fmt SMULL<c> <RdLo>,<RdHi>,<Rn>,<Rm> +extract32 11111,0111,0,00,Rn.4,RdLo.4,RdHi.4,0000,Rm.4 +pcode dLo = UInt(RdLo); dHi = UInt(RdHi); n = UInt(Rn); m = UInt(Rm); setflags = FALSE; if BadReg(dLo) || BadReg(dHi) || BadReg(n) || BadReg(m) then UNPREDICTABLE; if dHi == dLo then UNPREDICTABLE; + +sdiv: +Encoding T1 ARMv7_R +fmt SDIV<c> <Rd>,<Rn>,<Rm> +extract32 11111,011100,1,Rn.4,(1)(1)(1)(1),Rd.4,1111,Rm.4 +pcode d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); if BadReg(d) || BadReg(n) || BadReg(m) then UNPREDICTABLE; + +umull: +Encoding T1 ARMv6T2, ARMv7 +fmt UMULL<c> <RdLo>,<RdHi>,<Rn>,<Rm> +extract32 11111,0111,010,Rn.4,RdLo.4,RdHi.4,0000,Rm.4 +pcode dLo = UInt(RdLo); dHi = UInt(RdHi); n = UInt(Rn); m = UInt(Rm); setflags = FALSE; if BadReg(dLo) || BadReg(dHi) || BadReg(n) || BadReg(m) then UNPREDICTABLE; if dHi == dLo then UNPREDICTABLE; + +udiv: +Encoding T1 ARMv7_R +fmt UDIV<c> <Rd>,<Rn>,<Rm> +extract32 11111,011101,1,Rn.4,(1)(1)(1)(1),Rd.4,1111,Rm.4 +pcode d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); if BadReg(d) || BadReg(n) || BadReg(m) then UNPREDICTABLE; + +smlal: +Encoding T1 ARMv6T2, ARMv7 +fmt SMLAL<c> <RdLo>,<RdHi>,<Rn>,<Rm> +extract32 11111,0111,1,00,Rn.4,RdLo.4,RdHi.4,0000,Rm.4 +pcode dLo = UInt(RdLo); dHi = UInt(RdHi); n = UInt(Rn); m = UInt(Rm); setflags = FALSE; if BadReg(dLo) || BadReg(dHi) || BadReg(n) || BadReg(m) then UNPREDICTABLE; if dHi == dLo then UNPREDICTABLE; + +// expanded to four cases to avoid fields on the mnemonic +smlalbb_smlalbt_smlaltb_smlaltt: +Encoding T1 ARMv6T2, ARMv7 +fmt SMLALBB<c> <RdLo>,<RdHi>,<Rn>,<Rm> +extract32 11111,0111,100,Rn.4,RdLo.4,RdHi.4,10,00,Rm.4 +pcode N=0; M=0; dLo = UInt(RdLo); dHi = UInt(RdHi); n = UInt(Rn); m = UInt(Rm); n_high = (N == '1'); m_high = (M == '1'); if BadReg(dLo) || BadReg(dHi) || BadReg(n) || BadReg(m) then UNPREDICTABLE; if dHi == dLo then UNPREDICTABLE; +Encoding T1 ARMv6T2, ARMv7 +fmt SMLALBT<c> <RdLo>,<RdHi>,<Rn>,<Rm> +extract32 11111,0111,100,Rn.4,RdLo.4,RdHi.4,10,01,Rm.4 +pcode N=0; M=1; dLo = UInt(RdLo); dHi = UInt(RdHi); n = UInt(Rn); m = UInt(Rm); n_high = (N == '1'); m_high = (M == '1'); if BadReg(dLo) || BadReg(dHi) || BadReg(n) || BadReg(m) then UNPREDICTABLE; if dHi == dLo then UNPREDICTABLE; +Encoding T1 ARMv6T2, ARMv7 +fmt SMLALTB<c> <RdLo>,<RdHi>,<Rn>,<Rm> +extract32 11111,0111,100,Rn.4,RdLo.4,RdHi.4,10,10,Rm.4 +pcode N=1; M=0; dLo = UInt(RdLo); dHi = UInt(RdHi); n = UInt(Rn); m = UInt(Rm); n_high = (N == '1'); m_high = (M == '1'); if BadReg(dLo) || BadReg(dHi) || BadReg(n) || BadReg(m) then UNPREDICTABLE; if dHi == dLo then UNPREDICTABLE; +Encoding T1 ARMv6T2, ARMv7 +fmt SMLALTT<c> <RdLo>,<RdHi>,<Rn>,<Rm> +extract32 11111,0111,100,Rn.4,RdLo.4,RdHi.4,10,11,Rm.4 +pcode N=1; M=1; dLo = UInt(RdLo); dHi = UInt(RdHi); n = UInt(Rn); m = UInt(Rm); n_high = (N == '1'); m_high = (M == '1'); if BadReg(dLo) || BadReg(dHi) || BadReg(n) || BadReg(m) then UNPREDICTABLE; if dHi == dLo then UNPREDICTABLE; + +smlald: +Encoding T1 ARMv6T2, ARMv7 +fmt SMLALD<c> <RdLo>,<RdHi>,<Rn>,<Rm> +extract32 11111,0111,100,Rn.4,RdLo.4,RdHi.4,110,0,Rm.4 +pcode M=0; dLo = UInt(RdLo); dHi = UInt(RdHi); n = UInt(Rn); m = UInt(Rm); m_swap = (M == '1'); if BadReg(dLo) || BadReg(dHi) || BadReg(n) || BadReg(m) then UNPREDICTABLE; if dHi == dLo then UNPREDICTABLE; +Encoding T1 ARMv6T2, ARMv7 +fmt SMLALDX<c> <RdLo>,<RdHi>,<Rn>,<Rm> +extract32 11111,0111,100,Rn.4,RdLo.4,RdHi.4,110,1,Rm.4 +pcode M=1; dLo = UInt(RdLo); dHi = UInt(RdHi); n = UInt(Rn); m = UInt(Rm); m_swap = (M == '1'); if BadReg(dLo) || BadReg(dHi) || BadReg(n) || BadReg(m) then UNPREDICTABLE; if dHi == dLo then UNPREDICTABLE; + +smlsld: +Encoding T1 ARMv6T2, ARMv7 +fmt SMLSLD<c> <RdLo>,<RdHi>,<Rn>,<Rm> +extract32 11111,0111,1,01,Rn.4,RdLo.4,RdHi.4,110,0,Rm.4 +pcode M=0; dLo = UInt(RdLo); dHi = UInt(RdHi); n = UInt(Rn); m = UInt(Rm); m_swap = (M == '1'); if BadReg(dLo) || BadReg(dHi) || BadReg(n) || BadReg(m) then UNPREDICTABLE; if dHi == dLo then UNPREDICTABLE; +Encoding T1 ARMv6T2, ARMv7 +fmt SMLSLDX<c> <RdLo>,<RdHi>,<Rn>,<Rm> +extract32 11111,0111,1,01,Rn.4,RdLo.4,RdHi.4,110,1,Rm.4 +pcode M=1; dLo = UInt(RdLo); dHi = UInt(RdHi); n = UInt(Rn); m = UInt(Rm); m_swap = (M == '1'); if BadReg(dLo) || BadReg(dHi) || BadReg(n) || BadReg(m) then UNPREDICTABLE; if dHi == dLo then UNPREDICTABLE; + +umlal: +Encoding T1 ARMv6T2, ARMv7 +fmt UMLAL<c> <RdLo>,<RdHi>,<Rn>,<Rm> +extract32 11111,0111,110,Rn.4,RdLo.4,RdHi.4,0000,Rm.4 +pcode dLo = UInt(RdLo); dHi = UInt(RdHi); n = UInt(Rn); m = UInt(Rm); setflags = FALSE; if BadReg(dLo) || BadReg(dHi) || BadReg(n) || BadReg(m) then UNPREDICTABLE; if dHi == dLo then UNPREDICTABLE; + +umaal: +Encoding T1 ARMv6T2, ARMv7 +fmt UMAAL<c> <RdLo>,<RdHi>,<Rn>,<Rm> +extract32 11111,0111,110,Rn.4,RdLo.4,RdHi.4,0110,Rm.4 +pcode dLo = UInt(RdLo); dHi = UInt(RdHi); n = UInt(Rn); m = UInt(Rm); if BadReg(dLo) || BadReg(dHi) || BadReg(n) || BadReg(m) then UNPREDICTABLE; if dHi == dLo then UNPREDICTABLE; + +//----------------------------------------------------------------------------- + +qadd: +Encoding T1 ARMv6T2, ARMv7 +fmt QADD<c> <Rd>,<Rm>,<Rn> +extract32 11111,010,1,000,Rn.4,1111,Rd.4,1,000,Rm.4 +pcode d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); if BadReg(d) || BadReg(n) || BadReg(m) then UNPREDICTABLE; + +qdadd: +Encoding T1 ARMv6T2, ARMv7 +fmt QDADD<c> <Rd>,<Rm>,<Rn> +extract32 11111,010,1,000,Rn.4,1111,Rd.4,1,001,Rm.4 +pcode d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); if BadReg(d) || BadReg(n) || BadReg(m) then UNPREDICTABLE; + +qsub: +Encoding T1 ARMv6T2, ARMv7 +fmt QSUB<c> <Rd>,<Rm>,<Rn> +extract32 11111,010,1,000,Rn.4,1111,Rd.4,1,010,Rm.4 +pcode d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); if BadReg(d) || BadReg(n) || BadReg(m) then UNPREDICTABLE; + +qdsub: +Encoding T1 ARMv6T2, ARMv7 +fmt QDSUB<c> <Rd>,<Rm>,<Rn> +extract32 11111,010,1,000,Rn.4,1111,Rd.4,1,011,Rm.4 +pcode d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); if BadReg(d) || BadReg(n) || BadReg(m) then UNPREDICTABLE; + +rbit: +Encoding T1 ARMv6T2, ARMv7 +fmt RBIT<c> <Rd>,<Rm> +extract32 11111,010,1,001,Rm.4,1111,Rd.4,1,010,Rm.4 +pcode if !Consistent(Rm) then UNPREDICTABLE; d = UInt(Rd); m = UInt(Rm); if BadReg(d) || BadReg(m) then UNPREDICTABLE; + +sel: +Encoding T1 ARMv6T2, ARMv7 +fmt SEL<c> <Rd>,<Rn>,<Rm> +extract32 11111,010,1,010,Rn.4,1111,Rd.4,1,000,Rm.4 +pcode d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); if BadReg(d) || BadReg(n) || BadReg(m) then UNPREDICTABLE; + +clz: +Encoding T1 ARMv6T2, ARMv7 +fmt CLZ<c> <Rd>,<Rm> +extract32 11111,010,1,011,Rm.4,1111,Rd.4,1,000,Rm.4 +pcode if !Consistent(Rm) then UNPREDICTABLE; d = UInt(Rd); m = UInt(Rm); if BadReg(d) || BadReg(m) then UNPREDICTABLE; + +//----------------------------------------------------------------------------- + +rrx: +Encoding T1 ARMv6T2, ARMv7 +fmt RRX{S}<c> <Rd>,<Rm> +extract32 11101,01,0010,S.1,1111,(0),000,Rd.4,00,11,Rm.4 +pcode d = UInt(Rd); m = UInt(Rm); setflags = (S == '1'); if BadReg(d) || BadReg(m) then UNPREDICTABLE; + +ror_immediate: +Encoding T1 ARMv6T2, ARMv7 +fmt ROR{S}<c> <Rd>,<Rm>,#<shift_n> +extract32 11101,01,0010,S.1,1111,(0),imm3.3,Rd.4,imm2.2,11,Rm.4 +pcode if (imm3:imm2) == '00000' then SEE RRX; d = UInt(Rd); m = UInt(Rm); setflags = (S == '1'); (-, shift_n) = DecodeImmShift('11', imm3:imm2); if BadReg(d) || BadReg(m) then UNPREDICTABLE; + +//----------------------------------------------------------------------------- + +mcr_mcr2: +Encoding T1 ARMv6T2, ARMv7 +fmt MCR<c> <coproc>,#<opc1>,<Rt>,<CRn>,<CRm>,#<opc2> +extract32 1110,1110,opc1.3,0,CRn.4,Rt.4,coproc.4,opc2.3,1,CRm.4 +pcode if (coproc == '1010') || (coproc == '1011') then SEE "nop"; t = UInt(Rt); cp = UInt(coproc); if t == 15 || (t == 13 && (CurrentInstrSet() != InstrSet_ARM)) then UNPREDICTABLE; +Encoding T2 ARMv6T2, ARMv7 +fmt MCR2<c> <coproc>,#<opc1>,<Rt>,<CRn>,<CRm>,#<opc2> +extract32 1111,1110,opc1.3,0,CRn.4,Rt.4,coproc.4,opc2.3,1,CRm.4 +pcode t = UInt(Rt); cp = UInt(coproc); if t == 15 || (t == 13 && (CurrentInstrSet() != InstrSet_ARM)) then UNPREDICTABLE; + +mrc_mrc2: +Encoding T1 ARMv6T2, ARMv7 +fmt MRC<c> <coproc>,#<opc1>,<Rt_mrc>,<CRn>,<CRm>,#<opc2> +extract32 1110,1110,opc1.3,1,CRn.4,Rt_mrc.4,coproc.4,opc2.3,1,CRm.4 +pcode_start +if (coproc == '1010') || (coproc == '1011') then SEE "nop"; +t = UInt(Rt_mrc); cp = UInt(coproc); +if t == 13 && (CurrentInstrSet() != InstrSet_ARM) then UNPREDICTABLE; +pcode_end +Encoding T2 ARMv6T2, ARMv7 +fmt MRC2<c> <coproc>,#<opc1>,<Rt_mrc>,<CRn>,<CRm>,#<opc2> +extract32 1111,1110,opc1.3,1,CRn.4,Rt_mrc.4,coproc.4,opc2.3,1,CRm.4 +pcode_start +t = UInt(Rt_mrc); +cp = UInt(coproc); +if t == 13 && (CurrentInstrSet() != InstrSet_ARM) then UNPREDICTABLE; +pcode_end + +//----------------------------------------------------------------------------- +// NEON madness +//----------------------------------------------------------------------------- + +vst1_mult_1elem: +group NEON +Encoding T1 ADVSIMD +fmt VST1<c>.<size> <registers>,[<Rn>,#<align>] +fmt VST1<c>.<size> <registers>,[<Rn>,#<align>]! +fmt VST1<c>.<size> <registers>,[<Rn>,#<align>],<Rm> +extract32 1111,1001,0,D.1,00,Rn.4,Vd.4,type.4,size.2,align.2,Rm.4 +pcode_start +case type of + when '0111' + regs = 1; if align<1> == '1' then UNDEFINED; + when '1010' + regs = 2; if align == '11' then UNDEFINED; + when '0110' + regs = 3; if align<1> == '1' then UNDEFINED; + when '0010' + regs = 4; +alignment = if align == '00' then 1 else 64 << UInt(align-1); +ebytes = 1 << UInt(size); esize = 8 * ebytes; elements = 8 / ebytes; +d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm); +wback = (m != 15); register_index = (m != 15 && m != 13); +if d+regs > 32 then UNPREDICTABLE; +pcode_end + +vpush: +group NEON +Encoding T1 VFPv2, VFPv3, ADVSIMD +fmt VPUSH<c> <registers> +extract32 cond.4,110,1,0,D.1,1,0,1101,Vd.4,1011,imm8.8 +pcode single_regs = FALSE; d = UInt(D:Vd); imm32 = ZeroExtend(imm8:'00', 32); regs = UInt(imm8) / 2; if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE; +Encoding T2 VFPv2, VFPv3 +fmt VPUSH<c> <registers> +extract32 cond.4,110,1,0,D.1,1,0,1101,Vd.4,1010,imm8.8 +pcode single_regs = TRUE; d = UInt(Vd:D); imm32 = ZeroExtend(imm8:'00', 32); regs = UInt(imm8); if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE; + +vpop: +group NEON +Encoding T1 VFPv2, VFPv3, ADVSIMD +fmt VPOP<c> <registers> +extract32 cond.4,110,0,1,D.1,1,1,1101,Vd.4,1011,imm8.8 +pcode single_regs = FALSE; d = UInt(D:Vd); imm32 = ZeroExtend(imm8:'00', 32); regs = UInt(imm8) / 2; if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE; +Encoding T2 VFPv2, VFPv3 +fmt VPOP<c> <registers> +extract32 cond.4,110,0,1,D.1,1,1,1101,Vd.4,1010,imm8.8 +pcode single_regs = TRUE; d = UInt(Vd:D); imm32 = ZeroExtend(imm8:'00', 32); regs = UInt(imm8); if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE; + +advanced_simd_data_proc: +extract32 111,U.1,1111,A.5,xxx,xxxx,B.4,C.4,xxxx +on U,A,B,C +x,0xxxx,xxxx,xxxx advsimd_three_reg_same_len +x,1x000,xxxx,0xx1 advsimd_one_reg_mod_imm +x,1x001,xxxx,0xx1 advsimd_two_reg_shift +x,1x01x,xxxx,0xx1 advsimd_two_reg_shift +x,1x1xx,xxxx,0xx1 advsimd_two_reg_shift +x,1xxxx,xxxx,1xx1 advsimd_two_reg_shift +x,1x0xx,xxxx,x0x0 advsimd_three_reg_diff_len +x,1x10x,xxxx,x0x0 advsimd_three_reg_diff_len +x,1x0xx,xxxx,x1x0 advsimd_two_reg_scalar +x,1x10x,xxxx,x1x0 advsimd_two_reg_scalar +0,1x11x,xxxx,xxx0 vext +1,1x11x,xxxx,xxx0 advsimd_two_reg_misc +1,1x11x,10xx,xxx0 vtbl +1,1x11x,1100,0xx0 vdup_scalar + +advsimd_three_reg_same_len: +extract32 111,U.1,1111,0,x,C.2,xxxxxxxx,A.4,xxx,B.1,xxxx +on A,B,U,C +0000,0,x,x vhadd +0000,1,x,x vqadd +0001,0,x,x vrhadd +0001,1,0,00 vand +0001,1,0,01 vbic_register +0001,1,0,10 vorr_register +0001,1,0,11 vorn_register +0001,1,1,00 veor +0001,1,1,01 vbsl +0001,1,1,10 vbit +0001,1,1,11 vbif +0010,0,x,x vhsub +0011,0,x,x vcgt_register +0011,1,x,x vcge_register +0010,1,x,x vqsub +0100,0,x,x vshl_register +0100,1,x,x vqshl_register +0101,0,x,x vrshl +0101,1,x,x vqrshl +0110,x,x,x vmax_vmin_integer +0111,0,x,xx vabd_integer +0111,1,x,x vaba +1000,0,0,x vadd_integer +1000,0,1,x vsub_integer +1000,1,0,x vtst +1000,1,1,x vceq_register +1001,0,x,x vmla_integer +1001,1,x,x vmul_integer +1010,x,x,x vpmax_integer +1011,1,0,x vpadd_integer +1100,1,0,x vfma +1101,0,1,1x vabd_float +1101,0,0,0x vadd_float +1101,0,0,1x vsub_float +1101,0,1,0x vpadd_float +1101,1,0,x vmla_float +1101,1,1,0x vmul_float +1111,0,0,x vmax_vmin_float +1011,0,0,x vqdmulh +1011,0,1,x vqrdmulh +1110,0,1,0x vcge_register +1110,0,1,1x vcgt_register +1110,1,1,x vacge +1110,0,0,0x vceq_register +1111,0,1,x vpmax_float +1111,1,0,0x vrecps +1111,1,0,1x vrsqrts +x,x,x,x undefined + +advsimd_three_reg_diff_len: +extract32 111,U.1,11111,x,B.2,xxxxxxxx,A.4,x,0,x,0,xxxx +on A,U +0111,x vabd_integer +001x,x vsubl +0101,x vaba +000x,x vaddlw +0100,0 vaddhn +0100,1 vraddhn +0110,0 vsubhn +0110,1 vrsubhn +10x0,x vmla_integer +10x1,0 vqdmlal +1100,x vmul_integer +1101,0 vqdmull +1110,x vmul_integer +x,x undefined + +advsimd_one_reg_mod_imm: +extract32 111,a.1,11111,x,000,b.1,c.1,d.1,xxxx,cmode.4,0,x,op.1,1,e.1,f.1,g.1,h.1 +on op,cmode +0,0xx0 vmov_immediate +0,0xx1 vorr_immediate +0,10x0 vmov_immediate +0,10x1 vorr_immediate +0,11xx vmov_immediate +1,1110 vmov_immediate +1,0xx0 vmvn_immediate +1,0xx1 vbic_immediate +1,10x0 vmvn_immediate +1,10x1 vbic_immediate +1,110x vmvn_immediate +x,x undefined + +advsimd_two_reg_shift: +extract32 111,U.1,11111,x,imm3.3,xxxxxxx,A.4,L.1,B.1,x,1,xxxx +on A,U,B,L +0000,x,x,x vshr +0001,x,x,x vsra +0010,x,x,x vrshr +0011,x,x,x vrsra +0100,1,x,x vsri +0101,0,x,x vshl_immediate +0101,1,x,x vsli +011x,x,x,x vqshl_immediate +1010,x,0,0 vshll +1010,x,0,0 vmovl +111x,x,x,0 vcvt_float_fixed +1000,0,0,0 vshrn +1000,0,1,0 vrshrn +1000,1,0,0 vqshrn +1000,1,1,0 vqrshrn +1001,x,0,0 vqshrn +1001,x,1,0 vqrshrn +x,x,x,x undefined + + +advsimd_two_reg_scalar: +extract32 111,U.1,11111,x,B.2,xxxxxxxx,A.4,x,1,x,0,xxxx +on A,U +0x0x,x vmla_scalar +0x10,x vmla_scalar +0x11,0 vqdmlal +100x,x vmul_scalar +1010,x vmul_scalar +1011,0 vqdmull +1100,x vqdmulh +1101,x vqrdmulh +x,x undefined + + +advsimd_two_reg_misc: +extract32 1111,1111,1,x,11,xx,A.2,xxxx,0,B.5,x,0,xxxx +on A,B +// A=00 +00,0010x vrev16 +00,0001x vrev32 +00,0000x vrev64 +00,010xx vpaddl +00,1000x vcls +00,1001x vclz +00,1010x vcnt +00,1011x vmvn +00,110xx vpadal +00,1110x vqabs +00,1111x vqneg +// A=01 +01,x110x vabs +01,x111x vneg +01,x000x vcgt_immediate +01,x001x vcge_immediate +01,x011x vcle_immediate +01,x100x vclt_immediate +01,x010x vceq_immediate +// A=10 +10,0000x vswp +10,0001x vtrn +10,0010x vuzp +10,0011x vzip +10,01000 vmovn +10,01001 vqmovn +10,0101x vqmovn +10,01100 vshll +10,11x00 vcvt_half_single +// A=11 +11,10x0x vrecpe +11,10x1x vrsqrte +11,11xxx vcvt_float_int + + +vpaddl: +group NEON +Encoding T1 ADVSIMD +fmt VPADDL<c>.<dt> <Dd>,<Dm> +fmt VPADDL<c>.<dt> <Qd>,<Qm> +extract32 1111,xx11,1,D.1,11,size.2,00,Vd.4,0010,op.1,Q.1,M.1,0,Vm.4 +pcode_start +if size == '11' then UNDEFINED; +if (Q == '1' && (Vd<0> == '1' || Vm<0> == '1')) then UNDEFINED; +unsigned = (op == '1'); +esize = 8 << UInt(size); elements = 64 DIV esize; +d = UInt(D:Vd); m = UInt(M:Vm); regs = if Q == '0' then 1 else 2; +fmt_idx = (Q == '1') +dt = UInt(op:size); +pcode_end + +vcls: +group NEON +Encoding T1 ADVSIMD +fmt VCLS<c>.<dt> <Dd>,<Dm> +fmt VCLS<c>.<dt> <Qd>,<Qm> +extract32 1111,xx11,1,D.1,11,size.2,00,Vd.4,0,1000,Q.1,M.1,0,Vm.4 +pcode_start +if size == '11' then UNDEFINED; +if Q == '1' && (Vd<0> == '1' || Vm<0> == '1') then UNDEFINED; +esize = 8 << UInt(size); elements = 64 DIV esize; +d = UInt(D:Vd); m = UInt(M:Vm); regs = if Q == '0' then 1 else 2; +fmt_idx = (Q == '1') +dt = size; +pcode_end + +vclz: +group NEON +Encoding T1 ADVSIMD +fmt VCLZ<c>.<dt> <Dd>,<Dm> +fmt VCLZ<c>.<dt> <Qd>,<Qm> +extract32 1111,xx11,1,D.1,11,size.2,00,Vd.4,0,1001,Q.1,M.1,0,Vm.4 +pcode_start +if size == '11' then UNDEFINED; +if Q == '1' && (Vd<0> == '1' || Vm<0> == '1') then UNDEFINED; +esize = 8 << UInt(size); elements = 64 DIV esize; +d = UInt(D:Vd); m = UInt(M:Vm); regs = if Q == '0' then 1 else 2; +iword = TRUE; +fmt_idx = (Q == '1'); +dt = size; +pcode_end + +vcnt: +group NEON +Encoding T1 ADVSIMD +fmt VCNT<c>.8 <Dd>,<Dm> +fmt VCNT<c>.8 <Qd>,<Qm> +extract32 1111,xx11,1,D.1,11,size.2,00,Vd.4,0,1010,Q.1,M.1,0,Vm.4 +pcode_start +if size != '00' then UNDEFINED; +if Q == '1' && (Vd<0> == '1' || Vm<0> == '1') then UNDEFINED; +esize = 8; +elements = 8; +d = UInt(D:Vd); +m = UInt(M:Vm); +regs = if Q == '0' then 1 else 2; +fmt_idx = (Q == '1') +pcode_end + +vmvn: +group NEON +Encoding T1 ADVSIMD +fmt VMVN<c> <Dd>,<Dm> +fmt VMVN<c> <Qd>,<Qm> +extract32 1111,xx11,1,D.1,11,size.2,00,Vd.4,0,1011,Q.1,M.1,0,Vm.4 +pcode_start +if size != '00' then UNDEFINED; +if Q == '1' && (Vd<0> == '1' || Vm<0> == '1') then UNDEFINED; +d = UInt(D:Vd); m = UInt(M:Vm); regs = if Q == '0' then 1 else 2; +fmt_idx = (Q == '1') +pcode_end + +vpadal: +group NEON +Encoding T1 ADVSIMD +fmt VPADAL<c>.<dt> <Dd>,<Dm> +fmt VPADAL<c>.<dt> <Qd>,<Qm> +extract32 1111,xx11,1,D.1,11,size.2,00,Vd.4,0110,op.1,Q.1,M.1,0,Vm.4 +pcode_start +if size == '11' then UNDEFINED; +if (Q == '1' && (Vd<0> == '1' || Vm<0> == '1')) then UNDEFINED; +unsigned = (op == '1'); +esize = 8 << UInt(size); elements = 64 DIV esize; +d = UInt(D:Vd); m = UInt(M:Vm); regs = if Q == '0' then 1 else 2; +fmt_idx = (Q == '1'); +dt = UInt(op:size); +pcode_end + +vqabs: +Encoding T1 ADVSIMD +fmt VQABS<c>.<dt> <Dd>,<Dm> +fmt VQABS<c>.<dt> <Qd>,<Qm> +extract32 1111,xx11,1,D.1,11,size.2,00,Vd.4,0111,0,Q.1,M.1,0,Vm.4 +pcode if size == '11' then UNDEFINED; if Q == '1' && (Vd<0> == '1' || Vm<0> == '1') then UNDEFINED; esize = 8 << UInt(size); elements = 64 DIV esize; d = UInt(D:Vd); m = UInt(M:Vm); regs = if Q == '0' then 1 else 2; fmt_idx = (Q=='1'); dt = size; + +vand: +Encoding T1 ADVSIMD +fmt VAND<c> <Dd>,<Dn>,<Dm> +fmt VAND<c> <Qd>,<Qn>,<Qm> +extract32 111x,xx1x,0,D.1,00,Vn.4,Vd.4,0001,N.1,Q.1,M.1,1,Vm.4 +pcode_start +if Q == '1' && (Vd<0> == '1' || Vn<0> == '1' || Vm<0> == '1') then UNDEFINED; +d = UInt(D:Vd); n = UInt(N:Vn); m = UInt(M:Vm); regs = if Q == '0' then 1 else 2; +fmt_idx = (Q == '1') +pcode_end + +veor: +Encoding T1 ADVSIMD +fmt VEOR<c> <Dd>,<Dn>,<Dm> +fmt VEOR<c> <Qd>,<Qn>,<Qm> +extract32 1111,xx11,0,D.1,00,Vn.4,Vd.4,0001,N.1,Q.1,M.1,1,Vm.4 +pcode_start +if Q == '1' && (Vd<0> == '1' || Vn<0> == '1' || Vm<0> == '1') then UNDEFINED; +d = UInt(D:Vd); n = UInt(N:Vn); m = UInt(M:Vm); regs = if Q == '0' then 1 else 2; +fmt_idx = (Q == '1') +pcode_end + +vorr_register: +Encoding T1 ADVSIMD +fmt VORR<c> <Dd>,<Dn>,<Dm> +fmt VORR<c> <Qd>,<Qn>,<Qm> +extract32 1110,xx11,0,D.1,10,Vn.4,Vd.4,0001,N.1,Q.1,M.1,1,Vm.4 +pcode_start +if N == M && Vn == Vm then SEE vmov_register; +if Q == '1' && (Vd<0> == '1' || Vn<0> == '1' || Vm<0> == '1') then UNDEFINED; +d = UInt(D:Vd); n = UInt(N:Vn); m = UInt(M:Vm); regs = if Q == '0' then 1 else 2; +fmt_idx = (Q == '1') +pcode_end + +vorr_immediate: +Encoding T1 ADVSIMD +fmt VORR<c>.<dt> <Dd>,#<imm64> +fmt VORR<c>.<dt> <Qd>,#<imm64> +extract32 111,i.1,1111,1,D.1,000,imm3.3,Vd.4,cmode.4,0,Q.1,0,1,imm4.4 +pcode_start +if cmode<0> == '0' || cmode<3:2> == '11' then SEE VMOV (immediate); +if Q == '1' && Vd<0> == '1' then UNDEFINED; +imm64l = AdvSIMDExpandImm('0', cmode, i:imm3:imm4, 1); +imm64h = AdvSIMDExpandImm('0', cmode, i:imm3:imm4, 0); +d = UInt(D:Vd); regs = if Q == '0' then 1 else 2; +iword = TRUE; +fmt_idx = (Q == '1'); +dt = 1; +pcode_end + +vbic_register: +Encoding T1 ADVSIMD +fmt VBIC<c> <Dd>,<Dn>,<Dm> +fmt VBIC<c> <Qd>,<Qn>,<Qm> +extract32 111x,xx1x,0,D.1,01,Vn.4,Vd.4,0001,N.1,Q.1,M.1,1,Vm.4 +pcode_start +if Q == '1' && (Vd<0> == '1' || Vn<0> == '1' || Vm<0> == '1') then UNDEFINED; +d = UInt(D:Vd); n = UInt(N:Vn); m = UInt(M:Vm); regs = if Q == '0' then 1 else 2; +fmt_idx = (Q == '1') +pcode_end + +vbic_immediate: +Encoding T1 ADVSIMD +fmt VBIC<c>.<dt> <Dd>,#<imm64> +fmt VBIC<c>.<dt> <Qd>,#<imm64> +extract32 111,i.1,1111,1,D.1,000,imm3.3,Vd.4,cmode.4,0,Q.1,1,1,imm4.4 +pcode_start +if (cmode<0> == '0') || (cmode<3:2> == '11') then SEE advsimd_one_reg_mod_imm; +if (Q == '1' && Vd<0> == '1') then UNDEFINED; +imm64l = AdvSIMDExpandImm('1', cmode, i:imm3:imm4, 1); +imm64h = AdvSIMDExpandImm('1', cmode, i:imm3:imm4, 0); +d = UInt(D:Vd); regs = if Q == '0' then 1 else 2; +iword = TRUE; +fmt_idx = (Q == '1'); +dt = (D == '1') + 1; +pcode_end + +vorn_register: +Encoding T1 ADVSIMD +fmt VORN<c> <Dd>,<Dn>,<Dm> +fmt VORN<c> <Qd>,<Qn>,<Qm> +extract32 111x,xx1x,0,D.1,11,Vn.4,Vd.4,0001,N.1,Q.1,M.1,1,Vm.4 +pcode_start +if Q == '1' && (Vd<0> == '1' || Vn<0> == '1' || Vm<0> == '1') then UNDEFINED; +d = UInt(D:Vd); n = UInt(N:Vn); m = UInt(M:Vm); regs = if Q == '0' then 1 else 2; +fmt_idx = (Q == '1') +pcode_end + +vbsl: +Encoding T1 ADVSIMD +fmt VBSL<c> <Dd>,<Dn>,<Dm> +fmt VBSL<c> <Qd>,<Qn>,<Qm> +extract32 1111,xx11,0,D.1,01,Vn.4,Vd.4,0001,N.1,Q.1,M.1,1,Vm.4 +pcode_start +if Q == '1' && (Vd<0> == '1' || Vn<0> == '1' || Vm<0> == '1') then UNDEFINED; +d = UInt(D:Vd); n = UInt(N:Vn); m = UInt(M:Vm); regs = if Q == '0' then 1 else 2; +fmt_idx = (Q == '1') +pcode_end + +vbit: +Encoding T1 ADVSIMD +fmt VBIT<c> <Dd>,<Dn>,<Dm> +fmt VBIT<c> <Qd>,<Qn>,<Qm> +extract32 1111,xx11,0,D.1,10,Vn.4,Vd.4,0001,N.1,Q.1,M.1,1,Vm.4 +pcode_start +if Q == '1' && (Vd<0> == '1' || Vn<0> == '1' || Vm<0> == '1') then UNDEFINED; +d = UInt(D:Vd); n = UInt(N:Vn); m = UInt(M:Vm); regs = if Q == '0' then 1 else 2; +fmt_idx = (Q == '1') +pcode_end + +vbif: +Encoding T1 ADVSIMD +fmt VBIF<c> <Dd>,<Dn>,<Dm> +fmt VBIF<c> <Qd>,<Qn>,<Qm> +extract32 1111,xx11,0,D.1,11,Vn.4,Vd.4,0001,N.1,Q.1,M.1,1,Vm.4 +pcode_start +if Q == '1' && (Vd<0> == '1' || Vn<0> == '1' || Vm<0> == '1') then UNDEFINED; +d = UInt(D:Vd); n = UInt(N:Vn); m = UInt(M:Vm); regs = if Q == '0' then 1 else 2; +fmt_idx = (Q == '1') +pcode_end + +vmax_vmin_integer: +group NEON +Encoding T1 ADVSIMD +fmt VMAX<c>.<dt> <Dd>,<Dn>,<Dm> +fmt VMAX<c>.<dt> <Qd>,<Qn>,<Qm> +extract32 111,U.1,1111,0,D.1,size.2,Vn.4,Vd.4,0110,N.1,Q.1,M.1,0,Vm.4 +pcode_start +if Q == '1' && (Vd<0> == '1' || Vn<0> == '1' || Vm<0> == '1') then UNDEFINED; +if size == '11' then UNDEFINED; +unsigned = (U == '1'); +esize = 8 << UInt(size); elements = 64 DIV esize; +d = UInt(D:Vd); n = UInt(N:Vn); m = UInt(M:Vm); regs = if Q == '0' then 1 else 2; +fmt_idx = (Q == '1') +dt = UInt(U:size); +pcode_end +Encoding T2 ADVSIMD +fmt VMIN<c>.<dt> <Dd>,<Dn>,<Dm> +fmt VMIN<c>.<dt> <Qd>,<Qn>,<Qm> +extract32 111,U.1,1111,0,D.1,size.2,Vn.4,Vd.4,0110,N.1,Q.1,M.1,1,Vm.4 +pcode_start +if Q == '1' && (Vd<0> == '1' || Vn<0> == '1' || Vm<0> == '1') then UNDEFINED; +if size == '11' then UNDEFINED; +unsigned = (U == '1'); +esize = 8 << UInt(size); elements = 64 DIV esize; +d = UInt(D:Vd); n = UInt(N:Vn); m = UInt(M:Vm); regs = if Q == '0' then 1 else 2; +fmt_idx = (Q == '1') +dt = UInt(U:size); +pcode_end + +vmax_vmin_float: +group NEON +Encoding T1 ADVSIMD +fmt VMAX<c>.F32 <Dd>,<Dn>,<Dm> +fmt VMAX<c>.F32 <Qd>,<Qn>,<Qm> +extract32 111x,xx1x,0,D.1,0,sz.1,Vn.4,Vd.4,1111,N.1,Q.1,M.1,0,Vm.4 +pcode_start +if Q == '1' && (Vd<0> == '1' || Vn<0> == '1' || Vm<0> == '1') then UNDEFINED; +if sz == '1' then UNDEFINED; +esize = 32; elements = 2; +d = UInt(D:Vd); n = UInt(N:Vn); m = UInt(M:Vm); regs = if Q == '0' then 1 else 2; +fmt_idx = (Q == '1') +pcode_end +Encoding T1 ADVSIMD +fmt VMIN<c>.F32 <Dd>,<Dn>,<Dm> +fmt VMIN<c>.F32 <Qd>,<Qn>,<Qm> +extract32 111x,xx1x,0,D.1,1,sz.1,Vn.4,Vd.4,1111,N.1,Q.1,M.1,0,Vm.4 +pcode_start +if Q == '1' && (Vd<0> == '1' || Vn<0> == '1' || Vm<0> == '1') then UNDEFINED; +if sz == '1' then UNDEFINED; +esize = 32; elements = 2; +d = UInt(D:Vd); n = UInt(N:Vn); m = UInt(M:Vm); regs = if Q == '0' then 1 else 2; +fmt_idx = (Q == '1') +pcode_end + +vmov_register: +group NEON +Encoding T2 VFPv3 +fmt VMOV<c>.F64 <Dd>,<Dm> +fmt VMOV<c>.F32 <Sd>,<Sm> +extract32 1110,11101,D.1,11,0000,Vd.4,101,sz.1,0,1,M.1,0,Vm.4 +pcode_start +single_register = (sz == '0'); advsimd = FALSE; +d = UInt(D:Vd); +m = UInt(M:Vm); +if sz == '0' then d = UInt(Vd:D); +if sz == '0' then m = UInt(Vm:M); +fmt_idx = (sz == '0'); +pcode_end +Encoding T1 ADVSIMD +fmt VMOV<c> <Dd>,<Dm> +fmt VMOV<c> <Qd>,<Qm> +extract32 1110,1111,0,D.1,10,Vm.4,Vd.4,0001,M.1,Q.1,M.1,1,Vm.4 +pcode_start +if (!Consistent(M) || !Consistent(Vm)) then SEE vorr_register; +if (Q == '1' && (Vd<0> == '1' || Vm<0> == '1')) then UNDEFINED; +single_register = FALSE; +advsimd = TRUE; +d = UInt(D:Vd); m = UInt(M:Vm); regs = if Q == '0' then 1 else 2; +fmt_idx = (Q == '1'); +pcode_end + +vmov_immediate: +group NEON +Encoding T2 VFPv3 +fmt VMOV<c>.F64 <Dd>,#<imm64> +fmt VMOV<c>.F32 <Sd>,#<imm64> +extract32 1110,11101,D.1,11,imm4H.4,Vd.4,101,sz.1,(0),0,(0),0,imm4L.4 +pcode_start +single_register = (sz == '0'); advsimd = FALSE; +d = UInt(D:Vd); +imm64h = VFPExpandImm(imm4H:imm4L, 32, 0); +imm64l = VFPExpandImm(imm4H:imm4L, 32, 0); +if single_register then imm64h = 0; +if !single_register then imm64l = 0; +if sz == '0' then d = UInt(Vd:D); +fmt_idx = (sz == '0'); +pcode_end +Encoding T1 ADVSIMD +fmt VMOV<c>.<dt> <Dd>,#<imm64> +fmt VMOV<c>.<dt> <Qd>,#<imm64> +extract32 111,i.1,1111,1,D.1,000,imm3.3,Vd.4,cmode.4,0,Q.1,op.1,1,imm4.4 +pcode_start +//if (op == '0' && cmode<0> == '1' && cmode<3:2> != '11') then SEE vorr_immediate; +if (op == '1' && cmode != '1110') then SEE advsimd_one_reg_mod_imm; +if (Q == '1' && Vd<0> == '1') then UNDEFINED; +single_register = FALSE; advsimd = TRUE; +d = UInt(D:Vd); regs = if Q == '0' then 1 else 2; +imm64l = AdvSIMDExpandImm(op, cmode, i:imm3:imm4, 1); +imm64h = AdvSIMDExpandImm(op, cmode, i:imm3:imm4, 0); +fmt_idx = (Q == '1'); +dt = UInt(imm3:i); +pcode_end + +vmov_scalar_core: +group NEON +Encoding T1 ADVSIMD +fmt VMOV<c>.<dt> <Rt>,<Dn[x]> +extract32 1110,1110,U.1,opc1.2,1,Vn.4,Rt.4,1011,N.1,opc2.2,1,(0)(0)(0)(0) +pcode_start +if (U == '1' && UInt(opc1) < 2 && opc2 == '00') then UNDEFINED; +if (opc2 == '10' && UInt(opc1) < 2) then UNDEFINED; +esize = 32 +if UInt(opc1) >= 2 then esize = 8; +if (UInt(opc1) < 2 && UInt(opc2) >= 1) then esize = 16; +if esize == 8 then x = (UInt(opc1:opc2)) - 8; +if esize == 16 then x = (UInt(opc1:opc2) >> 1); +if esize == 32 then x = UInt(opc1); +t = UInt(Rt); n = UInt(N:Vn); unsigned = (U == '1'); +dt = 11; +if (U == '0' && esize == 8) then dt = 0; +if (U == '0' && esize == 16) then dt = 1; +if (U == '1' && esize == 8) then dt = 4; +if (U == '1' && esize == 16) then dt = 5; +if (U == '0' && esize == 32) then dt = 8; +pcode_end + +vmov_core_scalar: +group NEON +Encoding T1 ADVSIMD +fmt VMOV<c>.<size> <Dd[x]>,<Rt> +extract32 1110,1110,0,opc1.2,0,Vd.4,Rt.4,1011,D.1,opc2.2,1,(0)(0)(0)(0) +pcode_start +if UInt(opc1) >= 2 then esize = 8; +if (UInt(opc1) < 2 && UInt(opc2 >= 1)) then esize = 16; +if (UInt(opc1) < 2 && opc2 == '00') then esize = 32; +if (UInt(opc1) < 2 && opc2 == '10') then UNDEFINED; +d = UInt(D:Vd); t = UInt(Rt); +if esize == 8 then x = UInt(opc1:opc2) - 8; +if esize == 16 then x = UInt(opc1:opc2) >> 1; +if esize == 32 then x = UInt(opc1); +if esize == 8 then size = 0; +if esize == 16 then size = 1; +if esize == 32 then size = 2; +pcode_end + +vmovl: +group NEON +Encoding T1 ADVSIMD +fmt VMOVL<c>.<dt> <Qd>,<Dm> +extract32 111,U.1,xx11,1,D.1,imm3.3,000,Vd.4,1010,0,0,M.1,1,Vm.4 +pcode_start +if imm3 == '000' then SEE advsimd_one_reg_mod_imm; +if ((imm3 != '001') && (imm3 != '010') && (imm3 != '100')) then SEE vshll; +if Vd<0> == '1' then UNDEFINED; +esize = 8 * UInt(imm3); +unsigned = (U == '1'); elements = 64 DIV esize; +d = UInt(D:Vd); m = UInt(M:Vm); +unsigned = TRUE; +dt = UInt(U:imm3) +dt = dt DIV 2 +pcode_end + +vmvn_immediate: +group NEON +Encoding T1 ADVSIMD +fmt VMVN<c>.<dt> <Dd>,#<imm64> +fmt VMVN<c>.<dt> <Qd>,#<imm64> +extract32 111,i.1,1111,1,D.1,000,imm3.3,Vd.4,cmode.4,0,Q.1,1,1,imm4.4 +pcode_start +//if (cmode<0> == '1' && (cmode != '1101' || cmode != '1111')) then SEE advsimd_one_reg_mod_imm; +if (Q == '1' && Vd<0> == '1') then UNDEFINED; +imm64l = AdvSIMDExpandImm('1', cmode, i:imm3:imm4, 1); +imm64h = AdvSIMDExpandImm('1', cmode, i:imm3:imm4, 0); +d = UInt(D:Vd); regs = if Q == '0' then 1 else 2; +fmt_idx = (Q == '1'); +dt = UInt(imm3:i); +pcode_end + +vmovn: +group NEON +Encoding T1 ADVSIMD +fmt VMOVN<c>.<dt> <Dd>,<Qm> +extract32 1111,xx11,1,D.1,11,size.2,10,Vd.4,0,01000,M.1,0,Vm.4 +pcode_start +if size == '11' then UNDEFINED; +if Vm<0> == '1' then UNDEFINED; +esize = 8 << UInt(size); elements = 64 DIV esize; +d = UInt(D:Vd); m = UInt(M:Vm); +iword = TRUE; +dt = size + 1 +pcode_end + +vmov_core_double: +group NEON +Encoding T1 ADVSIMD +fmt VMOV<c> <Dm>,<Rt>,<Rt2> +fmt VMOV<c> <Rt>,<Rt2>,<Dm> +extract32 1110,1100,010,op.1,Rt2.4,Rt.4,1011,00,M.1,1,Vm.4 +pcode_start +t = UInt(Rt); t2 = UInt(Rt2); m = UInt(M:Vm); +if (t == 15 || t2 == 15) then UNPREDICTABLE; +if (t == 13 || t2 == 13) then UNPREDICTABLE; +if ((op == '1') && t == t2) then UNPREDICTABLE; +fmt_idx = op; +pcode_end + +vmov_core_single: +group NEON +Encoding T1 ADVSIMD +fmt VMOV<c> <Sn>,<Rt> +fmt VMOV<c> <Rt>,<Sn> +extract32 1110,1110,000,op.1,Vn.4,Rt.4,1010,N.1,(0)(0),1,(0)(0)(0)(0) +pcode_start +t = UInt(Rt); n = UInt(Vn:N); +if t == 15 || t == 13 then UNPREDICTABLE; +fmt_idx = op; +pcode_end + +vmov_core_two_single: +group NEON +Encoding T1 ADVSIMD +fmt VMOV<c> <Sm>,<Sd>,<Rt>,<Rt2> +fmt VMOV<c> <Rt>,<Rt2>,<Sm>,<Sd> +extract32 1110,1100,010,op.1,Rt2.4,Rt.4,1010,00,M.1,1,Vm.4 +pcode_start +t = UInt(Rt); t2 = UInt(Rt2); m = UInt(Vm:M); +if (t == 15 || t2 == 15 || m == 31) then UNPREDICTABLE; +if (t == 13 || t2 == 13) then UNPREDICTABLE; +if ((op == '1') && t == t2) then UNPREDICTABLE; +d = m + 1; +fmt_idx = op; +pcode_end + +vqmovn: +group NEON +Encoding T1 ADVSIMD +fmt VQMOVN<c>.<type><size> <Dd>,<Qm> +fmt VQMOVUN<c>.<type><size> <Dd>,<Qm> +extract32 1111,xx11,1,D.1,11,size.2,10,Vd.4,0,010,op.2,M.1,0,Vm.4 +pcode_start +if op == '00' then SEE vmovn; +if (size == '11' || Vm<0> == '1') then UNDEFINED; +src_unsigned = (op == '11'); dest_unsigned = (op == '11' || op == '01'); +esize = 8 << UInt(size); elements = 64 DIV esize; +d = UInt(D:Vd); m = UInt(M:Vm); +type = op +fmt_idx = (op == '01'); +pcode_end + +vqdmulh: +group NEON +Encoding T2 ADVSIMD +fmt VQDMULH<c>.<dt> <Dd>,<Dn>,<Dm[x]> +fmt VQDMULH<c>.<dt> <Qd>,<Qn>,<Dm[x]> +extract32 111,Q.1,1111,1,D.1,size.2,Vn.4,Vd.4,1100,N.1,1,M.1,0,Vm.4 +pcode_start +if size == '11' then SEE advanced_simd_data_proc; +if size == '00' then UNDEFINED; +if (Q == '1' && (Vd<0> == '1' || Vn<0> == '1')) then UNDEFINED; +d = UInt(D:Vd); n = UInt(N:Vn); regs = if Q == '0' then 1 else 2; +if size == '01' then esize = 16; +if size == '10' then esize = 32; +elements = 64 DIV esize; +x = UInt(M:Vm); +if esize == 16 then x = x >> 3; +if esize == 32 then x = UInt(M); +m = UInt(Vm); +if esize == 16 then m = m - ((UInt(Vm) >> 3) * 8); +fmt_idx = (op == '1'); +dt = size; +pcode_end +Encoding T1 ADVSIMD +fmt VQDMULH<c>.<dt> <Dd>,<Dn>,<Dm> +fmt VQDMULH<c>.<dt> <Qd>,<Qn>,<Qm> +extract32 111x,xx1x,0,D.1,size.2,Vn.4,Vd.4,1011,N.1,Q.1,M.1,0,Vm.4 +pcode_start +if (Q == '1' && (Vd<0> == '1' || Vn<0> == '1' || Vm<0> == '1')) then UNDEFINED; +if (size == '00' || size == '11') then UNDEFINED; +esize = 8 << UInt(size); elements = 64 DIV esize; +d = UInt(D:Vd); n = UInt(N:Vn); m = UInt(M:Vm); regs = if Q == '0' then 1 else 2; +fmt_idx = (Q == '1'); +dt = size; +pcode_end + +vqrdmulh: +group NEON +Encoding T1 ADVSIMD +fmt VQRDMULH<c>.<dt> <Dd>,<Dn>,<Dm[x]> +fmt VQRDMULH<c>.<dt> <Qd>,<Qn>,<Dm[x]> +extract32 111,Q.1,1111,1,D.1,size.2,Vn.4,Vd.4,1101,N.1,1,M.1,0,Vm.4 +pcode_start +if size == '11' then SEE advanced_simd_data_proc; +if size == '00' then UNDEFINED; +if (Q == '1' && (Vd<0> == '1' || Vn<0> == '1')) then UNDEFINED; +d = UInt(D:Vd); n = UInt(N:Vn); regs = if Q == '0' then 1 else 2; +x = (M << 1) + Vm<3>; +m = UInt(Vm<2:0>); +if size == '01' then esize = 16; +if size == '10' then esize = 32; +elements = 64 DIV esize; +if esize == 32 then m = UInt(Vm); +if esize == 32 then x = UInt(M); +fmt_idx = (Q == '1'); +dt = size; +pcode_end +Encoding T1 ADVSIMD +fmt VQRDMULH<c>.<dt> <Dd>,<Dn>,<Dm> +fmt VQRDMULH<c>.<dt> <Qd>,<Qn>,<Qm> +extract32 1111,xx11,0,D.1,size.2,Vn.4,Vd.4,1011,N.1,Q.1,M.1,0,Vm.4 +pcode_start +if (Q == '1' && (Vd<0> == '1' || Vn<0> == '1' || Vm<0> == '1')) then UNDEFINED; +if (size == '00' || size == '11') then UNDEFINED; +esize = 8 << UInt(size); elements = 64 DIV esize; +d = UInt(D:Vd); n = UInt(N:Vn); m = UInt(M:Vm); regs = if Q == '0' then 1 else 2; +fmt_idx = (Q == '1'); +dt = size; +pcode_end + +vqdmull: +group NEON +Encoding T2 ADVSIMD +fmt VQDMULL<c>.<dt> <Qd>,<Dn>,<Dm[x]> +extract32 1110,1111,1,D.1,size.2,Vn.4,Vd.4,1011,N.1,1,M.1,0,Vm.4 +pcode_start +if size == '11' then SEE advanced_simd_data_proc; +if (size == '00' || Vd<0> == '1') then UNDEFINED; +d = UInt(D:Vd); n = UInt(N:Vn); +if size == '01' then esize = 16; +if size == '10' then esize = 32; +elements = 64 DIV esize; +x = UInt(M:Vm); +if esize == 16 then x = x >> 3; +if esize == 32 then x = UInt(M); +m = UInt(Vm); +if esize == 16 then m = m - ((UInt(Vm) >> 3) * 8); +fmt_idx = (op == '1'); +dt = size; +pcode_end +Encoding T1 ADVSIMD +fmt VQDMULL<c>.<dt> <Qd>,<Dn>,<Dm> +extract32 111x,xx1x,1,D.1,size.2,Vn.4,Vd.4,1101,N.1,0,M.1,0,Vm.4 +pcode_start +if size == '11' then SEE advanced_simd_data_proc; +if (size == '00' || Vd<0> == '1') then UNDEFINED; +d = UInt(D:Vd); n = UInt(N:Vn); m = UInt(M:Vm); +esize = 8 << UInt(size); elements = 64 DIV esize; +dt = size; +pcode_end + +vqneg: +group NEON +Encoding T1 ADVSIMD +fmt VQNEG<c>.<dt> <Dd>,<Dm> +fmt VQNEG<c>.<dt> <Qd>,<Qm> +extract32 1111,xx11,1,D.1,11,size.2,00,Vd.4,0111,1,Q.1,M.1,0,Vm.4 +pcode_start +if size == '11' then UNDEFINED; +if (Q == '1' && (Vd<0> == '1' || Vm<0> == '1')) then UNDEFINED; +esize = 8 << UInt(size); elements = 64 DIV esize; +d = UInt(D:Vd); m = UInt(M:Vm); regs = if Q == '0' then 1 else 2; +fmt_idx = (Q == '1'); +dt = size; +pcode_end + +vpadd_integer: +group NEON +Encoding T1 ADVSIMD +fmt VPADD<c>.<dt> <Dd>,<Dn>,<Dm> +extract32 111x,xx1x,0,D.1,size.2,Vn.4,Vd.4,1011,N.1,Q.1,M.1,1,Vm.4 +pcode_start +if (size == '11' || Q == '1') then UNDEFINED; +esize = 8 << UInt(size); elements = 64 DIV esize; +d = UInt(D:Vd); n = UInt(N:Vn); m = UInt(M:Vm); +iword = TRUE; +dt = size; +pcode_end + +vpadd_float: +group NEON +Encoding T1 ADVSIMD +fmt VPADD<c>.F32 <Dd>,<Dn>,<Dm> +extract32 1111,xx11,0,D.1,0,sz.1,Vn.4,Vd.4,1101,N.1,Q.1,M.1,0,Vm.4 +pcode_start +if (sz == '1' || Q == '1') then UNDEFINED; +esize = 32; elements = 2; +d = UInt(D:Vd); n = UInt(N:Vn); m = UInt(M:Vm); +pcode_end + +vrecps: +group NEON +Encoding T1 ADVSIMD +fmt VRECPS<c>.F32 <Dd>,<Dn>,<Dm> +fmt VRECPS<c>.F32 <Qd>,<Qn>,<Qm> +extract32 111x,xx1x,0,D.1,0,sz.1,Vn.4,Vd.4,1111,N.1,Q.1,M.1,1,Vm.4 +pcode_start +if (Q == '1' && (Vd<0> == '1' || Vn<0> == '1' || Vm<0> == '1')) then UNDEFINED; +if sz == '1' then UNDEFINED; +esize = 32; elements = 2; +d = UInt(D:Vd); n = UInt(N:Vn); m = UInt(M:Vm); regs = if Q == '0' then 1 else 2; +fmt_idx = (Q == '1'); +pcode_end + +vrev64: +group NEON +Encoding T1 ADVSIMD +fmt VREV64<c>.<size> <Dd>,<Dm> +fmt VREV64<c>.<size> <Qd>,<Qm> +extract32 1111,1111,1,D.1,11,size.2,00,Vd.4,000,op.2,Q.1,M.1,0,Vm.4 +pcode_start +//if UInt(op)+UInt(size) >= 3 then UNDEFINED; +if (Q == '1' && (Vd<0> == '1' || Vm<0> == '1')) then UNDEFINED; +esize = 8 << UInt(size); elements = 64 DIV esize; +//groupsize = (1 << (3-UInt(op)-UInt(size)); +//reverse_mask = (groupsize-1)<esize-1:0>; +d = UInt(D:Vd); m = UInt(M:Vm); regs = if Q == '0' then 1 else 2; +fmt_idx = (Q == '1'); +pcode_end + + +vrev32: +group NEON +Encoding T1 ADVSIMD +fmt VREV32<c>.<size> <Dd>,<Dm> +fmt VREV32<c>.<size> <Qd>,<Qm> +extract32 1111,1111,1,D.1,11,size.2,00,Vd.4,000,op.2,Q.1,M.1,0,Vm.4 +pcode_start +//if UInt(op)+UInt(size) >= 3 then UNDEFINED; +if (Q == '1' && (Vd<0> == '1' || Vm<0> == '1')) then UNDEFINED; +esize = 8 << UInt(size); elements = 64 DIV esize; +//groupsize = (1 << (3-UInt(op)-UInt(size)); +//reverse_mask = (groupsize-1)<esize-1:0>; +d = UInt(D:Vd); m = UInt(M:Vm); regs = if Q == '0' then 1 else 2; +fmt_idx = (Q == '1'); +pcode_end + +vrev16: +group NEON +Encoding T1 ADVSIMD +fmt VREV16<c>.<size> <Dd>,<Dm> +fmt VREV16<c>.<size> <Qd>,<Qm> +extract32 1111,1111,1,D.1,11,size.2,00,Vd.4,000,op.2,Q.1,M.1,0,Vm.4 +pcode_start +//if UInt(op)+UInt(size) >= 3 then UNDEFINED; +if (Q == '1' && (Vd<0> == '1' || Vm<0> == '1')) then UNDEFINED; +esize = 8 << UInt(size); elements = 64 DIV esize; +//groupsize = (1 << (3-UInt(op)-UInt(size)); +//reverse_mask = (groupsize-1)<esize-1:0>; +d = UInt(D:Vd); m = UInt(M:Vm); regs = if Q == '0' then 1 else 2; +fmt_idx = (Q == '1'); +pcode_end + +vqshl_immediate: +group NEON +Encoding T1 ADVSIMD +fmt VQSHL<c>.<type><size> <Dd>,<Dm>,#<imm> +fmt VQSHL<c>.<type><size> <Qd>,<Qm>,#<imm> +fmt VQSHLU<c>.<type><size> <Dd>,<Dm>,#<imm> +fmt VQSHLU<c>.<type><size> <Qd>,<Qm>,#<imm> +extract32 111,U.1,1111,1,D.1,imm6.6,Vd.4,011,op.1,L.1,Q.1,M.1,1,Vm.4 +pcode_start +if (L == '0' && UInt(imm6) < 8) then SEE advsimd_one_reg_mod_imm; +if (U == '0' && op == '0') then UNDEFINED; +if (Q == '1' && (Vd<0> == '1' || Vm<0> == '1')) then UNDEFINED; +if UInt(L:imm6) < 128 then esize = 64; +if UInt(L:imm6) < 64 then esize = 32; +if UInt(L:imm6) < 32 then esize = 16; +if UInt(L:imm6) < 16 then esize = 8; +elements = 64 DIV esize; +src_unsigned = (U == '1' && op == '1'); +dest_unsigned = (U == '1'); +d = UInt(D:Vd); m = UInt(M:Vm); regs = if Q == '0' then 1 else 2; +fmt_idx = (op == '0'); +fmt_idx = fmt_idx + fmt_idx; +fmt_idx = fmt_idx + (Q == '1'); +imm = imm6; +type = UInt(U:op); +if esize == 64 then size = 2; +if esize == 32 then size = 1; +if esize == 16 then size = 0; +if esize == 8 then size = 3; +if esize == 64 then imm = UInt(imm6); +if esize == 32 then imm = UInt(imm6) - 32; +if esize == 16 then imm = UInt(imm6) - 16; +if esize == 8 then imm = UInt(imm6) - 8; +pcode_end + + +vqshl_register: +group NEON +Encoding T1 ADVSIMD +fmt VQSHL<c>.<dt> <Dd>,<Dm>,<Dn> +fmt VQSHL<c>.<dt> <Qd>,<Qm>,<Qn> +extract32 111,U.1,1111,0,D.1,size.2,Vn.4,Vd.4,0100,N.1,Q.1,M.1,1,Vm.4 +pcode_start +if (Q == '1' && (Vd<0> == '1' || Vm<0> == '1' || Vn<0> == '1')) then UNDEFINED; +unsigned = (U == '1'); +esize = 8 << UInt(size); elements = 64 DIV esize; +d = UInt(D:Vd); m = UInt(M:Vm); n = UInt(N:Vn); regs = if Q == '0' then 1 else 2; +fmt_idx = (Q == '1'); +dt = UInt(U:size); +pcode_end + +vqrshl: +group NEON +Encoding T1 ADVSIMD +fmt VQRSHL<c>.<dt> <Dd>,<Dm>,<Dn> +fmt VQRSHL<c>.<dt> <Qd>,<Qm>,<Qn> +extract32 111,U.1,1111,0,D.1,size.2,Vn.4,Vd.4,0101,N.1,Q.1,M.1,1,Vm.4 +pcode_start +if (Q == '1' && (Vd<0> == '1' || Vm<0> == '1' || Vn<0> == '1')) then UNDEFINED; +unsigned = (U == '1'); +esize = 8 << UInt(size); elements = 64 DIV esize; +d = UInt(D:Vd); m = UInt(M:Vm); n = UInt(N:Vn); regs = if Q == '0' then 1 else 2; +fmt_idx = (Q == '1'); +dt = UInt(U:size); +pcode_end + +vqshrn: +group NEON +Encoding T1 ADVSIMD +fmt VQSHRN<c>.<type><size> <Dd>,<Qm>,#<imm> +fmt VQSHRUN<c>.<type><size> <Dd>,<Qm>,#<imm> +extract32 111,U.1,1111,1,D.1,imm6.6,Vd.4,100,op.1,00,M.1,1,Vm.4 +pcode_start +if UInt(imm6) < 8 then SEE advsimd_one_reg_mod_imm; +if (U == '0' && op == '0') then SEE vshrn; +if Vm<0> == '1' then UNDEFINED; +if UInt(imm6) < 64 then esize = 32; +if UInt(imm6) < 32 then esize = 16; +if UInt(imm6) < 16 then esize = 8; +elements = 64 DIV esize; +src_unsigned = (U == '1' && op == '1'); +dest_unsigned = (U == '1'); +d = UInt(D:Vd); m = UInt(M:Vm); +fmt_idx = (op == '0'); +imm = imm6; +type = UInt(U:op); +if esize == 32 then size = 2; +if esize == 16 then size = 1; +if esize == 8 then size = 0; +if esize == 32 then imm = 32 - UInt(imm6<4:0>); +if esize == 16 then imm = 16 - UInt(imm6<3:0>); +if esize == 8 then imm = 8 - UInt(imm6<2:0>); +pcode_end + +vqrshrn: +group NEON +Encoding T1 ADVSIMD +fmt VQRSHRN<c>.<type><size> <Dd>,<Qm>,#<imm> +fmt VQRSHRUN<c>.<type><size> <Dd>,<Qm>,#<imm> +extract32 111,U.1,1111,1,D.1,imm6.6,Vd.4,100,op.1,01,M.1,1,Vm.4 +pcode_start +if UInt(imm6) < 8 then SEE advsimd_one_reg_mod_imm; +if (U == '0' && op == '0') then SEE vshrn; +if Vm<0> == '1' then UNDEFINED; +esize = 32; +if UInt(imm6) < 32 then esize = 16; +if UInt(imm6) < 16 then esize = 8; +elements = 64 DIV esize; +src_unsigned = (U == '1' && op == '1'); +dest_unsigned = (U == '1'); +d = UInt(D:Vd); m = UInt(M:Vm); +fmt_idx = (op == '0'); +imm = imm6; +type = UInt(U:op); +if esize == 32 then size = 2; +if esize == 16 then size = 1; +if esize == 8 then size = 0; +if esize == 32 then imm = 32 - UInt(imm6<4:0>); +if esize == 16 then imm = 16 - UInt(imm6<3:0>); +if esize == 8 then imm = 8 - UInt(imm6<2:0>); +pcode_end + +vshl_register: +group NEON +Encoding T1 ADVSIMD +fmt VSHL<c>.<dt> <Dd>,<Dm>,<Dn> +fmt VSHL<c>.<dt> <Qd>,<Qm>,<Qn> +extract32 111,U.1,1111,0,D.1,size.2,Vn.4,Vd.4,0100,N.1,Q.1,M.1,0,Vm.4 +pcode_start +if (Q == '1' && (Vd<0> == '1' || Vm<0> == '1' || Vn<0> == '1')) then UNDEFINED; +unsigned = (U == '1'); +esize = 8 << UInt(size); elements = 64 DIV esize; +d = UInt(D:Vd); m = UInt(M:Vm); n = UInt(N:Vn); regs = if Q == '0' then 1 else 2; +fmt_idx = (Q == '1'); +dt = UInt(U:size); +pcode_end + +vshl_immediate: +group NEON +Encoding T1 ADVSIMD +fmt VSHL<c>.I<size> <Dd>,<Dm>,#<imm> +fmt VSHL<c>.I<size> <Qd>,<Qm>,#<imm> +extract32 111x,xx1x,1,D.1,imm6.6,Vd.4,0101,L.1,Q.1,M.1,1,Vm.4 +pcode_start +if (L == '0' && UInt(imm6) < 8) then SEE advsimd_one_reg_mod_imm; +if (Q == '1' && (Vd<0> == '1' || Vm<0> == '1')) then UNDEFINED; +if UInt(L:imm6) < 128 then esize = 64; +if UInt(L:imm6) < 64 then esize = 32; +if UInt(L:imm6) < 32 then esize = 16; +if UInt(L:imm6) < 16 then esize = 8; +elements = 64 DIV esize; +d = UInt(D:Vd); m = UInt(M:Vm); regs = if Q == '0' then 1 else 2; +fmt_idx = (Q == '1'); +imm = imm6; +if esize == 64 then size = 3; +if esize == 32 then size = 2; +if esize == 16 then size = 1; +if esize == 8 then size = 0; +if esize == 64 then imm = UInt(imm6); +if esize == 32 then imm = UInt(imm6) - 32; +if esize == 16 then imm = UInt(imm6) - 16; +if esize == 8 then imm = UInt(imm6) - 8; +pcode_end + +vshr: +group NEON +Encoding T1 ADVSIMD +fmt VSHR<c>.<type><size> <Dd>,<Dm>,#<imm> +fmt VSHR<c>.<type><size> <Qd>,<Qm>,#<imm> +extract32 111,U.1,1111,1,D.1,imm6.6,Vd.4,0000,L.1,Q.1,M.1,1,Vm.4 +pcode_start +if (L == '0' && UInt(imm6) < 8) then SEE advsimd_one_reg_mod_imm; +if (Q == '1' && (Vd<0> == '1' || Vm<0> == '1')) then UNDEFINED; +if UInt(L:imm6) < 128 then esize = 64; +if UInt(L:imm6) < 64 then esize = 32; +if UInt(L:imm6) < 32 then esize = 16; +if UInt(L:imm6) < 16 then esize = 8; +elements = 64 DIV esize; +d = UInt(D:Vd); m = UInt(M:Vm); regs = if Q == '0' then 1 else 2; +fmt_idx = (Q == '1'); +imm = imm6; +type = UInt(U) + 2; +if esize == 64 then size = 2; +if esize == 32 then size = 1; +if esize == 16 then size = 0; +if esize == 8 then size = 3; +imm = UInt(imm6); +if esize == 64 then imm = 64 - UInt(imm6); +if esize == 32 then imm = 32 - UInt(imm6<4:0>); +if esize == 16 then imm = 16 - UInt(imm6<3:0>); +if esize == 8 then imm = 8 - UInt(imm6<2:0>); +pcode_end + +vrshr: +group NEON +Encoding T1 ADVSIMD +fmt VRSHR<c>.<type><size> <Dd>,<Dm>,#<imm> +fmt VRSHR<c>.<type><size> <Qd>,<Qm>,#<imm> +extract32 111,U.1,1111,1,D.1,imm6.6,Vd.4,0010,L.1,Q.1,M.1,1,Vm.4 +pcode_start +if (L == '0' && UInt(imm6) < 8) then SEE advsimd_one_reg_mod_imm; +if (Q == '1' && (Vd<0> == '1' || Vm<0> == '1')) then UNDEFINED; +if UInt(L:imm6) < 128 then esize = 64; +if UInt(L:imm6) < 64 then esize = 32; +if UInt(L:imm6) < 32 then esize = 16; +if UInt(L:imm6) < 16 then esize = 8; +elements = 64 DIV esize; +d = UInt(D:Vd); m = UInt(M:Vm); regs = if Q == '0' then 1 else 2; +fmt_idx = (Q == '1'); +imm = imm6; +type = UInt(U) + 2; +if esize == 64 then size = 2; +if esize == 32 then size = 1; +if esize == 16 then size = 0; +if esize == 8 then size = 3; +imm = UInt(imm6); +if esize == 64 then imm = 64 - UInt(imm6); +if esize == 32 then imm = 32 - UInt(imm6<4:0>); +if esize == 16 then imm = 16 - UInt(imm6<3:0>); +if esize == 8 then imm = 8 - UInt(imm6<2:0>); +pcode_end + +vrshrn: +group NEON +Encoding T1 ADVSIMD +fmt VRSHRN<c>.I<size> <Dd>,<Qm>,#<imm> +extract32 1110,xx1x,1,D.1,imm6.6,Vd.4,1000,0,1,M.1,1,Vm.4 +pcode_start +if UInt(imm6) < 8 then SEE advsimd_one_reg_mod_imm; +if Vm<0> == '1' then UNDEFINED; +if UInt(imm6) < 64 then esize = 32; +if UInt(imm6) < 32 then esize = 16; +if UInt(imm6) < 16 then esize = 8; +elements = 64 DIV esize; +d = UInt(D:Vd); m = UInt(M:Vm); regs = if Q == '0' then 1 else 2; +imm = imm6; +if esize == 32 then size = 3; +if esize == 16 then size = 2; +if esize == 8 then size = 1; +imm = UInt(imm6); +if esize == 32 then imm = 32 - UInt(imm6<4:0>); +if esize == 16 then imm = 16 - UInt(imm6<3:0>); +if esize == 8 then imm = 8 - UInt(imm6<2:0>); +pcode_end + +vshrn: +group NEON +Encoding T1 ADVSIMD +fmt VSHRN<c>.I<size> <Dd>,<Qm>,#<imm> +extract32 111x,xx1x,1,D.1,imm6.6,Vd.4,1000,0,0,M.1,1,Vm.4 +pcode_start +if UInt(imm6) < 8 then SEE advsimd_one_reg_mod_imm; +if Vm<0> == '1' then UNDEFINED; +esize = 32 +if UInt(imm6) < 32 then esize = 16; +if UInt(imm6) < 16 then esize = 8; +elements = 64 DIV esize; +if esize == 32 then size = 3; +if esize == 16 then size = 2; +if esize == 8 then size = 1; +imm = UInt(imm6); +d = UInt(D:Vd); m = UInt(M:Vm); +if esize == 32 then imm = 32 - UInt(imm6<4:0>); +if esize == 16 then imm = 16 - UInt(imm6<3:0>); +if esize == 8 then imm = 8 - UInt(imm6<2:0>); +pcode_end + +vshll: +group NEON +Encoding T2 ADVSIMD +fmt VSHLL<c>.I<size> <Qd>,<Dm>,#<imm> +extract32 1111,xx11,1,D.1,11,size.2,10,Vd.4,0011,0,0,M.1,0,Vm.4 +pcode_start +if (size == '11' || Vd<0> == '1') then UNDEFINED; +esize = 8 << UInt(size); +unsigned = FALSE; +d = UInt(D:Vd); m = UInt(M:Vm); +if size == '00' then imm = 8; +if size == '01' then imm = 16; +if size == '10' then imm = 32; +pcode_end +Encoding T1 ADVSIMD +fmt VSHLL<c>.<type><size> <Qd>,<Dm>,#<imm> +extract32 111,U.1,1111,1,D.1,imm6.6,Vd.4,1010,0,0,M.1,1,Vm.4 +pcode_start +if UInt(imm6) < 8 then SEE advsimd_one_reg_mod_imm; +if (UInt(imm6) == 8 || UInt(imm6) == 16 || UInt(imm6) == 32) then SEE vmovl; +unsigned = (U == '1'); +d = UInt(D:Vd); m = UInt(M:Vm); +esize = 32 +if UInt(imm6) < 32 then esize = 16; +if UInt(imm6) < 16 then esize = 8; +elements = 64 DIV esize; +type = UInt(U) + 2; +if esize == 32 then size = 1; +if esize == 16 then size = 0; +if esize == 8 then size = 3; +if esize == 32 then imm = UInt(imm6) - 32; +if esize == 16 then imm = UInt(imm6) - 16; +if esize == 8 then imm = UInt(imm6) - 8; +pcode_end + +vrshl: +group NEON +Encoding T1 ADVSIMD +fmt VRSHL<c>.<type><size> <Dd>,<Dm>,<Dn> +fmt VRSHL<c>.<type><size> <Qd>,<Qm>,<Qn> +extract32 111,U.1,1111,0,D.1,size.2,Vn.4,Vd.4,0101,N.1,Q.1,M.1,0,Vm.4 +pcode_start +if (Q == '1' && (Vd<0> == '1' || Vm<0> == '1' || Vn<0> == '1')) then UNDEFINED; +unsigned = (U == '1'); +esize = 8 << UInt(size); elements = 64 DIV esize; +d = UInt(D:Vd); m = UInt(M:Vm); n = UInt(N:Vn); regs = if Q == '0' then 1 else 2; +fmt_idx = (Q == '1'); +type = UInt(U) + 2; +size = if size == '00' then 3 else UInt(size) - 1; +pcode_end + +vsra: +group NEON +Encoding T1 ADVSIMD +fmt VSRA<c>.<type><size> <Dd>,<Dm>,#<imm> +fmt VSRA<c>.<type><size> <Qd>,<Qm>,#<imm> +extract32 111,U.1,1111,1,D.1,imm6.6,Vd.4,0001,L.1,Q.1,M.1,1,Vm.4 +pcode_start +if (L == '0' && UInt(imm6) < 8) then SEE advsimd_one_reg_mod_imm; +if (Q == '1' && (Vd<0> == '1' || Vm<0> == '1')) then UNDEFINED; +if UInt(L:imm6) < 128 then esize = 64; +if UInt(L:imm6) < 64 then esize = 32; +if UInt(L:imm6) < 32 then esize = 16; +if UInt(L:imm6) < 16 then esize = 8; +elements = 64 DIV esize; +d = UInt(D:Vd); m = UInt(M:Vm); regs = if Q == '0' then 1 else 2; +imm = imm6; +type = UInt(U) + 2; +if esize == 64 then size = 2; +if esize == 32 then size = 1; +if esize == 16 then size = 0; +if esize == 8 then size = 3; +imm = UInt(imm6); +if esize == 64 then imm = 64 - UInt(imm6); +if esize == 32 then imm = 64 - UInt(imm6); +if esize == 16 then imm = 32 - UInt(imm6); +if esize == 8 then imm = 16 - UInt(imm6); +fmt_idx = (Q == '1'); +pcode_end + +vrsra: +group NEON +Encoding T1 ADVSIMD +fmt VRSRA<c>.<type><size> <Dd>,<Dm>,#<imm> +fmt VRSRA<c>.<type><size> <Qd>,<Qm>,#<imm> +extract32 111,U.1,1111,1,D.1,imm6.6,Vd.4,0011,L.1,Q.1,M.1,1,Vm.4 +pcode_start +if (L == '0' && UInt(imm6) < 8) then SEE advsimd_one_reg_mod_imm; +if (Q == '1' && (Vd<0> == '1' || Vm<0> == '1')) then UNDEFINED; +if UInt(L:imm6) < 128 then esize = 64; +if UInt(L:imm6) < 64 then esize = 32; +if UInt(L:imm6) < 32 then esize = 16; +if UInt(L:imm6) < 16 then esize = 8; +elements = 64 DIV esize; +d = UInt(D:Vd); m = UInt(M:Vm); regs = if Q == '0' then 1 else 2; +imm = imm6; +type = UInt(U) + 2; +if esize == 64 then size = 2; +if esize == 32 then size = 1; +if esize == 16 then size = 0; +if esize == 8 then size = 3; +imm = UInt(imm6); +if esize == 64 then imm = 64 - UInt(imm6); +if esize == 32 then imm = 64 - UInt(imm6); +if esize == 16 then imm = 32 - UInt(imm6); +if esize == 8 then imm = 16 - UInt(imm6); +fmt_idx = (Q == '1'); +pcode_end + +vsli: +group NEON +Encoding T1 ADVSIMD +fmt VSLI<c>.<size> <Dd>,<Dm>,#<imm> +fmt VSLI<c>.<size> <Qd>,<Qm>,#<imm> +extract32 1111,1111,1,D.1,imm6.6,Vd.4,0101,L.1,Q.1,M.1,1,Vm.4 +pcode_start +if (L == '0' && UInt(imm6) < 8) then SEE advsimd_one_reg_mod_imm; +if (Q == '1' && (Vd<0> == '1' || Vm<0> == '1')) then UNDEFINED; +if UInt(L:imm6) < 128 then esize = 64; +if UInt(L:imm6) < 64 then esize = 32; +if UInt(L:imm6) < 32 then esize = 16; +if UInt(L:imm6) < 16 then esize = 8; +elements = 64 DIV esize; +d = UInt(D:Vd); m = UInt(M:Vm); regs = if Q == '0' then 1 else 2; +imm = imm6; +if esize == 64 then size = 3; +if esize == 32 then size = 2; +if esize == 16 then size = 1; +if esize == 8 then size = 0; +imm = UInt(imm6); +if esize == 32 then imm = UInt(imm6) - 32; +if esize == 16 then imm = UInt(imm6) - 16; +if esize == 8 then imm = UInt(imm6) - 8; +fmt_idx = (Q == '1'); +pcode_end + +vsri: +group NEON +Encoding T1 ADVSIMD +fmt VSRI<c>.<size> <Dd>,<Dm>,#<imm> +fmt VSRI<c>.<size> <Qd>,<Qm>,#<imm> +extract32 1111,xx11,1,D.1,imm6.6,Vd.4,0100,L.1,Q.1,M.1,1,Vm.4 +pcode_start +if (L == '0' && UInt(imm6) < 8) then SEE advsimd_one_reg_mod_imm; +if (Q == '1' && (Vd<0> == '1' || Vm<0> == '1')) then UNDEFINED; +if UInt(L:imm6) < 128 then esize = 64; +if UInt(L:imm6) < 64 then esize = 32; +if UInt(L:imm6) < 32 then esize = 16; +if UInt(L:imm6) < 16 then esize = 8; +elements = 64 DIV esize; +d = UInt(D:Vd); m = UInt(M:Vm); regs = if Q == '0' then 1 else 2; +imm = imm6; +if esize == 64 then size = 3; +if esize == 32 then size = 2; +if esize == 16 then size = 1; +if esize == 8 then size = 0; +imm = UInt(imm6); +if esize == 64 then imm = 64 - UInt(imm6); +if esize == 32 then imm = 64 - UInt(imm6); +if esize == 16 then imm = 32 -UInt(imm6); +if esize == 8 then imm = 16 - UInt(imm6); +fmt_idx = (Q == '1'); +pcode_end + +vcvta: +group NEON +Encoding T1 VFPv3 +fmt VCVTA<c>.S32.F32 <Sd>,<Sm> +fmt VCVTA<c>.S32.F64 <Sd>,<Dm> +fmt VCVTA<c>.U32.F32 <Sd>,<Sm> +fmt VCVTA<c>.U32.F64 <Sd>,<Dm> +extract32 1111,11101,D.1,111,opc1.1,opc2.2,Vd.4,101,sz.1,op.1,1,M.1,0,Vm.4 +pcode_start +round_mode = opc2; +dp_operation = (sz == '1'); unsigned = (op == '0'); +d = UInt(Vd:D); +m = if dp_operation then UInt(M:Vm) else UInt(Vm:M); +fmt_idx = (unsigned * 2) + dp_operation; +pcode_end + +vcvtn: +group NEON +Encoding T1 VFPv3 +fmt VCVTN<c>.S32.F32 <Sd>,<Sm> +fmt VCVTN<c>.S32.F64 <Sd>,<Dm> +fmt VCVTN<c>.U32.F32 <Sd>,<Sm> +fmt VCVTN<c>.U32.F64 <Sd>,<Dm> +extract32 1111,11101,D.1,111,opc1.1,opc2.2,Vd.4,101,sz.1,op.1,1,M.1,0,Vm.4 +pcode_start +round_mode = opc2; +dp_operation = (sz == '1'); unsigned = (op == '0'); +d = UInt(Vd:D); +m = if dp_operation then UInt(M:Vm) else UInt(Vm:M); +fmt_idx = (unsigned * 2) + dp_operation; +pcode_end + +vcvtp: +group NEON +Encoding T1 VFPv3 +fmt VCVTP<c>.S32.F32 <Sd>,<Sm> +fmt VCVTP<c>.S32.F64 <Sd>,<Dm> +fmt VCVTP<c>.U32.F32 <Sd>,<Sm> +fmt VCVTP<c>.U32.F64 <Sd>,<Dm> +extract32 1111,11101,D.1,111,opc1.1,opc2.2,Vd.4,101,sz.1,op.1,1,M.1,0,Vm.4 +pcode_start +round_mode = opc2; +dp_operation = (sz == '1'); unsigned = (op == '0'); +d = UInt(Vd:D); +m = if dp_operation then UInt(M:Vm) else UInt(Vm:M); +fmt_idx = (unsigned * 2) + dp_operation; +pcode_end + +vcvtm: +group NEON +Encoding T1 VFPv3 +fmt VCVTM<c>.S32.F32 <Sd>,<Sm> +fmt VCVTM<c>.S32.F64 <Sd>,<Dm> +fmt VCVTM<c>.U32.F32 <Sd>,<Sm> +fmt VCVTM<c>.U32.F64 <Sd>,<Dm> +extract32 1111,11101,D.1,111,opc1.1,opc2.2,Vd.4,101,sz.1,op.1,1,M.1,0,Vm.4 +pcode_start +round_mode = opc2; +dp_operation = (sz == '1'); unsigned = (op == '0'); +d = UInt(Vd:D); +m = if dp_operation then UInt(M:Vm) else UInt(Vm:M); +fmt_idx = (unsigned * 2) + dp_operation; +pcode_end + +vcvtb: +group NEON +Encoding T1 VFPv3 +fmt VCVTB<c>.F32.F16 <Sd>,<Sm> +fmt VCVTB<c>.F16.F32 <Sd>,<Sm> +fmt VCVTB<c>.F64.F16 <Dd>,<Sm> +fmt VCVTB<c>.F16.F64 <Sd>,<Dm> +fmt VCVTT<c>.F32.F16 <Sd>,<Sm> +fmt VCVTT<c>.F16.F32 <Sd>,<Sm> +fmt VCVTT<c>.F64.F16 <Dd>,<Sm> +fmt VCVTT<c>.F16.F64 <Sd>,<Dm> +extract32 1110,11101,D.1,11001,op.1,Vd.4,101,sz.1,T.1,1,M.1,0,Vm.4 +pcode_start +dp_operation = (sz == '1'); +half_to_single = (op == '0'); +lowbit = if T == '1' then 16 else 0; +m = UInt(Vm:M); d = UInt(Vd:D); +if (dp_operation && !half_to_single) then m = UInt(M:Vm); +if (dp_operation && half_to_single) then d = UInt(D:Vd); +fmt_idx = (T == '1') +fmt_idx = fmt_idx * 4; +fmt_idx = fmt_idx + (sz * 2); +fmt_idx = fmt_idx + (op == '1'); +pcode_end + +vfma: +group NEON +Encoding T2 VFPv2 +fmt VFMA<c>.F32 <Sd>,<Sn>,<Sm> +fmt VFMA<c>.F64 <Dd>,<Dn>,<Dm> +fmt VFMS<c>.F32 <Sd>,<Sn>,<Sm> +fmt VFMS<c>.F64 <Dd>,<Dn>,<Dm> +extract32 1110,11101,D.1,10,Vn.4,Vd.4,101,sz.1,N.1,op.1,M.1,0,Vm.4 +pcode_start +advsimd = FALSE; dp_operation = (sz == '1'); op1_neg = (op == '1'); +d = if dp_operation then UInt(D:Vd) else UInt(Vd:D); +n = if dp_operation then UInt(N:Vn) else UInt(Vn:N); +m = if dp_operation then UInt(M:Vm) else UInt(Vm:M); +fmt_idx = (op == '1'); +fmt_idx = fmt_idx + fmt_idx; +fmt_idx = fmt_idx + (sz == '1'); +pcode_end +Encoding T1 ADVSIMD +fmt VFMA<c>.F32 <Dd>,<Dn>,<Dm> +fmt VFMA<c>.F32 <Qd>,<Qn>,<Qm> +fmt VFMS<c>.F32 <Dd>,<Dn>,<Dm> +fmt VFMS<c>.F32 <Qd>,<Qn>,<Qm> +extract32 111x,xx1x0,D.1,op.1,sz.1,Vn.4,Vd.4,1100,N.1,Q.1,M.1,1,Vm.4 +pcode_start +if (Q == '1' && (Vd<0> == '1' || Vn<0> == '1' || Vm<0> == '1')) then UNDEFINED; +if sz == '1' then UNDEFINED; +advsimd = TRUE; op1_neg = (op == '1'); esize = 32; elements = 2; +d = UInt(D:Vd); n = UInt(N:Vn); m = UInt(M:Vm); +regs = if Q == '0' then 1 else 2; +fmt_idx = (op == '1'); +fmt_idx = fmt_idx + fmt_idx; +fmt_idx = fmt_idx + (Q == '1'); +pcode_end + +vfnma: +group NEON +Encoding T1 VFPv2 +fmt VFNMS<c>.F32 <Sd>,<Sn>,<Sm> +fmt VFNMS<c>.F64 <Dd>,<Dn>,<Dm> +fmt VFNMA<c>.F32 <Sd>,<Sn>,<Sm> +fmt VFNMA<c>.F64 <Dd>,<Dn>,<Dm> +extract32 1110,11101,D.1,01,Vn.4,Vd.4,101,sz.1,N.1,op.1,M.1,0,Vm.4 +pcode_start +op1_neg = (op == '1'); +dp_operation = (sz == '1'); +d = if dp_operation then UInt(D:Vd) else UInt(Vd:D); +n = if dp_operation then UInt(N:Vn) else UInt(Vn:N); +m = if dp_operation then UInt(M:Vm) else UInt(Vm:M); +fmt_idx = op * 2 +fmt_idx = fmt_idx + (sz == '1'); +pcode_end + +vabs: +group NEON +Encoding T2 VFPv2, VFPv3 +fmt VABS<c>.F32 <Sd>,<Sm> +fmt VABS<c>.F64 <Dd>,<Dm> +extract32 1110,11101,D.1,11,0000,Vd.4,101,sz.1,1,1,M.1,0,Vm.4 +pcode_start +advsimd = FALSE; dp_operation = (sz == '1'); +d = if dp_operation then UInt(D:Vd) else UInt(Vd:D); +m = if dp_operation then UInt(M:Vm) else UInt(Vm:M); +fmt_idx = (dp_operation == '1') +pcode_end +Encoding T1 ADVSIMD +fmt VABS<c>.<dt> <Dd>,<Dm> +fmt VABS<c>.<dt> <Qd>,<Qm> +extract32 1111,xx11,1,D.1,11,size.2,01,Vd.4,0,F.1,110,Q.1,M.1,0,Vm.4 +pcode nop; fmt_idx = (Q=='1'); if size == '11' || (F == '1' && size != '10') then UNDEFINED; if Q == '1' && (Vd<0> == '1' || Vm<0> == '1') then UNDEFINED; advsimd = TRUE; floating_point = (F == '1'); esize = 8 << UInt(size); elements = 64 DIV esize; d = UInt(D:Vd); m = UInt(M:Vm); regs = if Q == '0' then 1 else 2; dt = size+F; + +vabd_integer: +group NEON +Encoding T1 ADVSIMD +fmt VABD<c>.<dt> <Dd>,<Dn>,<Dm> +fmt VABD<c>.<dt> <Qd>,<Qn>,<Qm> +extract32 111,U.1,1111,0,D.1,size.2,Vn.4,Vd.4,0111,N.1,Q.1,M.1,0,Vm.4 +pcode_start +if size == '11' then UNDEFINED; +if Q == '1' && (Vd<0> == '1' || Vn<0> == '1' || Vm<0> == '1') then UNDEFINED; +unsigned = (U == '1'); +long_destination = FALSE; +esize = 8 << UInt(size); +elements = 64 DIV esize; +d = UInt(D:Vd); +n = UInt(N:Vn); +m = UInt(M:Vm); +regs = if Q == '0' then 1 else 2; +dt = UInt(U:size); +fmt_idx = Q=='1'; +pcode_end +Encoding T2 ADVSIMD +fmt VABDL<c>.<dt> <Qd>,<Dn>,<Dm> +extract32 111,U.1,1111,1,D.1,size.2,Vn.4,Vd.4,0111,N.1,0,M.1,0,Vm.4 +pcode_start +if size == '11' then SEE "Advanced SIMD Data Proc"; +if Vd<0> == '1' then UNDEFINED; +unsigned = (U == '1'); +long_destination = TRUE; +esize = 8 << UInt(size); +elements = 64 DIV esize; +d = UInt(D:Vd); +n = UInt(N:Vn); +m = UInt(M:Vm); +dt = UInt(U:size); +regs = 1; +pcode_end + +vabd_float: +Encoding T1 ADVSIMD +fmt VABD<c>.F32 <Dd>,<Dn>,<Dm> +fmt VABD<c>.F32 <Qd>,<Qn>,<Qm> +extract32 1111,1111,0,D.1,1,sz.1,Vn.4,Vd.4,1101,N.1,Q.1,M.1,0,Vm.4 +pcode_start +if Q == '1' && (Vd<0> == '1' || Vn<0> == '1' || Vm<0> == '1') then UNDEFINED; +if sz == '1' then UNDEFINED; +esize = 32; +elements = 2; +d = UInt(D:Vd); +n = UInt(N:Vn); +m = UInt(M:Vm); +regs = if Q == '0' then 1 else 2; +fmt_idx = Q == '1'; +pcode_end + +vaba: +group NEON +Encoding T1 ADVSIMD +fmt VABA<c>.<dt> <Dd>,<Dn>,<Dm> +fmt VABA<c>.<dt> <Qd>,<Qn>,<Qm> +extract32 111,U.1,1111,0,D.1,size.2,Vn.4,Vd.4,0111,N.1,Q.1,M.1,1,Vm.4 +pcode_start +if size == '11' then UNDEFINED; +if Q == '1' && (Vd<0> == '1' || Vn<0> == '1' || Vm<0> == '1') then UNDEFINED; +unsigned = (U == '1'); +long_destination = FALSE; +esize = 8 << UInt(size); +elements = 64 DIV esize; +d = UInt(D:Vd); +n = UInt(N:Vn); +m = UInt(M:Vm); +regs = if Q == '0' then 1 else 2; +fmt_idx = (Q == '1'); +dt = UInt(U:size); +pcode_end +Encoding T2 ADVSIMD +fmt VABAL<c>.<dt> <Qd>,<Dn>,<Dm> +extract32 111,U.1,1111,1,D.1,size.2,Vn.4,Vd.4,0101,N.1,0,M.1,0,Vm.4 +pcode_start +if size == '11' then SEE "Advanced SIMD Data Proc"; +if Vd<0> == '1' then UNDEFINED; +unsigned = (U == '1'); +long_destination = TRUE; +esize = 9 << UInt(size); +elements = 64 DIV esize; +d = UInt(D:Vd); +n = UInt(N:Vn); +m = UInt(M:Vm); +regs = 1; +dt = UInt(U:size); +pcode_end + +vacge: +group NEON +Encoding T1 ADVSIMD +fmt VACGE<c>.F32 <Dd>,<Dn>,<Dm> +fmt VACGE<c>.F32 <Qd>,<Qn>,<Qm> +fmt VACGT<c>.F32 <Dd>,<Dn>,<Dm> +fmt VACGT<c>.F32 <Qd>,<Qn>,<Qm> +extract32 1111,1111,0,D.1,op.1,sz.1,Vn.4,Vd.4,1110,N.1,Q.1,M.1,1,Vm.4 +pcode_start +if (Q == '1' && (Vd<0> == '1' || Vn<0> == '1' || Vm<0> == '1')) then UNDEFINED; +if sz == '1' then UNDEFINED; +esize = 32; elements = 2; +d = UInt(D:Vd); n = UInt(N:Vn); m = UInt(M:Vm); regs = if Q == '0' then 1 else 2; +fmt_idx = (op == '1'); +fmt_idx = fmt_idx + fmt_idx; +fmt_idx = fmt_idx + (Q == '1'); +pcode_end + +vadd_integer: +group NEON +Encoding T1 ADVSIMD +fmt VADD<c>.<dt> <Dd>,<Dn>,<Dm> +fmt VADD<c>.<dt> <Qd>,<Qn>,<Qm> +extract32 111x,xx1x,0,D.1,size.2,Vn.4,Vd.4,1000,N.1,Q.1,M.1,0,Vm.4 +pcode_start +if Q == '1' && (Vd<0> == '1' || Vn<0> == '1' || Vm<0> == '1') then UNDEFINED; +esize = 8 << UInt(size); +elements = 64 DIV esize; +d = UInt(D:Vd); +n = UInt(N:Vn); +m = UInt(M:Vm); +regs = if Q == '0' then 1 else 2; +iword = TRUE; +fmt_idx = (Q == '1'); +dt = UInt(size); +pcode_end + +vadd_float: +group NEON +Encoding T1 ADVSIMD +fmt VADD<c>.F32 <Dd>,<Dn>,<Dm> +fmt VADD<c>.F32 <Qd>,<Qn>,<Qm> +extract32 111x,xx11,0,D.1,0,sz.1,Vn.4,Vd.4,1101,N.1,Q.1,M.1,0,Vm.4 +pcode_start +if Q == '1' && (Vd<0> == '1' || Vn<0> == '1' || Vm<0> == '1') then UNDEFINED; +if sz == '1' then UNDEFINED; +advsimd = TRUE; +esize = 32; +elements = 2; +d = UInt(D:Vd); +n = UInt(N:Vn); +m = UInt(M:Vm); +regs = if Q == '0' then 1 else 2; +fmt_idx = (Q == '1'); +pcode_end +Encoding T2 VFPv2, VFPv3 +fmt VADD<c>.F32 <Sd>,<Sn>,<Sm> +fmt VADD<c>.F64 <Dd>,<Dn>,<Dm> +extract32 cond.4,11100,D.1,11,Vn.4,Vd.4,101,sz.1,N.1,0,M.1,0,Vm.4 +pcode_start +advsimd = FALSE; +dp_operation = (sz == '1'); +d = if dp_operation then UInt(D:Vd) else UInt(Vd:D); +n = if dp_operation then UInt(N:Vn) else UInt(Vn:N); +m = if dp_operation then UInt(M:Vm) else UInt(Vm:M); +fmt_idx = (sz == '1'); +pcode_end + +vaddlw: +group NEON +Encoding T1 ADVSIMD +fmt VADDL<c>.<dt> <Qd>,<Dn>,<Dm> +fmt VADDW<c>.<dt> <Qd>,<Qn>,<Dm> +extract32 111,U.1,1111,1,D.1,size.2,Vn.4,Vd.4,000,op.1,N.1,0,M.1,0,Vm.4 +pcode_start +if size == '11' then SEE "Advanced SIMD Data Proc"; +if Vd<0> == '1' || (op == '1' && Vn<0> == '1') then UNDEFINED; +unsigned = (U == '1'); +esize = 8 << UInt(size); +elements = 64 DIV esize; +d = UInt(D:Vd); +n = UInt(N:Vn); +m = UInt(M:Vm); +fmt_idx = (op == '1'); +dt = UInt(U:size); +pcode_end + +vcge_immediate: +group NEON +Encoding T1 ADVSIMD +fmt VCGE<c>.<dt> <Dd>,<Dm>,#0 +fmt VCGE<c>.<dt> <Qd>,<Qm>,#0 +extract32 1111,1111,1,D.1,11,size.2,01,Vd.4,0,F.1,001,Q.1,M.1,0,Vm.4 +pcode_start +if (size == '11' || (F == '1' && size != '10')) then UNDEFINED; +if (Q == '1' && (Vd<0> == '1' || Vm<0> == '1')) then UNDEFINED; +esize = 8 << UInt(size); elements = 64 DIV esize; +d = UInt(D:Vd); m = UInt(M:Vm); regs = if Q == '0' then 1 else 2; +fmt_idx = (Q == '1'); +dt = size; +pcode_end + +vcge_register: +group NEON +Encoding T2 ADVSIMD +fmt VCGE<c>.F32 <Dd>,<Dn>,<Dm> +fmt VCGE<c>.F32 <Qd>,<Qn>,<Qm> +extract32 1111,1111,0,D.1,0,sz.1,Vn.4,Vd.4,1110,N.1,Q.1,M.1,0,Vm.4 +pcode_start +if (Q == '1' && (Vd<0> == '1' || Vn<0> == '1' || Vm<0> == '1')) then UNDEFINED; +if sz == '1' then UNDEFINED; +esize = 32; elements = 2; +d = UInt(D:Vd); n = UInt(N:Vn); m = UInt(M:Vm); regs = if Q == '0' then 1 else 2; +fmt_idx = (Q == '1'); +pcode_end +Encoding T1 ADVSIMD +fmt VCGE<c>.<dt> <Dd>,<Dn>,<Dm> +fmt VCGE<c>.<dt> <Qd>,<Qn>,<Qm> +extract32 111,U.1,1111,0,D.1,size.2,Vn.4,Vd.4,0011,N.1,Q.1,M.1,1,Vm.4 +pcode_start +if (Q == '1' && (Vd<0> == '1' || Vn<0> == '1' || Vm<0> == '1')) then UNDEFINED; +if size == '11' then UNDEFINED; +esize = 8 << UInt(size); elements = 64 DIV esize; +d = UInt(D:Vd); n = UInt(N:Vn); m = UInt(M:Vm); regs = if Q == '0' then 1 else 2; +unsigned = (U == '1'); +fmt_idx = (Q == '1'); +dt = UInt(U:size); +pcode_end + +vcgt_immediate: +group NEON +Encoding T1 ADVSIMD +fmt VCGT<c>.<dt> <Dd>,<Dm>,#0 +fmt VCGT<c>.<dt> <Qd>,<Qm>,#0 +extract32 1111,1111,1,D.1,11,size.2,01,Vd.4,0,F.1,000,Q.1,M.1,0,Vm.4 +pcode_start +if (size == '11' || (F == '1' && size != '10')) then UNDEFINED; +if (Q == '1' && (Vd<0> == '1' || Vm<0> == '1')) then UNDEFINED; +esize = 8 << UInt(size); elements = 64 DIV esize; +d = UInt(D:Vd); m = UInt(M:Vm); regs = if Q == '0' then 1 else 2; +fmt_idx = (Q == '1'); +dt = size + F; +pcode_end + +vcgt_register: +group NEON +Encoding T2 ADVSIMD +fmt VCGT<c>.F32 <Dd>,<Dn>,<Dm> +fmt VCGT<c>.F32 <Qd>,<Qn>,<Qm> +extract32 1111,1111,0,D.1,1,sz.1,Vn.4,Vd.4,1110,N.1,Q.1,M.1,0,Vm.4 +pcode_start +if (Q == '1' && (Vd<0> == '1' || Vn<0> == '1' || Vm<0> == '1')) then UNDEFINED; +if sz == '1' then UNDEFINED; +esize = 32; elements = 2; +d = UInt(D:Vd); n = UInt(N:Vn); m = UInt(M:Vm); regs = if Q == '0' then 1 else 2; +fmt_idx = (Q == '1'); +pcode_end +Encoding T1 ADVSIMD +fmt VCGT<c>.<dt> <Dd>,<Dn>,<Dm> +fmt VCGT<c>.<dt> <Qd>,<Qn>,<Qm> +extract32 111,U.1,1111,0,D.1,size.2,Vn.4,Vd.4,0011,N.1,Q.1,M.1,0,Vm.4 +pcode_start +if (Q == '1' && (Vd<0> == '1' || Vn<0> == '1' || Vm<0> == '1')) then UNDEFINED; +if size == '11' then UNDEFINED; +esize = 8 << UInt(size); elements = 64 DIV esize; +d = UInt(D:Vd); n = UInt(N:Vn); m = UInt(M:Vm); regs = if Q == '0' then 1 else 2; +unsigned = (U == '1'); +fmt_idx = (Q == '1'); +dt = UInt(U:size); +pcode_end + +vcle_immediate: +group NEON +Encoding T1 ADVSIMD +fmt VCLE<c>.<dt> <Dd>,<Dm>,#0 +fmt VCLE<c>.<dt> <Qd>,<Qm>,#0 +extract32 1111,1111,1,D.1,11,size.2,01,Vd.4,0,F.1,011,Q.1,M.1,0,Vm.4 +pcode_start +if (size == '11' || (F == '1' && size != '10')) then UNDEFINED; +if (Q == '1' && (Vd<0> == '1' || Vm<0> == '1')) then UNDEFINED; +esize = 8 << UInt(size); elements = 64 DIV esize; +d = UInt(D:Vd); m = UInt(M:Vm); regs = if Q == '0' then 1 else 2; +fmt_idx = (Q == '1'); +dt = size + F; +pcode_end + +vclt_immediate: +group NEON +Encoding T1 ADVSIMD +fmt VCLT<c>.<dt> <Dd>,<Dm>,#0 +fmt VCLT<c>.<dt> <Qd>,<Qm>,#0 +extract32 1111,1111,1,D.1,11,size.2,01,Vd.4,0,F.1,100,Q.1,M.1,0,Vm.4 +pcode_start +if (size == '11' || (F == '1' && size != '10')) then UNDEFINED; +if (Q == '1' && (Vd<0> == '1' || Vm<0> == '1')) then UNDEFINED; +esize = 8 << UInt(size); elements = 64 DIV esize; +d = UInt(D:Vd); m = UInt(M:Vm); regs = if Q == '0' then 1 else 2; +fmt_idx = (Q == '1'); +dt = size + F; +pcode_end + +vcmp: +group NEON +Encoding T2 ADVSIMD +fmt VCMP<c>.F32 <Sd>,#0 +fmt VCMP<c>.F64 <Dd>,#0 +fmt VCMPE<c>.F32 <Sd>,#0 +fmt VCMPE<c>.F64 <Dd>,#0 +extract32 1110,11101,D.1,11,0101,Vd.4,101,sz.1,E.1,1,(0),0,(0)(0)(0)(0) +pcode_start +dp_operation = (sz == '1'); +d = if dp_operation then UInt(D:Vd) else UInt(Vd:D); +fmt_idx = ((E == '1') * 2) + (sz == '1'); +pcode_end +Encoding T1 ADVSIMD +fmt VCMP<c>.F32 <Sd>,<Sm> +fmt VCMP<c>.F64 <Dd>,<Dm> +fmt VCMPE<c>.F32 <Sd>,<Sm> +fmt VCMPE<c>.F64 <Dd>,<Dm> +extract32 1110,11101,D.1,11,0100,Vd.4,101,sz.1,E.1,1,M.1,0,Vm.4 +pcode_start +dp_operation = (sz == '1'); +d = if dp_operation then UInt(D:Vd) else UInt(Vd:D); +m = if dp_operation then UInt(M:Vm) else UInt(Vm:M); +fmt_idx = ((E == '1') * 2) + (sz == '1'); +pcode_end + +vdiv: +group NEON +Encoding T1 ADVSIMD +fmt VDIV<c>.F32 <Sd>,<Sn>,<Sm> +fmt VDIV<c>.F64 <Dd>,<Dn>,<Dm> +extract32 1110,11101,D.1,00,Vn.4,Vd.4,101,sz.1,N.1,0,M.1,0,Vm.4 +pcode_start +dp_operation = (sz == '1'); +d = if dp_operation then UInt(D:Vd) else UInt(Vd:D); +n = if dp_operation then UInt(N:Vn) else UInt(Vn:N); +m = if dp_operation then UInt(M:Vm) else UInt(Vm:M); +fmt_idx = dp_operation; +pcode_end + +vhadd: +group NEON +Encoding T1 ADVSIMD +fmt VHADD<c>.<dt> <Dd>,<Dn>,<Dm> +fmt VHADD<c>.<dt> <Qd>,<Qn>,<Qm> +extract32 111,U.1,1111,0,D.1,size.2,Vn.4,Vd.4,00,op.1,0,N.1,Q.1,M.1,0,Vm.4 +pcode_start +if Q == '1' && (Vd<0> == '1' || Vn<0> == '1' || Vm<0> == '1') then UNDEFINED; +if size == '11' then UNDEFINED; +unsigned = (U == '1'); +esize = 8 << UInt(size); +elements = 64 DIV esize; +d = UInt(D:Vd); +n = UInt(N:Vn); +m = UInt(M:Vm); +fmt_idx = (Q == '1'); +regs = if Q == '0' then 1 else 2; +dt = UInt(U:size); +pcode_end + +vhsub: +group NEON +Encoding T1 ADVSIMD +fmt VHSUB<c>.<dt> <Dd>,<Dn>,<Dm> +fmt VHSUB<c>.<dt> <Qd>,<Qn>,<Qm> +extract32 111,U.1,1111,0,D.1,size.2,Vn.4,Vd.4,00,op.1,0,N.1,Q.1,M.1,0,Vm.4 +pcode_start +if Q == '1' && (Vd<0> == '1' || Vn<0> == '1' || Vm<0> == '1') then UNDEFINED; +if size == '11' then UNDEFINED; +unsigned = (U == '1'); +esize = 8 << UInt(size); +elements = 64 DIV esize; +d = UInt(D:Vd); +n = UInt(N:Vn); +m = UInt(M:Vm); +fmt_idx = (Q == '1'); +regs = if Q == '0' then 1 else 2; +dt = UInt(U:size); +pcode_end + +vrhadd: +group NEON +Encoding T1 ADVSIMD +fmt VRHADD<c>.<dt> <Dd>,<Dn>,<Dm> +fmt VRHADD<c>.<dt> <Qd>,<Qn>,<Qm> +extract32 111,U.1,1111,0,D.1,size.2,Vn.4,Vd.4,0001,N.1,Q.1,M.1,0,Vm.4 +pcode_start +if Q == '1' && (Vd<0> == '1' || Vn<0> == '1' || Vm<0> == '1') then UNDEFINED; +if size == '11' then UNDEFINED; +unsigned = (U == '1'); +esize = 8 << UInt(size); +elements = 64 DIV esize; +d = UInt(D:Vd); +n = UInt(N:Vn); +m = UInt(M:Vm); +fmt_idx = (Q == '1'); +regs = if Q == '0' then 1 else 2; +dt = UInt(U:size); +pcode_end + +vqadd: +group NEON +Encoding T1 ADVSIMD +fmt VQADD<c>.<dt> <Dd>,<Dn>,<Dm> +fmt VQADD<c>.<dt> <Qd>,<Qn>,<Qm> +extract32 111,U.1,1111,0,D.1,size.2,Vn.4,Vd.4,0000,N.1,Q.1,M.1,1,Vm.4 +pcode_start +if Q == '1' && (Vd<0> == '1' || Vn<0> == '1' || Vm<0> == '1') then UNDEFINED; +unsigned = (U == '1'); +esize = 8 << UInt(size); +elements = 64 DIV esize; +d = UInt(D:Vd); +n = UInt(N:Vn); +m = UInt(M:Vm); +fmt_idx = (Q == '1'); +regs = if Q == '0' then 1 else 2; +dt = UInt(U:size); +pcode_end + +vaddhn: +group NEON +Encoding T1 ADVSIMD +fmt VADDHN<c>.<dt> <Dd>,<Qn>,<Qm> +extract32 1110,xx1x,1,D.1,size.2,Vn.4,Vd.4,0100,N.1,0,M.1,0,Vm.4 +pcode_start +if size == '11' then SEE "Advanced SIMD Data Proc"; +if Vn<0> == '1' || Vm<0> == '1' then UNDEFINED; +esize = 8 << UInt(size); +elements = 64 DIV esize; +d = UInt(D:Vd); +n = UInt(N:Vn); +m = UInt(M:Vm); +iword = TRUE; +dt = UInt(size+1); +pcode_end + +vceq_immediate: +group NEON +Encoding T1 ADVSIMD +fmt VCEQ<c>.<dt> <Dd>,<Dm>,#0 +fmt VCEQ<c>.<dt> <Qd>,<Qm>,#0 +extract32 1111,1111,1,D.1,11,size.2,01,Vd.4,0,F.1,010,Q.1,M.1,0,Vm.4 +pcode_start +if (size == '11' || (F == '1' && size != '10')) then UNDEFINED; +if (Q == '1' && (Vd<0> == '1' || Vm<0> == '1')) then UNDEFINED; +esize = 8 << UInt(size); elements = 64 DIV esize; +d = UInt(D:Vd); m = UInt(M:Vm); regs = if Q == '0' then 1 else 2; +fmt_idx = (Q == '1'); +iword = TRUE; +dt = 4; +if F == '0' then dt = size; +pcode_end + +vceq_register: +group NEON +Encoding T2 ADVSIMD +fmt VCEQ<c>.F32 <Dd>,<Dn>,<Dm> +fmt VCEQ<c>.F32 <Qd>,<Qn>,<Qm> +extract32 1110,0010,0,D.1,0,sz.1,Vn.4,Vd.4,1110,N.1,Q.1,M.1,0,Vm.4 +pcode_start +if (Q == '1' && (Vd<0> == '1' || Vn<0> == '1' || Vm<0> == '1')) then UNDEFINED; +if sz == '1' then UNDEFINED; +esize = 32; elements = 2; +d = UInt(D:Vd); n = UInt(N:Vn); m = UInt(M:Vm); regs = if Q == '0' then 1 else 2; +fmt_idx = (Q == '1'); +pcode_end +Encoding T1 ADVSIMD +fmt VCEQ<c>.<dt> <Dd>,<Dn>,<Dm> +fmt VCEQ<c>.<dt> <Qd>,<Qn>,<Qm> +extract32 1111,1111,0,D.1,size.2,Vn.4,Vd.4,1000,N.1,Q.1,M.1,1,Vm.4 +pcode_start +if (Q == '1' && (Vd<0> == '1' || Vn<0> == '1' || Vm<0> == '1')) then UNDEFINED; +if size == '11' then UNDEFINED; +esize = 8 << UInt(size); elements = 64 DIV esize; +d = UInt(D:Vd); n = UInt(N:Vn); m = UInt(M:Vm); regs = if Q == '0' then 1 else 2; +fmt_idx = (Q == '1'); +dt = UInt(size); +pcode_end + +vraddhn: +group NEON +Encoding T1 ADVSIMD +fmt VRADDHN<c>.<dt> <Dd>,<Qn>,<Qm> +extract32 1111,xx11,1,D.1,size.2,Vn.4,Vd.4,0100,N.1,0,M.1,0,Vm.4 +pcode_start +if size == '11' then SEE "Advanced SIMD Data Proc"; +if Vn<0> == '1' || Vm<0> == '1' then UNDEFINED; +esize = 8 << UInt(size); +elements = 64 DIV esize; +d = UInt(D:Vd); +n = UInt(N:Vn); +m = UInt(M:Vm); +iword = TRUE; +dt = UInt(size+1); +pcode_end + +vmla_integer: +group NEON +Encoding T4 ADVSIMD +fmt VMLSL<c>.S<size> <Qd>,<Dn>,<Dm> +fmt VMLSL<c>.U<size> <Qd>,<Dn>,<Dm> +fmt VMLSL<c>.I<size> <Qd>,<Dn>,<Dm> +extract32 111,U.1,1111,1,D.1,size.2,Vn.4,Vd.4,10,1,0,N.1,0,M.1,0,Vm.4 +pcode_start +if size == '11' then SEE advanced_simd_data_proc; +if Vd<0> == '1' then UNDEFINED; +long_destination = TRUE; unsigned = (U == '1'); +esize = 8 << UInt(size); elements = 64 DIV esize; +d = UInt(D:Vd); n = UInt(N:Vn); m = UInt(M:Vm); regs = 1; +fmt_idx = (U == '1'); +pcode_end +Encoding T3 ADVSIMD +fmt VMLS<c>.<dt> <Dd>,<Dn>,<Dm> +fmt VMLS<c>.<dt> <Qd>,<Qn>,<Qm> +extract32 111,1,1111,0,D.1,size.2,Vn.4,Vd.4,1001,N.1,Q.1,M.1,0,Vm.4 +pcode_start +if size == '11' then UNDEFINED; +if (Q == '1' && (Vd<0> == '1' || Vn<0> == '1' || Vm<0> == '1')) then UNDEFINED; +long_destination = FALSE; +iword = TRUE; +esize = 8 << UInt(size); elements = 64 DIV esize; +d = UInt(D:Vd); n = UInt(N:Vn); m = UInt(M:Vm); regs = if Q == '0' then 1 else 2; +fmt_idx = (Q == '1'); +dt = size; +pcode_end +Encoding T2 ADVSIMD +fmt VMLAL<c>.S<size> <Qd>,<Dn>,<Dm> +fmt VMLAL<c>.U<size> <Qd>,<Dn>,<Dm> +fmt VMLAL<c>.I<size> <Qd>,<Dn>,<Dm> +extract32 111,U.1,1111,1,D.1,size.2,Vn.4,Vd.4,10,0,0,N.1,0,M.1,0,Vm.4 +pcode_start +if size == '11' then SEE advanced_simd_data_proc; +if Vd<0> == '1' then UNDEFINED; +long_destination = TRUE; unsigned = (U == '1'); +esize = 8 << UInt(size); elements = 64 DIV esize; +d = UInt(D:Vd); n = UInt(N:Vn); m = UInt(M:Vm); regs = 1; +fmt_idx = (U == '1'); +pcode_end +Encoding T1 ADVSIMD +fmt VMLA<c>.<dt> <Dd>,<Dn>,<Dm> +fmt VMLA<c>.<dt> <Qd>,<Qn>,<Qm> +extract32 111,0,1111,0,D.1,size.2,Vn.4,Vd.4,1001,N.1,Q.1,M.1,0,Vm.4 +pcode_start +if size == '11' then UNDEFINED; +if (Q == '1' && (Vd<0> == '1' || Vn<0> == '1' || Vm<0> == '1')) then UNDEFINED; +long_destination = FALSE; +iword = TRUE; +esize = 8 << UInt(size); elements = 64 DIV esize; +d = UInt(D:Vd); n = UInt(N:Vn); m = UInt(M:Vm); regs = if Q == '0' then 1 else 2; +fmt_idx = (Q == '1'); +dt = size; +pcode_end + +vmla_float: +group NEON +Encoding T2 VFPv2, VFPv3 +fmt VMLA<c>.F32 <Sd>,<Sn>,<Sm> +fmt VMLA<c>.F64 <Dd>,<Dn>,<Dm> +fmt VMLS<c>.F32 <Sd>,<Sn>,<Sm> +fmt VMLS<c>.F64 <Dd>,<Dn>,<Dm> +extract32 1110,11100,D.1,00,Vn.4,Vd.4,101,sz.1,N.1,op.1,M.1,0,Vm.4 +pcode_start +advsimd = FALSE; dp_operation = (sz == '1'); add = (op == '0'); +d = if dp_operation then UInt(D:Vd) else UInt(Vd:D); +n = if dp_operation then UInt(N:Vn) else UInt(Vn:N); +m = if dp_operation then UInt(M:Vm) else UInt(Vm:M); +fmt_idx = (op * 2) + dp_operation; +dt = size; +pcode_end +Encoding T1 ADVSIMD +fmt VMLA<c>.F32 <Dd>,<Dn>,<Dm> +fmt VMLA<c>.F32 <Qd>,<Qn>,<Qm> +fmt VMLS<c>.F32 <Dd>,<Dn>,<Dm> +fmt VMLS<c>.F32 <Qd>,<Qn>,<Qm> +extract32 1110,1111,0,D.1,op.1,sz.1,Vn.4,Vd.4,1101,N.1,Q.1,M.1,1,Vm.4 +pcode_start +if (Q == '1' && (Vd<0> == '1' || Vn<0> == '1' || Vm<0> == '1')) then UNDEFINED; +if sz == '1' then UNDEFINED; +advsimd = TRUE; esize = 32; elements = 2; +d = UInt(D:Vd); n = UInt(N:Vn); m = UInt(M:Vm); regs = if Q == '0' then 1 else 2; +fmt_idx = (op * 2) + (Q == '1'); +dt = size; +pcode_end + +vmla_scalar: +group NEON +Encoding T2 ADVSIMD +fmt VMLAL<c>.<type><size> <Qd>,<Dn>,<Dm[x]> +fmt VMLSL<c>.<type><size> <Qd>,<Dn>,<Dm[x]> +extract32 111,U.1,1111,1,D.1,size.2,Vn.4,Vd.4,0,op.1,10,N.1,1,M.1,0,Vm.4 +pcode_start +if size == '11' then SEE advanced_simd_data_proc; +if (size == '00' || Vd<0> == '1') then UNDEFINED; +unsigned = (U == '1'); +floating_point = FALSE; long_destination = TRUE; +d = UInt(D:Vd); n = UInt(N:Vn); regs = 1; +if size == '01' then esize = 16; +if size == '10' then esize = 32; +elements = 64 DIV esize; +if esize == 16 then m = UInt(Vm) - ((UInt(Vm) >> 3) * 8); +if esize == 32 then m = UInt(Vm); +x = UInt(M:Vm); +if esize == 16 then x = x >> 3; +if esize == 32 then x = UInt(M); +fmt_idx = (op == '1'); +type = U + 2; +size = size - 1; +pcode_end +Encoding T1 ADVSIMD +fmt VMLA<c>.I<size> <Dd>,<Dn>,<Dm[x]> +fmt VMLA<c>.I<size> <Qd>,<Qn>,<Dm[x]> +fmt VMLS<c>.I<size> <Dd>,<Dn>,<Dm[x]> +fmt VMLS<c>.I<size> <Qd>,<Qn>,<Dm[x]> +fmt VMLA<c>.F<size> <Dd>,<Dn>,<Dm[x]> +fmt VMLA<c>.F<size> <Qd>,<Qn>,<Dm[x]> +fmt VMLS<c>.F<size> <Dd>,<Dn>,<Dm[x]> +fmt VMLS<c>.F<size> <Qd>,<Qn>,<Dm[x]> +extract32 111,Q.1,1111,1,D.1,size.2,Vn.4,Vd.4,0,op.1,0,F.1,N.1,1,M.1,0,Vm.4 +pcode_start +if size == '11' then SEE advanced_simd_data_proc; +if (size == '00' || (F == '1' && size == '01')) then UNDEFINED; +if (Q == '1' && (Vd<0> == '1' || Vn<0> == '1')) then UNDEFINED; +unsigned = FALSE; +floating_point = (F == '1'); long_destination = FALSE; +d = UInt(D:Vd); n = UInt(N:Vn); regs = if Q == '0' then 1 else 2; +if size == '01' then esize = 16; +if size == '10' then esize = 32; +elements = 64 DIV esize; +if esize == 16 then m = UInt(Vm) - ((UInt(Vm) >> 3) * 8); +if esize == 32 then m = UInt(Vm); +x = UInt(M:Vm); +if esize == 16 then x = x >> 3; +if esize == 32 then x = UInt(M); +fmt_idx = (F == '1'); +fmt_idx = fmt_idx * 4; +fmt_idx = fmt_idx + (op * 2); +fmt_idx = fmt_idx + (Q == '1'); +pcode_end + +vqdmlal: +group NEON +Encoding T2 ADVSIMD +fmt VQDMLAL<c>.<dt> <Qd>,<Dn>,<Dm[x]> +fmt VQDMLSL<c>.<dt> <Qd>,<Dn>,<Dm[x]> +extract32 111x,xx1x,1,D.1,size.2,Vn.4,Vd.4,0,op.1,11,N.1,1,M.1,0,Vm.4 +pcode_start +if size == '11' then SEE advanced_simd_data_proc; +if (size == '00' || Vd<0> == '1') then UNDEFINED; +d = UInt(D:Vd); n = UInt(N:Vn); +if size == '01' then esize = 16; +if size == '10' then esize = 32; +elements = 64 DIV esize; +x = UInt(M:Vm); +if esize == 16 then x = x >> 3; +if esize == 32 then x = UInt(M); +m = UInt(Vm); +if esize == 16 then m = m - ((UInt(Vm) >> 3) * 8); +fmt_idx = (op == '1'); +dt = size; +pcode_end +Encoding T1 ADVSIMD +fmt VQDMLAL<c>.<dt> <Qd>,<Dn>,<Dm> +fmt VQDMLSL<c>.<dt> <Qd>,<Dn>,<Dm> +extract32 111x,xx1x,1,D.1,size.2,Vn.4,Vd.4,10,op.1,1,N.1,0,M.1,0,Vm.4 +pcode_start +if size == '11' then SEE advanced_simd_data_proc; +if (size == '00' || Vd<0> == '1') then UNDEFINED; +d = UInt(D:Vd); n = UInt(N:Vn); m = UInt(M:Vm); +esize = 8 << UInt(size); elements = 64 DIV esize; +fmt_idx = (op == '1'); +dt = size; +pcode_end + +vmul_integer: +group NEON +Encoding T3 ADVSIMD +fmt VMUL<c>.P8 <Dd>,<Dn>,<Dm> +fmt VMUL<c>.P8 <Qd>,<Qn>,<Qm> +extract32 111,1,1111,0,D.1,size.2,Vn.4,Vd.4,1001,N.1,Q.1,M.1,1,Vm.4 +pcode_start +if (size == '11' || (op == '1' && size != '00')) then UNDEFINED; +if (Q == '1' && (Vd<0> == '1' || Vn<0> == '1' || Vm<0> == '1')) then UNDEFINED; +long_destination = FALSE; +esize = 8 << UInt(size); elements = 64 DIV esize; +d = UInt(D:Vd); n = UInt(N:Vn); m = UInt(M:Vm); regs = if Q == '0' then 1 else 2; +fmt_idx = (Q == '1'); +dt = size; +pcode_end +Encoding T2 ADVSIMD +fmt VMULL<c>.<dt> <Qd>,<Dn>,<Dm> +fmt VMULL<c>.P8 <Qd>,<Dn>,<Dm> +extract32 111,U.1,1111,1,D.1,size.2,Vn.4,Vd.4,11,op.1,0,N.1,0,M.1,0,Vm.4 +pcode_start +if size == '11' then SEE advanced_simd_data_proc; +if (op == '1' && (U != '0' || size != '00')) then UNDEFINED; +if Vd<0> == '1' then UNDEFINED; +long_destination = TRUE; unsigned = (U == '1'); +esize = 8 << UInt(size); elements = 64 DIV esize; +d = UInt(D:Vd); n = UInt(N:Vn); m = UInt(M:Vm); regs = 1; +fmt_idx = (op == '1'); +dt = UInt(U:size); +pcode_end +Encoding T1 ADVSIMD +fmt VMUL<c>.<dt> <Dd>,<Dn>,<Dm> +fmt VMUL<c>.<dt> <Qd>,<Qn>,<Qm> +extract32 111,op.1,1111,0,D.1,size.2,Vn.4,Vd.4,1001,N.1,Q.1,M.1,1,Vm.4 +pcode_start +if (size == '11' || (op == '1' && size != '00')) then UNDEFINED; +if (Q == '1' && (Vd<0> == '1' || Vn<0> == '1' || Vm<0> == '1')) then UNDEFINED; +long_destination = FALSE; +esize = 8 << UInt(size); elements = 64 DIV esize; +d = UInt(D:Vd); n = UInt(N:Vn); m = UInt(M:Vm); regs = if Q == '0' then 1 else 2; +iword = TRUE +fmt_idx = (Q == '1'); +dt = size; +pcode_end + +vmul_float: +group NEON +Encoding T2 ADVSIMD +fmt VMUL<c>.F32 <Sd>,<Sn>,<Sm> +fmt VMUL<c>.F64 <Dd>,<Dn>,<Dm> +extract32 1110,11100,D.1,10,Vn.4,Vd.4,101,sz.1,N.1,0,M.1,0,Vm.4 +pcode_start +advsimd = FALSE; dp_operation = (sz == '1'); +d = if dp_operation then UInt(D:Vd) else UInt(Vd:D); +n = if dp_operation then UInt(N:Vn) else UInt(Vn:N); +m = if dp_operation then UInt(M:Vm) else UInt(Vm:M); +fmt_idx = dp_operation; +pcode_end +Encoding T1 ADVSIMD +fmt VMUL<c>.F32 <Dd>,<Dn>,<Dm> +fmt VMUL<c>.F32 <Qd>,<Qn>,<Qm> +extract32 1111,xx11,0,D.1,0,sz.1,Vn.4,Vd.4,1101,N.1,Q.1,M.1,1,Vm.4 +pcode_start +if (Q == '1' && (Vd<0> == '1' || Vn<0> == '1' || Vm<0> == '1')) then UNDEFINED; +if sz == '1' then UNDEFINED; +advsimd = TRUE; esize = 32; elements = 2; +d = UInt(D:Vd); n = UInt(N:Vn); m = UInt(M:Vm); regs = if Q == '0' then 1 else 2; +fmt_idx = (Q == '1'); +pcode_end + +vmul_scalar: +group NEON +Encoding T2 ADVSIMD +fmt VMULL<c>.<dt> <Qd>,<Dn>,<Dm[x]> +extract32 111,U.1,1111,1,D.1,size.2,Vn.4,Vd.4,1010,N.1,1,M.1,0,Vm.4 +pcode_start +if size == '11' then SEE advanced_simd_data_proc; +if size == '00' || Vd<0> == '1' then UNDEFINED; +unsigned = (U == '1'); long_destination = TRUE; floating_point = FALSE; +d = UInt(D:Vd); n = UInt(N:Vn); regs = 1; +if size == '01' then esize = 16; +if size == '10' then esize = 32; +elements = 64 DIV esize; +m = UInt(Vm<2:0>); +x = (M * 2) + Vm<3>; +if esize == 32 then m = UInt(Vm); +if esize == 32 then x = UInt(M); +dt = size + (U * 4); +pcode_end +Encoding T1 ADVSIMD +fmt VMUL<c>.<dt> <Dd>,<Dn>,<Dm[x]> +fmt VMUL<c>.<dt> <Qd>,<Qn>,<Dm[x]> +extract32 111,Q.1,1111,1,D.1,size.2,Vn.4,Vd.4,100,F.1,N.1,1,M.1,0,Vm.4 +pcode_start +if size == '11' then SEE advanced_simd_data_proc; +if (size == '00' || (F == '1' && size == '01')) then UNDEFINED; +if (Q == '1' && (Vd<0> == '1' || Vn<0> == '1')) then UNDEFINED; +floating_point = (F == '1'); long_destination = FALSE; +d = UInt(D:Vd); n = UInt(N:Vn); regs = if Q == '0' then 1 else 2; +if size == '01' then esize = 16; +if size == '10' then esize = 32; +elements = 64 DIV esize; +x = UInt(M:Vm); +if esize == 16 then x = x >> 3; +if esize == 32 then x = UInt(M); +if esize == 16 then m = Vm - ((Vm >> 3)*8); +if esize == 32 then m = UInt(Vm); +iword = TRUE; +fmt_idx = (Q == '1'); +dt = if F == '1' then 4 else size; +pcode_end + +vneg: +group NEON +Encoding T2 VFPv2, VFPv3 +fmt VNEG<c>.F32 <Sd>,<Sm> +fmt VNEG<c>.F64 <Dd>,<Dm> +extract32 1110,11101,D.1,11,0001,Vd.4,101,sz.1,0,1,M.1,0,Vm.4 +pcode_start +advsimd = FALSE; dp_operation = (sz == '1'); +d = if dp_operation then UInt(D:Vd) else UInt(Vd:D); +m = if dp_operation then UInt(M:Vm) else UInt(Vm:M); +fmt_idx = (sz == '1'); +pcode_end +Encoding T1 ADVSIMD +fmt VNEG<c>.<dt> <Dd>,<Dm> +fmt VNEG<c>.<dt> <Qd>,<Qm> +extract32 1111,xx11,1,D.1,11,size.2,01,Vd.4,0,F.1,111,Q.1,M.1,0,Vm.4 +pcode_start +if (size == '11' || (F == '1' && size != '10')) then UNDEFINED; +if (Q == '1' && (Vd<0> == '1' || Vm<0> == '1')) then UNDEFINED; +advsimd = TRUE; floating_point = (F == '1'); +esize = 8 << UInt(size); elements = 64 DIV esize; +d = UInt(D:Vd); m = UInt(M:Vm); regs = if Q == '0' then 1 else 2; +fmt_idx = (Q == '1'); +dt = size; +dt = dt + UInt(F); +pcode_end + +vpmax_integer: +group NEON +Encoding T1 ADVSIMD +fmt VPMAX<c>.<dt> <Dd>,<Dn>,<Dm> +fmt VPMIN<c>.<dt> <Dd>,<Dn>,<Dm> +extract32 111,U.1,1111,0,D.1,size.2,Vn.4,Vd.4,1010,N.1,Q.1,M.1,op.1,Vm.4 +pcode_start +if (size == '11' || Q == '1') then UNDEFINED; +unsigned = (U == '1'); +esize = 8 << UInt(size); elements = 64 DIV esize; +d = UInt(D:Vd); n = UInt(N:Vn); m = UInt(M:Vm); +fmt_idx = (op == '1'); +dt = UInt(U:size); +pcode_end + +vpmax_float: +group NEON +Encoding T1 ADVSIMD +fmt VPMAX<c>.F32 <Dd>,<Dn>,<Dm> +fmt VPMIN<c>.F32 <Dd>,<Dn>,<Dm> +extract32 1111,xx11,0,D.1,op.1,sz.1,Vn.4,Vd.4,1111,N.1,Q.1,M.1,0,Vm.4 +pcode_start +if (sz == '1' || Q == '1') then UNDEFINED; +esize = 32; elements = 2; +d = UInt(D:Vd); n = UInt(N:Vn); m = UInt(M:Vm); +fmt_idx = (op == '1'); +pcode_end + +vext: +group NEON +Encoding T1 ADVSIMD +fmt VEXT<c>.8 <Dd>,<Dn>,<Dm>,#<imm> +fmt VEXT<c>.8 <Qd>,<Qn>,<Qm>,#<imm> +extract32 111x,xx1x,1,D.1,11,Vn.4,Vd.4,imm4.4,N.1,Q.1,M.1,0,Vm.4 +pcode_start +if (Q == '1' && (Vd<0> == '1' || Vn<0> == '1' || Vm<0> == '1')) then UNDEFINED; +if (Q == '0' && ((imm4 >> 3) == '1')) then UNDEFINED; +quadword_operation = (Q == '1'); position = 8 * UInt(imm4); +d = UInt(D:Vd); n = UInt(N:Vn); m = UInt(M:Vm); +imm = imm4; +fmt_idx = (Q == '1'); +pcode_end + +vswp: +group NEON +Encoding T1 ADVSIMD +fmt VSWP<c> <Dd>,<Dm> +fmt VSWP<c> <Qd>,<Qm> +extract32 1111,1111,1,D.1,11,size.2,10,Vd.4,0,0000,Q.1,M.1,0,Vm.4 +pcode_start +if size != '00' then UNDEFINED; +if (Q == '1' && (Vd<0> == '1' || Vm<0> == '1')) then UNDEFINED; +d = UInt(D:Vd); m = UInt(M:Vm); regs = if Q == '0' then 1 else 2; +fmt_idx = (Q == '1') +pcode_end + +vtrn: +group NEON +Encoding T1 ADVSIMD +fmt VTRN<c>.<size> <Dd>,<Dm> +fmt VTRN<c>.<size> <Qd>,<Qm> +extract32 1111,xx11,1,D.1,11,size.2,10,Vd.4,0000,1,Q.1,M.1,0,Vm.4 +pcode_start +if size == '11' then UNDEFINED; +if (Q == '1' && (Vd<0> == '1' || Vm<0> == '1')) then UNDEFINED; +esize = 8 << UInt(size); elements = 64 DIV esize; +d = UInt(D:Vd); m = UInt(M:Vm); regs = if Q == '0' then 1 else 2; +fmt_idx = (Q == '1'); +pcode_end + +vuzp: +group NEON +Encoding T1 ADVSIMD +fmt VUZP<c>.<size> <Dd>,<Dm> +fmt VUZP<c>.<size> <Qd>,<Qm> +extract32 1111,xx11,1,D.1,11,size.2,10,Vd.4,0001,0,Q.1,M.1,0,Vm.4 +pcode_start +if (size == '11' || (Q == '0' && size == '10')) then UNDEFINED; +if (Q == '1' && (Vd<0> == '1' || Vm<0> == '1')) then UNDEFINED; +quadword_operation = (Q == '1'); esize = 8 << UInt(size); +d = UInt(D:Vd); m = UInt(M:Vm); +fmt_idx = (Q == '1'); +pcode_end + +vzip: +group NEON +Encoding T1 ADVSIMD +fmt VZIP<c>.<size> <Dd>,<Dm> +fmt VZIP<c>.<size> <Qd>,<Qm> +extract32 1111,xx11,1,D.1,11,size.2,10,Vd.4,0001,1,Q.1,M.1,0,Vm.4 +pcode_start +if (size == '11' || (Q == '0' && size == '10')) then UNDEFINED; +if (Q == '1' && (Vd<0> == '1' || Vm<0> == '1')) then UNDEFINED; +quadword_operation = (Q == '1'); esize = 8 << UInt(size); +d = UInt(D:Vd); m = UInt(M:Vm); +fmt_idx = (Q == '1'); +pcode_end + +vrecpe: +group NEON +Encoding T2 ADVSIMD +fmt VRECPE<c>.F32 <Dd>,<Dm> +fmt VRECPE<c>.F32 <Qd>,<Qm> +extract32 1111,xx11,1,D.1,11,size.2,11,Vd.4,010,1,0,Q.1,M.1,0,Vm.4 +pcode_start +if (Q == '1' && (Vd<0> == '1' || Vm<0> == '1')) then UNDEFINED; +if size != '10' then UNDEFINED; +esize = 32; elements = 2; +d = UInt(D:Vd); m = UInt(M:Vm); regs = if Q == '0' then 1 else 2; +fmt_idx = (Q == '1'); +pcode_end +Encoding T1 ADVSIMD +fmt VRECPE<c>.U32 <Dd>,<Dm> +fmt VRECPE<c>.U32 <Qd>,<Qm> +extract32 1111,xx11,1,D.1,11,size.2,11,Vd.4,010,0,0,Q.1,M.1,0,Vm.4 +pcode_start +if (Q == '1' && (Vd<0> == '1' || Vm<0> == '1')) then UNDEFINED; +if size != '10' then UNDEFINED; +esize = 32; elements = 2; +d = UInt(D:Vd); m = UInt(M:Vm); regs = if Q == '0' then 1 else 2; +fmt_idx = (Q == '1'); +pcode_end + +vrsqrte: +group NEON +Encoding T2 ADVSIMD +fmt VRSQRTE<c>.F32 <Dd>,<Dm> +fmt VRSQRTE<c>.F32 <Qd>,<Qm> +extract32 1111,xx11,1,D.1,11,size.2,11,Vd.4,010,1,1,Q.1,M.1,0,Vm.4 +pcode_start +if (Q == '1' && (Vd<0> == '1' || Vm<0> == '1')) then UNDEFINED; +if size != '10' then UNDEFINED; +esize = 32; elements = 2; +d = UInt(D:Vd); m = UInt(M:Vm); regs = if Q == '0' then 1 else 2; +fmt_idx = (Q == '1'); +pcode_end +Encoding T1 ADVSIMD +fmt VRSQRTE<c>.U32 <Dd>,<Dm> +fmt VRSQRTE<c>.U32 <Qd>,<Qm> +extract32 1111,xx11,1,D.1,11,size.2,11,Vd.4,010,0,1,Q.1,M.1,0,Vm.4 +pcode_start +if (Q == '1' && (Vd<0> == '1' || Vm<0> == '1')) then UNDEFINED; +if size != '10' then UNDEFINED; +esize = 32; elements = 2; +d = UInt(D:Vd); m = UInt(M:Vm); regs = if Q == '0' then 1 else 2; +fmt_idx = (Q == '1'); +pcode_end + +vrsqrts: +group NEON +Encoding T1 ADVSIMD +fmt VRSQRTS<c>.F32 <Dd>,<Dn>,<Dm> +fmt VRSQRTS<c>.F32 <Qd>,<Qn>,<Qm> +extract32 111x,xx1x,0,D.1,1,sz.1,Vn.4,Vd.4,1111,N.1,Q.1,M.1,1,Vm.4 +pcode_start +if (Q == '1' && (Vd<0> == '1' || Vn<0> == '1' || Vm<0> == '1')) then UNDEFINED; +if sz == '1' then UNDEFINED; +esize = 32; elements = 2; +d = UInt(D:Vd); n = UInt(N:Vn); m = UInt(M:Vm); regs = if Q == '0' then 1 else 2; +fmt_idx = (Q == '1'); +pcode_end + +vcvt_float_fixed: +group NEON +Encoding T2 ADVSIMD +fmt VCVT<c>.F32.<dt> <Sd>,<Sd>,#<imm> +fmt VCVT<c>.F64.<dt> <Dd>,<Dd>,#<imm> +fmt VCVT<c>.<dt> <Sd>,<Sd>,#<imm> +fmt VCVT<c>.<dt> <Dd>,<Dd>,#<imm> +extract32 1110,1110,1,D.1,11,1,op.1,1,U.1,Vd.4,101,sf.1,sx.1,1,i.1,0,imm4.4 +pcode_start +to_fixed = (op == '1'); dp_operation = (sf == '1'); unsigned = (U == '1'); +size = (sx * 16) + 16; +imm = size - UInt(imm4:i); +d = if dp_operation then UInt(D:Vd) else UInt(Vd:D); +if size < UInt(imm4:i) then UNPREDICTABLE; +fmt_idx = (op * 2) + sf; +if fmt_idx > 1 then dt_suffix = sf; +dt = 1 + sx + (U * 4); +pcode_end +Encoding T1 ADVSIMD +fmt VCVT<c>.<dt> <Dd>,<Dm>,#<fbits> +fmt VCVT<c>.<dt> <Qd>,<Qm>,#<fbits> +extract32 111,U.1,1111,1,D.1,imm6.6,Vd.4,111,op.1,0,Q.1,M.1,1,Vm.4 +pcode_start +//if imm6 IN "000xxx" then SEE advsimd_one_reg_mod_imm; +//if imm6 IN "0xxxxx" then UNDEFINED; +if Q == '1' && (Vd<0> == '1' || Vm<0> == '1') then UNDEFINED; +to_fixed = (op == '1'); unsigned = (U == '1'); +if to_fixed == TRUE then round_zero = TRUE else round_nearest = TRUE; +esize = 32; fbits = 64 - UInt(imm6); elements = 2; +d = UInt(D:Vd); m = UInt(M:Vm); regs = if Q == '0' then 1 else 2; +td = TRUE +fmt_idx = (Q == '1') +dt = UInt(op:U) +pcode_end + +vcvt_half_single: +group NEON +Encoding T1 ADVSIMD +fmt VCVT<c>.F16.F32 <Dd>,<Qm> +fmt VCVT<c>.F32.F16 <Qd>,<Dm> +extract32 1111,xx11,1,D.1,11,size.2,10,Vd.4,011,op.1,0,0,M.1,0,Vm.4 +pcode_start +half_to_single = (op == '1'); +if size != '01' then UNDEFINED; +if (half_to_single == TRUE && Vd<0> == '1') then UNDEFINED; +if (half_to_single == FALSE && Vm<0> == '1') then UNDEFINED; +esize = 16; +elements = 4; +m = UInt(M:Vm); +d = UInt(D:Vd); +td = TRUE; +fmt_idx = (op == '1'); +pcode_end + +vcvt_double_single: +group NEON +Encoding T1 VFPv2, VFPv3 +fmt VCVT<c>.F64.F32 <Dd>,<Sm> +fmt VCVT<c>.F32.F64 <Sd>,<Dm> +extract32 1110,1110,1,D.1,11,011,1,Vd.4,101,sz.1,1,1,M.1,0,Vm.4 +pcode_start +double_to_single = (sz == '1'); +d = if double_to_single then UInt(Vd:D) else UInt(D:Vd); +m = if double_to_single then UInt(M:Vm) else UInt(Vm:M); +fmt_idx = double_to_single; +pcode_end + +vcvt_float_int: +group NEON +Encoding T2 ADVSIMD +fmt VCVT<c>.F32.<dt> <Sd>,<Sm> +fmt VCVT<c>.F64.<dt> <Dd>,<Sm> +fmt VCVT<c>.U32.F32 <Sd>,<Sm> +fmt VCVT<c>.U32.F64 <Sd>,<Dm> +fmt VCVT<c>.S32.F32 <Sd>,<Sm> +fmt VCVT<c>.S32.F64 <Sd>,<Dm> +fmt VCVTR<c>.U32.F32 <Sd>,<Sm> +fmt VCVTR<c>.U32.F64 <Sd>,<Dm> +fmt VCVTR<c>.S32.F32 <Sd>,<Sm> +fmt VCVTR<c>.S32.F64 <Sd>,<Dm> +extract32 1110,11101,D.1,11,1,opc1.1,opc2.1,opc3.1,Vd.4,101,sz.1,op.1,1,M.1,0,Vm.4 +pcode_start +to_integer = (opc1 == '1'); dp_operation = (sz == 1); +unsigned = (op == '0'); +m = UInt(Vm:M); +d = if dp_operation then UInt(D:Vd) else UInt(Vd:D); +if (to_integer) then unsigned = (opc1 == '0'); +if (to_integer) then d = UInt(Vd:D); +if (to_integer) then m = if dp_operation then UInt(M:Vm) else UInt(Vm:M); +fmt_idx = ((op == '0') * 4) + (opc3 * 2) + sz + 2; +if (opc1 == '0') then fmt_idx = sz; +dt = ((op == '0') * 4) + 2; +pcode_end +Encoding T1 ADVSIMD +fmt VCVT<c>.<dt> <Dd>,<Dm> +fmt VCVT<c>.<dt> <Qd>,<Qm> +extract32 1111,xx11,1,D.1,11,size.2,11,Vd.4,0,11,op.2,Q.1,M.1,0,Vm.4 +pcode_start +if Q == '1' && (Vd<0> == '1' || Vm<0> == '1') then UNDEFINED; +if size != '10' then UNDEFINED; +to_integer = (op == '10' || op == '11'); +unsigned = (op == '01' || op == '11'); +esize = 32; elements = 2; +round_nearest = (to_integer == FALSE) +round_zero = to_integer +d = UInt(D:Vd); m = UInt(M:Vm); regs = if Q == '0' then 1 else 2; +td = TRUE; +fmt_idx = (Q == '1') +dt = UInt(op) +pcode_end + +vtbl: +group NEON +Encoding T1 ADVSIMD +fmt VTBL<c>.8 <Dd>,<list>,<Dm> +fmt VTBX<c>.8 <Dd>,<list>,<Dm> +extract32 1111,xx11,1,D.1,11,Vn.4,Vd.4,10,len.2,N.1,op.1,M.1,0,Vm.4 +pcode_start +is_vtbl = (op == '0'); length = UInt(len)+1; +d = UInt(D:Vd); n = UInt(N:Vn); m = UInt(M:Vm); +if (n + length > 32) then UNPREDICTABLE; +fmt_idx = (op == '1'); +pcode_end + +vdup_register: +group NEON +Encoding T1 ADVSIMD +fmt VDUP<c>.<size> <Dd>,<Rt> +fmt VDUP<c>.<size> <Qd>,<Rt> +extract32 1110,1110,1,B.1,Q.1,0,Vd.4,Rt.4,1011,D.1,0,E.1,1,(0)(0)(0)(0) +pcode_start +if (Q == '1' && Vd<0> == '1') then UNDEFINED; +d = UInt(D:Vd); +t = UInt(Rt); +regs = if Q == '0' then 1 else 2; +if (B == '0' && E == '0') then esize = 32; +if (B == '0' && E == '1') then esize = 16; +if (B == '1' && E == '0') then esize = 8; +if (B == '1' && E == '1') then UNDEFINED; +if (B == '0' && E == '0') then size = 2; +if (B == '0' && E == '1') then size = 1; +if (B == '1' && E == '0') then size = 0; +elements = 64 DIV esize; +fmt_idx = (Q == '1'); +pcode_end + +vdup_scalar: +group NEON +Encoding T1 ADVSIMD +fmt VDUP<c>.<size> <Dd>,<Dm[x]> +fmt VDUP<c>.<size> <Qd>,<Dm[x]> +extract32 1111,xx11,1,D.1,11,imm4.4,Vd.4,110,0,0,Q.1,M.1,0,Vm.4 +pcode_start +if (imm4 == '0000' || imm4 == '1000') then UNDEFINED; +if (Q == '1' && Vd<0> == '1') then UNDEFINED; +esize = 8; +if (imm4 == '1110' || imm4 == '1010' || imm4 == '0110' || imm4 == '0010') then esize = 16; +if (imm4 == '1100' || imm4 == '0100') then esize = 32; +d = UInt(D:Vd); m = UInt(M:Vm); regs = if Q == '0' then 1 else 2; +if esize == 8 then size = 0; +if esize == 16 then size = 1; +if esize == 32 then size = 2; +if esize == 8 then x = UInt(imm4) >> 1; +if esize == 16 then x = UInt(imm4) >> 2; +if esize == 32 then x = UInt(imm4) >> 3; +fmt_idx = (Q == '1'); +pcode_end + +advanced_simd_elem_struct_load_store: +extract32 1111,1001,A.1,x,L.1,0,xxxx,xxxx,B.4,xxxxxxxx +on A,B,L +// A7-20 (L==0) +0,0010,0 vst1_mult_1elem +0,011x,0 vst1_mult_1elem +0,1010,0 vst1_mult_1elem +0,0011,0 vst2_mult_2elem +0,100x,0 vst2_mult_2elem +0,010x,0 vst3_mult_3elem +0,000x,0 vst4_mult_4elem +1,0x00,0 vst1_single_1elem +1,1000,0 vst1_single_1elem +1,0x01,0 vst2_single_2elem +1,1001,0 vst2_single_2elem +1,0x10,0 vst3_single_3elem +1,1010,0 vst3_single_3elem +1,0x11,0 vst4_single_4elem +1,1011,0 vst4_single_4elem +// A7-21 (L==1) +0,0010,1 vld1_mult_1elem +0,011x,1 vld1_mult_1elem +0,1010,1 vld1_mult_1elem +0,0011,1 vld2_mult_2elem +0,100x,1 vld2_mult_2elem +0,010x,1 vld3_mult_3elem +0,000x,1 vld4_mult_4elem +1,0x00,1 vld1_single_1elem_1lane +1,1000,1 vld1_single_1elem_1lane +1,1100,1 vld1_single_1elem_nlanes +1,0x01,1 vld2_single_2elem_1lane +1,1001,1 vld2_single_2elem_1lane +1,1101,1 vld2_single_2elem_nlanes +1,0x10,1 vld3_single_3elem_1lane +1,1010,1 vld3_single_3elem_1lane +1,1110,1 vld3_single_3elem_nlanes +1,0x11,1 vld4_single_4elem_1lane +1,1011,1 vld4_single_4elem_1lane +1,1111,1 vld4_single_4elem_nlanes + +vst1_mult_1elem: +group NEON +Encoding T1 ADVSIMD +fmt VST1<c>.<size> <registers>,[<Rn>,#<align>] +fmt VST1<c>.<size> <registers>,[<Rn>,#<align>]! +fmt VST1<c>.<size> <registers>,[<Rn>,#<align>],<Rm> +extract32 1111,1001,0,D.1,00,Rn.4,Vd.4,type.4,size.2,align.2,Rm.4 +pcode_start +case type of + when '0111' + regs = 1; if align<1> == '1' then UNDEFINED; + when '1010' + regs = 2; if align == '11' then UNDEFINED; + when '0110' + regs = 3; if align<1> == '1' then UNDEFINED; + when '0010' + regs = 4; +alignment = if align == '00' then 1 else 64 << UInt(align-1); +ebytes = 1 << UInt(size); esize = 8 * ebytes; elements = 8 / ebytes; +d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm); +wback = (m != 15); register_index = (m != 15 && m != 13); +if d+regs > 32 then UNPREDICTABLE; +pcode_end + +vst2_mult_2elem: +group NEON +Encoding T1 ADVSIMD +fmt VST2<c>.<size> <registers>,[<Rn>,#<align>] +fmt VST2<c>.<size> <registers>,[<Rn>,#<align>]! +fmt VST2<c>.<size> <registers>,[<Rn>,#<align>],<Rm> +extract32 1111,1001,0,D.1,00,Rn.4,Vd.4,type.4,size.2,align.2,Rm.4 +pcode_start +if size == '11' then UNDEFINED; +case type of + when '1000' + regs = 2; inc = 1; if align == '11' then UNDEFINED; + when '1001' + regs = 2; inc = 2; if align == '11' then UNDEFINED; + when '0011' + regs = 4; inc = 1; +alignment = if align == '00' then 1 else 64 << UInt(align-1); +ebytes = 1 << UInt(size); esize = 8*ebytes; elements = 8 / ebytes; +d = UInt(D:Vd); d2 = d + inc; n = UInt(Rn); m = UInt(Rm); +wback = (m != 15); register_index = (m != 15 && m != 13); +if d2+regs > 32 then UNPREDICTABLE; +pcode_end + +vst3_mult_3elem: +group NEON +Encoding T1 ADVSIMD +fmt VST3<c>.<size> <registers>,[<Rn>,#<align>] +fmt VST3<c>.<size> <registers>,[<Rn>,#<align>]! +fmt VST3<c>.<size> <registers>,[<Rn>,#<align>],<Rm> +extract32 1111,1001,0,D.1,00,Rn.4,Vd.4,type.4,size.2,align.2,Rm.4 +pcode_start +if (size == '11' || align<1>) == '1' then UNDEFINED; +case type of + when '0100' + inc = 1; + when '0101' + inc = 2; +alignment = if align<0> == '0' then 1 else 64; +ebytes = 1 << UInt(size); esize = 8 * ebytes; elements = 8 / ebytes; +d = UInt(D:Vd); d2 = d + inc; d3 = d2 + inc; n = UInt(Rn); m = UInt(Rm); +wback = (m != 15); register_index = (m != 15 && m != 13); +if d3 > 31 then UNPREDICTABLE; +pcode_end + +vst4_mult_4elem: +group NEON +Encoding T1 ADVSIMD +fmt VST4<c>.<size> <registers>,[<Rn>,#<align>] +fmt VST4<c>.<size> <registers>,[<Rn>,#<align>]! +fmt VST4<c>.<size> <registers>,[<Rn>,#<align>],<Rm> +extract32 1111,1001,0,D.1,00,Rn.4,Vd.4,type.4,size.2,align.2,Rm.4 +pcode_start +if size == '11' then UNDEFINED; +case type of + when '0000' + inc = 1; + when '0001' + inc = 2; +alignment = if align == '00' then 1 else 64 << UInt(align-1) +ebytes = 1 << UInt(size); esize = 8 * ebytes; elements = 8/ebytes; +d = UInt(D:Vd); d2 = d + inc; d3 = d2 + inc; d4 = d3 + inc; n = UInt(Rn); m = UInt(Rm); +wback = (m != 15); register_index = (m != 15 && m != 13); +if d4 > 31 then UNPREDICTABLE; +pcode_end + +vst1_single_1elem: +group NEON +Encoding T1 ADVSIMD +fmt VST1<c>.<size> <registers_indexed>,[<Rn>,#<align>] +fmt VST1<c>.<size> <registers_indexed>,[<Rn>,#<align>]! +fmt VST1<c>.<size> <registers_indexed>,[<Rn>,#<align>],<Rm> +extract32 1111,1001,1,D.1,00,Rn.4,Vd.4,size.2,00,index_align.4,Rm.4 +pcode_start +if size=='11' then UNDEFINED; +case size of + when '00' + if index_align<0> != '0' then UNDEFINED; + ebytes = 1; esize = 8; index = UInt(index_align<3:1>); alignment = 1; + when '01' + if index_align<1> != '0' then UNDEFINED; + ebytes = 2; esize = 16; index = UInt(index_align<3:2>); + alignment = if index_align<0> == '0' then 1 else 16; + when '10' + if index_align<2> != '0' then UNDEFINED; + if index_align<1:0> != '00' && index_align<1:0> != '11' then UNDEFINED; + ebytes = 4; esize = 32; index = UInt(index_align<3>); + alignment = if index_align<1:0> == '00' then 1 else 32; +d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm); +wback = (m != 15); register_index = (m != 15 && m != 13); +length = 1; +pcode_end + +vst2_single_2elem: +group NEON +Encoding T1 ADVSIMD +fmt VST2<c>.<size> <registers_indexed>,[<Rn>,#<align>] +fmt VST2<c>.<size> <registers_indexed>,[<Rn>,#<align>]! +fmt VST2<c>.<size> <registers_indexed>,[<Rn>,#<align>],<Rm> +extract32 1111,1001,1,D.1,00,Rn.4,Vd.4,size.2,01,index_align.4,Rm.4 +pcode_start +if size == '11' then UNDEFINED; +case size of + when '00' + ebytes = 1; esize = 8; index = UInt(index_align<3:1>); inc = 1; + alignment = if index_align<0> == '0' then 1 else 16; + when '01' + ebytes = 2; esize = 16; index = UInt(index_align<3:2>); + inc = if index_align<1> == '0' then 1 else 2; + alignment = if index_align<0> == '0' then 1 else 32; + when '10' + if index_align<1> != '0' then UNDEFINED; + ebytes = 4; esize = 32; index = UInt(index_align<3>); + inc = if index_align<2> == '0' then 1 else 2; + alignment = if index_align<0> == '0' then 1 else 64; +d = UInt(D:Vd); d2 = d + inc; n = UInt(Rn); m = UInt(Rm); +wback = (m != 15); register_index = (m != 15 && m != 13); +if d2 > 31 then UNPREDICTABLE; +length = 2; +pcode_end + +vst3_single_3elem: +group NEON +Encoding T1 ADVSIMD +fmt VST3<c>.<size> <registers_indexed>,[<Rn>,#<align>] +fmt VST3<c>.<size> <registers_indexed>,[<Rn>,#<align>]! +fmt VST3<c>.<size> <registers_indexed>,[<Rn>,#<align>],<Rm> +extract32 1111,1001,1,D.1,00,Rn.4,Vd.4,size.2,10,index_align.4,Rm.4 +pcode_start +if size == '11' then UNDEFINED; +case size of + when '00' + if index_align<0> != '0' then UNDEFINED; + ebytes = 1; esize = 8; index = UInt(index_align<3:1>); inc = 1; + when '01' + if index_align<0> != '0' then UNDEFINED; + ebytes = 2; esize = 16; index = UInt(index_align<3:2>); + inc = if index_align<1> == '0' then 1 else 2; + when '10' + if index_align<1:0> != '00' then UNDEFINED; + ebytes = 4; esize = 32; index = UInt(index_align<3>); + inc = if index_align<2> == '0' then 1 else 2; +d = UInt(D:Vd); d2 = d + inc; d3 = d2 + inc; n = UInt(Rn); m = UInt(Rm); +wback = (m != 15); register_index = (m != 15 && m != 13); +if d3 > 31 then UNPREDICTABLE; +alignment = 1 +length = 3; +pcode_end + +vst4_single_4elem: +group NEON +Encoding T1 ADVSIMD +fmt VST4<c>.<size> <registers_indexed>,[<Rn>,#<align>] +fmt VST4<c>.<size> <registers_indexed>,[<Rn>,#<align>]! +fmt VST4<c>.<size> <registers_indexed>,[<Rn>,#<align>],<Rm> +extract32 1111,1001,1,D.1,00,Rn.4,Vd.4,size.2,11,index_align.4,Rm.4 +pcode_start +if size == '11' then UNDEFINED; +case size of + when '00' + ebytes = 1; esize = 8; index = UInt(index_align<3:1>); inc = 1; + alignment = if index_align<0> == '0' then 1 else 32; + when '01' + ebytes = 2; esize = 16; index = UInt(index_align<3:2>); + inc = if index_align<1> == '0' then 1 else 2; + alignment = if index_align<0> == '0' then 1 else 64; + when '10' + if index_align<1:0> == '11' then UNDEFINED; + ebytes = 4; esize = 32; index = UInt(index_align<3>); + inc = if index_align<2> == '0' then 1 else 2; + alignment = if index_align<1:0> == '00' then 1 else 64 << UInt(index_align<1:0> - 1); +d = UInt(D:Vd); d2 = d + inc; d3 = d2 + inc; d4 = d3 + inc; n = UInt(Rn); m = UInt(Rm); +wback = (m != 15); register_index = (m != 15 && m != 13); +if d4 > 31 then UNPREDICTABLE +length = 4; +pcode_end + +vld1_mult_1elem: +group NEON +Encoding T1 ADVSIMD +fmt VLD1<c>.<size> <registers>,[<Rn>,#<align>] +fmt VLD1<c>.<size> <registers>,[<Rn>,#<align>]! +fmt VLD1<c>.<size> <registers>,[<Rn>,#<align>],<Rm> +extract32 1111,1001,0,D.1,10,Rn.4,Vd.4,type.4,size.2,align.2,Rm.4 +pcode_start +regs_n = 0; +if type == '0111' then regs_n = 1; +if type == '0111' && (align==2 || align==3) then UNDEFINED; +if type == '1010' then regs_n = 2; +if type == '1010' && (align==3) then UNDEFINED; +if type == '0110' then regs_n = 3; +if type == '0110' && (align==2 || align==3) then UNDEFINED; +if type == '0010' then regs_n = 4; +if align == 0 then alignment = 1; +if align == 1 then alignment = 64; +if align == 2 then alignment = 128; +if align == 3 then alignment = 256; +d = D:Vd; +if regs_n > 1 then d2 = d+1; +if regs_n > 2 then d3 = d2+1; +if regs_n > 3 then d4 = d3+1; +wback = 0; +if Rm != 0 then wback = 1; +register_index = 0; +if (m != 15 && m != 13) then wback = 1; +if d+regs_n > 32 then UNPREDICTABLE; +pcode_end + +vld2_mult_2elem: +group NEON +Encoding T1 ADVSIMD +fmt VLD2<c>.<size> <registers>,[<Rn>,#<align>] +fmt VLD2<c>.<size> <registers>,[<Rn>,#<align>]! +fmt VLD2<c>.<size> <registers>,[<Rn>,#<align>],<Rm> +extract32 1111,1001,0,D.1,10,Rn.4,Vd.4,type.4,size.2,align.2,Rm.4 +pcode_start +if size == '11' then UNDEFINED; +case type of + when '1000' + regs = 2; inc = 1; if align == '11' then UNDEFINED; + when '1001' + regs = 2; inc = 2; if align == '11' then UNDEFINED; + when '0011' + regs = 4; inc = 1; +alignment = if align == '00' then 1 else 64 << (align-1); +ebytes = 1 << UInt(size); esize = 8 * ebytes; elements = 8 / ebytes; +d = UInt(D:Vd); d2 = d + inc; n = UInt(Rn); m = UInt(Rm); +wback = (m != 15); register_index = (m != 15 && m != 13); +if d2 + regs > 32 then UNPREDICTABLE; +pcode_end + +vld3_mult_3elem: +group NEON +Encoding T1 ADVSIMD +fmt VLD3<c>.<size> <registers>,[<Rn>,#<align>] +fmt VLD3<c>.<size> <registers>,[<Rn>,#<align>]! +fmt VLD3<c>.<size> <registers>,[<Rn>,#<align>],<Rm> +extract32 1111,1001,0,D.1,10,Rn.4,Vd.4,type.4,size.2,align.2,Rm.4 +pcode_start +if size=='11' || align==2 || align==3 then UNDEFINED; +regs_n = 3; +if type=='0100' then inc=1; +if type=='0101' then inc=2; +alignment=64; +if align==0 || align==2 then alignment=1; +d = D:Vd; +d2 = d + inc; +d3 = d2 + inc; +wback = (Rm != 15); +pcode_end + +vld4_mult_4elem: +group NEON +Encoding T1 ADVSIMD +fmt VLD4<c>.<size> <registers>,[<Rn>,#<align>] +fmt VLD4<c>.<size> <registers>,[<Rn>,#<align>]! +fmt VLD4<c>.<size> <registers>,[<Rn>,#<align>],<Rm> +extract32 1111,1001,0,D.1,10,Rn.4,Vd.4,type.4,size.2,align.2,Rm.4 +pcode_start +regs_n = 4; +if size == '11' then UNDEFINED; +inc = 0; +if type == '0000' then inc = 1; +if type == '0001' then inc = 2; +if align == 0 then alignment = 1; +if align == 1 then alignment = 64; +if align == 2 then alignment = 128; +if align == 3 then alignment = 256; +d = D:Vd; +d2 = d + inc; +d3 = d2 + inc; +d4 = d3 + inc; +wback = (Rm != 15); +fmt_idx = 2; +if Rm == '1111' then fmt_idx = 0; +if Rm == '1101' then fmt_idx = 1; +pcode_end + +// A8.6.308 +vld1_single_1elem_1lane: +group NEON +Encoding T1 ADVSIMD +fmt VLD1<c>.<size> <registers_indexed>,[<Rn>,#<align>] +fmt VLD1<c>.<size> <registers_indexed>,[<Rn>,#<align>]! +fmt VLD1<c>.<size> <registers_indexed>,[<Rn>,#<align>],<Rm> +extract32 1111,1001,1,D.1,10,Rn.4,Vd.4,size.2,00,index_align.4,Rm.4 +pcode_start +if size == '11' then UNDEFINED; +case size of + when '00' + if index_align<0> != '0' then UNDEFINED; + ebytes = 1; esize = 8; index = UInt(index_align<3:1>); alignment = 1; + when '01' + if index_align<1> != '0' then UNDEFINED; + ebytes = 2; esize = 16; index = UInt(index_align<3:2>); + alignment = if index_align<0> == '0' then 1 else 16; + when '10' + if index_align<2> != '0' then UNDEFINED; + if index_align<1:0> != '00' && index_align<1:0> != '11' then UNDEFINED; + ebytes = 4; esize = 32; index = UInt(index_align<3>); + alignment = if index_align<1:0> == '00' then 1 else 32; +d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm); +wback = (m != 15); register_index = (m != 15 && m != 13); +length = 1; +pcode_end + +vld1_single_1elem_nlanes: +group NEON +Encoding T1 ADVSIMD +fmt VLD1<c>.<size> <registers[]>,[<Rn>,#<align>] +fmt VLD1<c>.<size> <registers[]>,[<Rn>,#<align>]! +fmt VLD1<c>.<size> <registers[]>,[<Rn>,#<align>],<Rm> +extract32 1111,1001,1,D.1,10,Rn.4,Vd.4,11,00,size.2,T.1,a.1,Rm.4 +pcode_start +if size == '11' || (size == '00' && a == '1') then UNDEFINED; +ebytes = 1 << UInt(size); elements = 8 / ebytes; regs = if T == '0' then 1 else 2; +if a == '0' then alignment = 1 +alignment = if a == '0' then 1 else 16*size; +d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm); +wback = (m != 15); register_index = (m != 15 && m != 13); +if d+regs > 32 then UNPREDICTABLE; +pcode_end + +vld2_single_2elem_1lane: +group NEON +Encoding T1 ADVSIMD +fmt VLD2<c>.<size> <registers_indexed>,[<Rn>,#<align>] +fmt VLD2<c>.<size> <registers_indexed>,[<Rn>,#<align>]! +fmt VLD2<c>.<size> <registers_indexed>,[<Rn>,#<align>],<Rm> +extract32 1111,1001,1,D.1,10,Rn.4,Vd.4,size.2,01,index_align.4,Rm.4 +pcode_start +if size == '11' then UNDEFINED +case size of + when '00' + ebytes = 1; esize = 8; index = UInt(index_align<3:1>); inc = 1; + alignment = if index_align<0> == '0' then 1 else 16; + when '01' + ebytes = 2; esize = 16; index = UInt(index_align<3:2>); + inc = if index_align<1> == '0' then 1 else 2; + alignment = if index_align<0> == '0' then 1 else 32; + when '10' + if index_align<1> != '0' then UNDEFINED; + ebytes = 4; esize = 32; index = UInt(index_align<3>); + inc = if index_align<2> == '0' then 1 else 2; + alignment = if index_align<0> == '0' then 1 else 64; +d = UInt(D:Vd); d2 = d + inc; n = UInt(Rn); m = UInt(Rm); +wback = (m != 15); register_index = (m != 15 && m != 13); +if d2 > 31 then UNPREDICTABLE; +length = 2; +pcode_end + +vld2_single_2elem_nlanes: +group NEON +Encoding T1 ADVSIMD +fmt VLD2<c>.<size> <registers[]>,[<Rn>,#<align>] +fmt VLD2<c>.<size> <registers[]>,[<Rn>,#<align>]! +fmt VLD2<c>.<size> <registers[]>,[<Rn>,#<align>],<Rm> +extract32 1111,1001,1,D.1,10,Rn.4,Vd.4,11,01,size.2,T.1,a.1,Rm.4 +pcode_start +if size == '11' then UNDEFINED; +ebytes = 1 << UInt(size); elements = 8 / ebytes; +alignment = if a == '0' then 1 else 16<<size; +inc = if T == '0' then 1 else 2; +d = UInt(D:Vd); d2 = d + inc; n = UInt(Rn); m = UInt(Rm); +wback = (m != 15); register_index = (m != 15 && m != 13); +if d2 > 31 then UNPREDICTABLE; +pcode_end + +vld3_single_3elem_1lane: +group NEON +Encoding T1 ADVSIMD +fmt VLD3<c>.<size> <registers_indexed>,[<Rn>,#<align>] +fmt VLD3<c>.<size> <registers_indexed>,[<Rn>,#<align>]! +fmt VLD3<c>.<size> <registers_indexed>,[<Rn>,#<align>],<Rm> +extract32 1111,1001,1,D.1,10,Rn.4,Vd.4,size.2,10,index_align.4,Rm.4 +pcode_start +if size == '11' then UNDEFINED +case size of + when '00' + if index_align<0> != '0' then UNDEFINED; + ebytes = 1; esize = 8; index = UInt(index_align<3:1>); inc = 1; + when '01' + if index_align<0> != '0' then UNDEFINED; + ebytes = 2; esize = 16; index = UInt(index_align<3:2>); + inc = if index_align<1> == '0' then 1 else 2; + when '10' + if index_align<1:0> != '00' then UNDEFINED; + ebytes = 4; esize = 32; index = UInt(index_align<3>); + inc = if index_align<2> == '0' then 1 else 2; +d = UInt(D:Vd); d2 = d + inc; d3 = d2 + inc; n = UInt(Rn); m = UInt(Rm); +wback = (m != 15); register_index = (m != 15 && m != 13); +if d3 > 31 then UNPREDICTABLE; +alignment = 1; +length = 3; +pcode_end + +vld3_single_3elem_nlanes: +group NEON +Encoding T1 ADVSIMD +fmt VLD3<c>.<size> <registers[]>,[<Rn>,#<align>] +fmt VLD3<c>.<size> <registers[]>,[<Rn>,#<align>]! +fmt VLD3<c>.<size> <registers[]>,[<Rn>,#<align>],<Rm> +extract32 1111,1001,1,D.1,10,Rn.4,Vd.4,11,10,size.2,T.1,a.1,Rm.4 +pcode_start +if size == '11' || a == '1' then UNDEFINED; +ebytes = 1 << UInt(size); elements = 8 / ebytes; +inc = if T == '0' then 1 else 2; +d = UInt(D:Vd); d2 = d + inc; d3 = d2 + inc; n = UInt(Rn); +wback = (m != 15); register_index = (m != 15 && m != 13); +if d3 > 31 then UNPREDICTABLE; +alignment = 1; +pcode_end + +vld4_single_4elem_1lane: +group NEON +Encoding T1 ADVSIMD +fmt VLD4<c>.<size> <registers_indexed>,[<Rn>,#<align>] +fmt VLD4<c>.<size> <registers_indexed>,[<Rn>,#<align>]! +fmt VLD4<c>.<size> <registers_indexed>,[<Rn>,#<align>],<Rm> +extract32 1111,1001,1,D.1,10,Rn.4,Vd.4,size.2,11,index_align.4,Rm.4 +pcode_start +if size == '11' then UNDEFINED +case size of + when '00' + ebytes = 1; esize = 8; index = UInt(index_align<3:1>); inc = 1; + alignment = if index_align<0> == '0' then 1 else 32; + when '01' + ebytes = 2; esize = 16; index = UInt(index_align<3:2>); + inc = if index_align<1> == '0' then 1 else 2; + alignment = if index_align<0> == '0' then 1 else 64; + when '10' + if index_align<1:0> == '11' then UNDEFINED; + ebytes = 4; esize = 32; index = UInt(index_align<3>); + inc = if index_align<2> == '0' then 1 else 2; + alignment = if index_align<1:0> == '00' then 1 else 64 << UInt(index_align<1:0> - 1); +d = UInt(D:Vd); d2 = d + inc; d3 = d2 + inc; d4 = d3 + inc; n = UInt(Rn); m = UInt(Rm); +wback = (m != 15); register_index = (m != 15 && m != 13); +if d4 > 31 then UNPREDICTABLE; +length = 4; +pcode_end + +// this is fucked up ... VLD4.<size> is VLD4.32 for both size.4==0b10 or 0b11 for 16-byte alignment +// the alignment field is all kinds of fucked up too ... just fuck this instruction +// - Andrew +// I've seen some shit, this isn't so bad now +// - Josh +vld4_single_4elem_nlanes: +group NEON +Encoding T1 ADVSIMD +fmt VLD4<c>.<size> <registers[]>,[<Rn>,#<align>] +fmt VLD4<c>.<size> <registers[]>,[<Rn>,#<align>]! +fmt VLD4<c>.<size> <registers[]>,[<Rn>,#<align>],<Rm> +extract32 1111,1001,1,D.1,10,Rn.4,Vd.4,11,11,size.2,T.1,a.1,Rm.4 +pcode_start +if size == '11' && a == '0' then UNDEFINED; +ebytes = if size == '11' then 4 else 1 << UInt(size) +elements = if size == '11' then 2 else 8 / ebytes; +alignment = 1; +if size == 3 then alignment = 128; +if size == 2 && a == 1 then alignment = 64; +if size < 2 && a == 1 then alignment = 32*ebytes +inc = if T == '0' then 1 else 2; +d = UInt(D:Vd); d2 = d + inc; d3 = d2 + inc; d4 = d3 + inc; n = UInt(Rn); m = UInt(Rm); +wback = (m != 15); register_index = (m != 15 && m != 13); +if size == 3 then size = 2; +if d4 > 31 then UNPREDICTABLE; +pcode_end + +vldm: +group NEON +Encoding T2 VFPv2, VFPv3 +fmt VLDMDB<c> <Rn>{!},<registers> +fmt VLDMIA<c> <Rn>{!},<registers> +extract32 1110,110,P.1,U.1,D.1,W.1,1,Rn.4,Vd.4,1010,imm8.8 +pcode_start +if (P == '0' && U == '0' && W == '0') then SEE xfer_64_core_ext_regs; +if (P == '0' && U == '1' && W == '1' && Rn == '1101') then SEE vpop; +if (P == '1' && W == '0') then SEE vldr; +if (P == U && W == '1') then UNDEFINED; +single_regs = TRUE; add = (U == '1'); wback = (W == '1'); d = UInt(Vd:D); n = UInt(Rn); +imm32 = ZeroExtend(imm8:'00', 32); regs = UInt(imm8); +if (n == 15 && wback) then UNPREDICTABLE; +if (regs == 0 || (d+regs) > 32) then UNPREDICTABLE; +fmt_idx = U; +pcode_end +Encoding T1 ADVSIMD +fmt VLDMDB<c> <Rn>{!},<registers> +fmt VLDMIA<c> <Rn>{!},<registers> +extract32 1110,110,P.1,U.1,D.1,W.1,1,Rn.4,Vd.4,1011,imm8.8 +pcode_start +if (P == '0' && U == '0' && W == '0') then SEE xfer_64_core_ext_regs; +if (P == '0' && U == '1' && W == '1' && Rn == '1101') then SEE vpop; +if (P == '1' && W == '0') then SEE vldr; +if (imm8<0> == '1') then UNDEFINED; +if (P == U && W == '1') then UNDEFINED; +single_regs = FALSE; add = (U == '1'); wback = (W == '1'); +d = UInt(D:Vd); n = UInt(Rn); imm32 = ZeroExtend(imm8:'00', 32); +regs = UInt(imm8) DIV 2; +if n == 15 then UNPREDICTABLE; +if (regs == 0 || regs > 16 || (d+regs) > 32) then UNPREDICTABLE; +if (d+regs) > 16 then UNPREDICTABLE; +fmt_idx = U; +pcode_end + +vstm: +group NEON +Encoding T2 VFPv2, VFPv3 +fmt VSTMDB<c> <Rn>{!},<registers> +fmt VSTMIA<c> <Rn>{!},<registers> +extract32 1110,110,P.1,U.1,D.1,W.1,0,Rn.4,Vd.4,1010,imm8.8 +pcode_start +if P == '0' && U == '0' && W == '0' then SEE xfer_64_core_ext_regs; +if P == '1' && U == '0' && W == '1' && Rn == '1101' then SEE vpush; +if P == '1' && W == '0' then SEE vstr; +if P == U && W == '1' then UNDEFINED; +single_regs = TRUE; add = (U == '1'); wback = (W == '1'); d = UInt(Vd:D); n = UInt(Rn); +imm32 = ZeroExtend(imm8:'00', 32); regs = UInt(imm8); +if n == 15 && (wback) then UNPREDICTABLE; +if regs == 0 || (d+regs) > 32 then UNPREDICTABLE; +fmt_idx = U; +pcode_end +Encoding T1 ADVSIMD +fmt VSTMDB<c> <Rn>{!},<registers> +fmt VSTMIA<c> <Rn>{!},<registers> +extract32 1110,110,P.1,U.1,D.1,W.1,0,Rn.4,Vd.4,1011,imm8.8 +pcode_start +if P == '0' && U == '0' && W == '0' then SEE xfer_64_core_ext_regs; +if P == '1' && U == '0' && W == '1' && Rn == '1101' then SEE vpush; +if P == '1' && W == '0' then SEE vstr; +if P == U && W == '1' then UNDEFINED; +single_regs = FALSE; add = (U == '1'); wback = (W == '1'); +d = UInt(D:Vd); n = UInt(Rn); imm32 = ZeroExtend(imm8:'00', 32); +regs = UInt(imm8) DIV 2; +if n == 15 && (wback) then UNPREDICTABLE; +if (regs == 0 || regs > 16 || (d+regs) > 32) then UNPREDICTABLE; +if (d+regs) > 16 then UNPREDICTABLE; +fmt_idx = U; +pcode_end + +vldr: +group NEON +Encoding T2 VFPv2, VFPv3 +fmt VLDR<c> <Sd>,[<Rn>{,#<+/-><imm>}] +fmt VLDR<c> <Sd>,<label> +extract32 1110,1101,U.1,D.1,0,1,Rn.4,Vd.4,1010,imm8.8 +pcode_start +add = (U == '1'); imm32 = ZeroExtend(imm8:'00', 32); +d = UInt(Vd:D); n = UInt(Rn); +imm = imm32 +fmt_idx = 0; +pcode_end +Encoding T1 VFPv2, VFPv3 +fmt VLDR<c> <Dd>,[<Rn>{,#<+/-><imm>}] +fmt VLDR<c> <Dd>,<label> +extract32 1110,1101,U.1,D.1,0,1,Rn.4,Vd.4,1011,imm8.8 +pcode_start +add = (U == '1'); imm32 = ZeroExtend(imm8:'00', 32); +d = UInt(D:Vd); n = UInt(Rn); +imm = imm32 +fmt_idx = 0; +pcode_end + +vmaxnm: +group NEON +Encoding T1 ADVSIMD +fmt VMAXNM.F32 <Sd>,<Sn>,<Sm> +fmt VMAXNM.F64 <Dd>,<Dn>,<Dm> +fmt VMINNM.F32 <Sd>,<Sn>,<Sm> +fmt VMINNM.F64 <Dd>,<Dn>,<Dm> +extract32 1111,11101,D.1,00,Vn.4,Vd.4,101,sz.1,N.1,op.1,M.1,0,Vm.4 +pcode_start +dp_operation = (sz == '1'); +d = if dp_operation then UInt(D:Vd) else UInt(Vd:D); +n = if dp_operation then UInt(N:Vn) else UInt(Vn:N); +m = if dp_operation then UInt(M:Vm) else UInt(Vm:M); +fmt_idx = ((op == '1') * 2) + dp_operation; +pcode_end + + +vmrs: +group NEON +Encoding T1 ADVSIMD +fmt VMRS<c> <Rt>,<fpscr> +fmt VMRS<c> <Rt_mrc>,<fpscr> +extract32 1110,11101111,FPSCR.4,Rt.4,1010,(0),(0)(0),1,(0)(0)(0)(0) +pcode_start +t = UInt(Rt); +if t == 13 then UNPREDICTABLE; +Rt_mrc = Rt; +fmt_idx = (Rt == '1111'); +pcode_end + +vmsr: +group NEON +Encoding T1 ADVSIMD +fmt VMSR<c> <fpscr>,<Rt> +extract32 1110,11101110,FPSCR.4,Rt.4,1010,(0),(0)(0),1,(0)(0)(0)(0) +pcode_start +t = UInt(Rt); +if (t == 15 || t == 13) then UNPREDICTABLE; +pcode_end + +vnmla: +group NEON +Encoding T2 VFPv2, VFPv3 +fmt VNMUL<c>.F32 <Sd>,<Sn>,<Sm> +fmt VNMUL<c>.F64 <Dd>,<Dn>,<Dm> +extract32 1110,11100,D.1,10,Vn.4,Vd.4,101,sz.1,N.1,1,M.1,0,Vm.4 +pcode_start +dp_operation = (sz == '1'); +d = if dp_operation then UInt(D:Vd) else UInt(Vd:D); +n = if dp_operation then UInt(N:Vn) else UInt(Vn:N); +m = if dp_operation then UInt(M:Vm) else UInt(Vm:M); +fmt_idx = dp_operation; +pcode_end +Encoding T1 VFPv2, VFPv3 +fmt VNMLS<c>.F32 <Sd>,<Sn>,<Sm> +fmt VNMLS<c>.F64 <Dd>,<Dn>,<Dm> +fmt VNMLA<c>.F32 <Sd>,<Sn>,<Sm> +fmt VNMLA<c>.F64 <Dd>,<Dn>,<Dm> +extract32 1110,11100,D.1,01,Vn.4,Vd.4,101,sz.1,N.1,op.1,M.1,0,Vm.4 +pcode_start +dp_operation = (sz == '1'); +d = if dp_operation then UInt(D:Vd) else UInt(Vd:D); +n = if dp_operation then UInt(N:Vn) else UInt(Vn:N); +m = if dp_operation then UInt(M:Vm) else UInt(Vm:M); +fmt_idx = (op * 2) + dp_operation; +pcode_end + +vqsub: +group NEON +Encoding T1 ADVSIMD +fmt VQSUB<c>.<dt> <Dd>,<Dn>,<Dm> +fmt VQSUB<c>.<dt> <Qd>,<Qn>,<Qm> +extract32 111,U.1,1111,0,D.1,size.2,Vn.4,Vd.4,0010,N.1,Q.1,M.1,1,Vm.4 +pcode_start +if (Q == '1' && (Vd<0> == '1' || Vn<0> == '1' || Vm<0> == '1')) then UNDEFINED; +unsigned = (U == '1'); +esize = 8 << UInt(size); elements = 64 DIV esize; +d = UInt(D:Vd); n = UInt(N:Vn); m = UInt(M:Vm); regs = if Q == '0' then 1 else 2; +fmt_idx = (Q == '1'); +dt = UInt(U:size); +pcode_end + +vrinta: +group NEON +Encoding T1 ADVSIMD +fmt VRINTA<c>.F32 <Sd>,<Sm> +fmt VRINTA<c>.F64 <Dd>,<Dm> +fmt VRINTN<c>.F32 <Sd>,<Sm> +fmt VRINTN<c>.F64 <Dd>,<Dm> +fmt VRINTP<c>.F32 <Sd>,<Sm> +fmt VRINTP<c>.F64 <Dd>,<Dm> +fmt VRINTM<c>.F32 <Sd>,<Sm> +fmt VRINTM<c>.F64 <Dd>,<Dm> +extract32 1111,11101,D.1,1110,RM.2,Vd.4,101,sz.1,0,1,M.1,0,Vm.4 +pcode_start +dp_operation = (sz == '1'); +d = if dp_operation then UInt(D:Vd) else UInt(Vd:D); +m = if dp_operation then UInt(M:Vm) else UInt(Vm:M); +fmt_idx = (RM * 2) + dp_operation; +pcode_end + +vrintx: +group NEON +Encoding T1 ADVSIMD +fmt VRINTX<c>.F32 <Sd>,<Sm> +fmt VRINTX<c>.F64 <Dd>,<Dm> +extract32 1110,11101,D.1,11011,1,Vd.4,101,sz.1,0,1,M.1,0,Vm.4 +pcode_start +dp_operation = (sz == '1'); +d = if dp_operation then UInt(D:Vd) else UInt(Vd:D); +m = if dp_operation then UInt(M:Vm) else UInt(Vm:M); +fmt_idx = dp_operation; +pcode_end + +vrintz: +group NEON +Encoding T1 ADVSIMD +fmt VRINTR<c>.F32 <Sd>,<Sm> +fmt VRINTR<c>.F64 <Dd>,<Dm> +fmt VRINTZ<c>.F32 <Sd>,<Sm> +fmt VRINTZ<c>.F64 <Dd>,<Dm> +extract32 1110,11101,D.1,11011,0,Vd.4,101,sz.1,op.1,1,M.1,0,Vm.4 +pcode_start +dp_operation = (sz == '1'); +d = if dp_operation then UInt(D:Vd) else UInt(Vd:D); +m = if dp_operation then UInt(M:Vm) else UInt(Vm:M); +fmt_idx = (op * 2) + dp_operation; +pcode_end + +vrsubhn: +group NEON +Encoding T1 ADVSIMD +fmt VRSUBHN<c>.<dt> <Dd>,<Qn>,<Qm> +extract32 1111,1111,1,D.1,size.2,Vn.4,Vd.4,0110,N.1,0,M.1,0,Vm.4 +pcode_start +if size == '11' then SEE advanced_simd_data_proc; +if (Vn<0> == '1' || Vm<0> == '1') then UNDEFINED; +esize = 8 << UInt(size); elements = 64 DIV esize; +d = UInt(D:Vd); n = UInt(N:Vn); m = UInt(M:Vm); +iword = TRUE; +dt = size + 1; +pcode_end + +vsel: +group NEON +Encoding T1 ADVSIMD +fmt VSEL<c>.<dt> <Sd>,<Sn>,<Sm> +fmt VSEL<c>.<dt> <Dd>,<Dn>,<Dm> +extract32 1111,11100,D.1,cc.2,Vn.4,Vd.4,101,sz.1,N.1,0,M.1,0,Vm.4 +pcode_start +dp_operation = (sz == '1'); cond = ((cc * 2) + (cc<1> XOR cc<0>)) * 2; +d = if dp_operation then UInt(D:Vd) else UInt(Vd:D); +n = if dp_operation then UInt(N:Vn) else UInt(Vn:N); +m = if dp_operation then UInt(M:Vm) else UInt(Vm:M); +fmt_idx = dp_operation; +dt = 3 + dp_operation; +pcode_end + +vsqrt: +group NEON +Encoding T1 VFPv2, VFPv3 +fmt VSQRT<c>.F32 <Sd>,<Sm> +fmt VSQRT<c>.F64 <Dd>,<Dm> +extract32 1110,11101,D.1,11,0001,Vd.4,101,sz.1,1,1,M.1,0,Vm.4 +pcode_start +dp_operation = (sz == '1'); +d = if dp_operation then UInt(D:Vd) else UInt(Vd:D); +m = if dp_operation then UInt(M:Vm) else UInt(Vm:M); +fmt_idx = dp_operation; +pcode_end + +vstr: +group NEON +Encoding T2 VFPv2, VFPv3 +fmt VSTR<c> <Sd>,[<Rn>,#<+/-><imm32>] +extract32 1110,1101,U.1,D.1,0,0,Rn.4,Vd.4,1010,imm8.8 +pcode_start +add = (U == '1'); imm32 = ZeroExtend(imm8:'00', 32); +d = UInt(Vd:D); n = UInt(Rn); +pcode_end +Encoding T1 VFPv2, VFPv3 +fmt VSTR<c> <Dd>,[<Rn>,#<+/-><imm32>] +extract32 1110,1101,U.1,D.1,0,0,Rn.4,Vd.4,1011,imm8.8 +pcode_start +add = (U == '1'); imm32 = ZeroExtend(imm8:'00', 32); +d = UInt(D:Vd); n = UInt(Rn); +pcode_end + +vsub_integer: +group NEON +Encoding T1 ADVSIMD +fmt VSUB<c>.<dt> <Dd>,<Dn>,<Dm> +fmt VSUB<c>.<dt> <Qd>,<Qn>,<Qm> +extract32 1111,1111,0,D.1,size.2,Vn.4,Vd.4,1000,N.1,Q.1,M.1,0,Vm.4 +pcode_start +if Q == '1' && (Vd<0> == '1' || Vn<0> == '1' || Vm<0> == '1') then UNDEFINED; +esize = 8 << UInt(size); elements = 64 DIV esize; +d = UInt(D:Vd); n = UInt(N:Vn); m = UInt(M:Vm); regs = if Q == '0' then 1 else 2; +iword = TRUE; +dt = size; +fmt_idx = (Q == '1'); +pcode_end + +vsub_float: +group NEON +Encoding T2 VFPv2, VFPv3 +fmt VSUB<c>.F32 <Sd>,<Sn>,<Sm> +fmt VSUB<c>.F64 <Dd>,<Dn>,<Dm> +extract32 1110,11100,D.1,11,Vn.4,Vd.4,101,sz.1,N.1,1,M.1,0,Vm.4 +pcode_start +advsimd = FALSE; dp_operation = (sz == '1'); +d = if dp_operation then UInt(D:Vd) else UInt(Vd:D); +n = if dp_operation then UInt(N:Vn) else UInt(Vn:N); +m = if dp_operation then UInt(M:Vm) else UInt(Vm:M); +fmt_idx = dp_operation; +pcode_end +Encoding T1 ADVSIMD +fmt VSUB<c>.F32 <Dd>,<Dn>,<Dm> +fmt VSUB<c>.F32 <Qd>,<Qn>,<Qm> +extract32 1110,1111,0,D.1,1,sz.1,Vn.4,Vd.4,1101,N.1,Q.1,M.1,0,Vm.4 +pcode_start +if Q == '1' && (Vd<0> == '1' || Vn<0> == '1' || Vm<0> == '1') then UNDEFINED; +if sz == '1' then UNDEFINED; +advsimd = TRUE; esize = 32; elements = 2; +d = UInt(D:Vd); n = UInt(N:Vn); m = UInt(M:Vm); regs = if Q == '0' then 1 else 2; +fmt_idx = (Q == '1'); +pcode_end + +vsubhn: +group NEON +Encoding T1 ADVSIMD +fmt VSUBHN<c>.<dt> <Dd>,<Qn>,<Qm> +extract32 1110,1111,1,D.1,size.2,Vn.4,Vd.4,0110,N.1,0,M.1,0,Vm.4 +pcode_start +if size == '11' then SEE advanced_simd_data_proc; +if Vn<0> == '1' || Vm<0> == '1' then UNDEFINED; +esize = 8 << UInt(size); elements = 64 DIV esize; +d = UInt(D:Vd); n = UInt(N:Vn); m = UInt(M:Vm); +iword = TRUE; +dt = size + 1; +fmt_idx = (Q == '1'); +pcode_end + +vsubl: +group NEON +Encoding T1 ADVSIMD +fmt VSUBL<c>.<dt> <Qd>,<Dn>,<Dm> +fmt VSUBW<c>.<dt> <Qd>,<Qn>,<Dm> +extract32 111,U.1,1111,1,D.1,size.2,Vn.4,Vd.4,001,op.1,N.1,0,M.1,0,Vm.4 +pcode_start +if size == '11' then SEE advanced_simd_data_proc; +if Vd<0> == '1' || (op == '1' && Vn<0> == '1') then UNDEFINED; +unsigned = (U == '1'); +esize = 8 << UInt(size); elements = 64 DIV esize; +d = UInt(D:Vd); n = UInt(N:Vn); m = UInt(M:Vm); +dt = UInt(U:size); +fmt_idx = op; +pcode_end + +vtst: +group NEON +Encoding T1 ADVSIMD +fmt VTST<c>.<size> <Dd>,<Dn>,<Dm> +fmt VTST<c>.<size> <Qd>,<Qn>,<Qm> +extract32 1110,1111,0,D.1,size.2,Vn.4,Vd.4,1000,N.1,Q.1,M.1,1,Vm.4 +pcode_start +if Q == '1' && (Vd<0> == '1' || Vn<0> == '1' || Vm<0> == '1') then UNDEFINED; +if size == '11' then UNDEFINED; +esize = 8 << UInt(size); elements = 64 DIV esize; +d = UInt(D:Vd); n = UInt(N:Vn); m = UInt(M:Vm); regs = if Q == '0' then 1 else 2; +fmt_idx = (Q == '1'); +pcode_end + +//----------------------------------------------------------------------------- +// misc +//----------------------------------------------------------------------------- + +undefined: +Encoding T1 ARMv4T, ARMv5T, ARMv6, ARMv7 +fmt UNDEFINED +extract16 (0)(0)(0)(0)(0)(0)(0)(0)(0)(0)(0)(0)(0)(0)(0)(0) +pcode UNDEFINED; +Encoding T1 ARMv4T, ARMv5T, ARMv6, ARMv7 +fmt UNDEFINED +extract32 (0)(0)(0)(0)(0)(0)(0)(0)(0)(0)(0)(0)(0)(0)(0)(0)(0)(0)(0)(0)(0)(0)(0)(0)(0)(0)(0)(0)(0)(0)(0)(0) +pcode UNDEFINED; + +unpredictable: +Encoding T1 ARMv4T, ARMv5T, ARMv6, ARMv7 +fmt UNPREDICTABLE +extract16 (0)(0)(0)(0)(0)(0)(0)(0)(0)(0)(0)(0)(0)(0)(0)(0) +pcode UNPREDICTABLE; +Encoding T1 ARMv4T, ARMv5T, ARMv6, ARMv7 +fmt UNPREDICTABLE +extract32 (0)(0)(0)(0)(0)(0)(0)(0)(0)(0)(0)(0)(0)(0)(0)(0)(0)(0)(0)(0)(0)(0)(0)(0)(0)(0)(0)(0)(0)(0)(0)(0) +pcode UNPREDICTABLE; + |
