//-----------------------------------------------------------------------------
// 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;

