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