# Thumb2 instructions # # Copyright (c) 2019 Linaro, Ltd # # This library is free software; you can redistribute it and/or # modify it under the terms of the GNU Lesser General Public # License as published by the Free Software Foundation; either # version 2 of the License, or (at your option) any later version. # # This library is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # Lesser General Public License for more details. # # You should have received a copy of the GNU Lesser General Public # License along with this library; if not, see . # # This file is processed by scripts/decodetree.py # &empty !extern &s_rrr_shi !extern s rd rn rm shim shty &s_rrr_shr !extern s rn rd rm rs shty &s_rri_rot !extern s rn rd imm rot &s_rrrr !extern s rd rn rm ra &rrrr !extern rd rn rm ra &rrr !extern rd rn rm &rr !extern rd rm &ri !extern rd imm &r !extern rm &i !extern imm &msr_reg !extern rn r mask &mrs_reg !extern rd r &msr_bank !extern rn r sysm &mrs_bank !extern rd r sysm &ldst_rr !extern p w u rn rt rm shimm shtype &ldst_ri !extern p w u rn rt imm &strex !extern rn rd rt rt2 imm &ldrex !extern rn rt rt2 imm # Data-processing (register) %imm5_12_6 12:3 6:2 @s_rrr_shi ....... .... s:1 rn:4 .... rd:4 .. shty:2 rm:4 \ &s_rrr_shi shim=%imm5_12_6 @s_rxr_shi ....... .... s:1 .... .... rd:4 .. shty:2 rm:4 \ &s_rrr_shi shim=%imm5_12_6 rn=0 @S_xrr_shi ....... .... . rn:4 .... .... .. shty:2 rm:4 \ &s_rrr_shi shim=%imm5_12_6 s=1 rd=0 { TST_xrri 1110101 0000 1 .... 0 ... 1111 .... .... @S_xrr_shi AND_rrri 1110101 0000 . .... 0 ... .... .... .... @s_rrr_shi } BIC_rrri 1110101 0001 . .... 0 ... .... .... .... @s_rrr_shi { MOV_rxri 1110101 0010 . 1111 0 ... .... .... .... @s_rxr_shi ORR_rrri 1110101 0010 . .... 0 ... .... .... .... @s_rrr_shi } { MVN_rxri 1110101 0011 . 1111 0 ... .... .... .... @s_rxr_shi ORN_rrri 1110101 0011 . .... 0 ... .... .... .... @s_rrr_shi } { TEQ_xrri 1110101 0100 1 .... 0 ... 1111 .... .... @S_xrr_shi EOR_rrri 1110101 0100 . .... 0 ... .... .... .... @s_rrr_shi } # PKHBT, PKHTB at opc1 = 0110 { CMN_xrri 1110101 1000 1 .... 0 ... 1111 .... .... @S_xrr_shi ADD_rrri 1110101 1000 . .... 0 ... .... .... .... @s_rrr_shi } ADC_rrri 1110101 1010 . .... 0 ... .... .... .... @s_rrr_shi SBC_rrri 1110101 1011 . .... 0 ... .... .... .... @s_rrr_shi { CMP_xrri 1110101 1101 1 .... 0 ... 1111 .... .... @S_xrr_shi SUB_rrri 1110101 1101 . .... 0 ... .... .... .... @s_rrr_shi } RSB_rrri 1110101 1110 . .... 0 ... .... .... .... @s_rrr_shi # Data-processing (register-shifted register) MOV_rxrr 1111 1010 0 shty:2 s:1 rm:4 1111 rd:4 0000 rs:4 \ &s_rrr_shr rn=0 # Data-processing (immediate) %t32extrot 26:1 12:3 0:8 !function=t32_expandimm_rot %t32extimm 26:1 12:3 0:8 !function=t32_expandimm_imm @s_rri_rot ....... .... s:1 rn:4 . ... rd:4 ........ \ &s_rri_rot imm=%t32extimm rot=%t32extrot @s_rxi_rot ....... .... s:1 .... . ... rd:4 ........ \ &s_rri_rot imm=%t32extimm rot=%t32extrot rn=0 @S_xri_rot ....... .... . rn:4 . ... .... ........ \ &s_rri_rot imm=%t32extimm rot=%t32extrot s=1 rd=0 { TST_xri 1111 0.0 0000 1 .... 0 ... 1111 ........ @S_xri_rot AND_rri 1111 0.0 0000 . .... 0 ... .... ........ @s_rri_rot } BIC_rri 1111 0.0 0001 . .... 0 ... .... ........ @s_rri_rot { MOV_rxi 1111 0.0 0010 . 1111 0 ... .... ........ @s_rxi_rot ORR_rri 1111 0.0 0010 . .... 0 ... .... ........ @s_rri_rot } { MVN_rxi 1111 0.0 0011 . 1111 0 ... .... ........ @s_rxi_rot ORN_rri 1111 0.0 0011 . .... 0 ... .... ........ @s_rri_rot } { TEQ_xri 1111 0.0 0100 1 .... 0 ... 1111 ........ @S_xri_rot EOR_rri 1111 0.0 0100 . .... 0 ... .... ........ @s_rri_rot } { CMN_xri 1111 0.0 1000 1 .... 0 ... 1111 ........ @S_xri_rot ADD_rri 1111 0.0 1000 . .... 0 ... .... ........ @s_rri_rot } ADC_rri 1111 0.0 1010 . .... 0 ... .... ........ @s_rri_rot SBC_rri 1111 0.0 1011 . .... 0 ... .... ........ @s_rri_rot { CMP_xri 1111 0.0 1101 1 .... 0 ... 1111 ........ @S_xri_rot SUB_rri 1111 0.0 1101 . .... 0 ... .... ........ @s_rri_rot } RSB_rri 1111 0.0 1110 . .... 0 ... .... ........ @s_rri_rot # Data processing (plain binary immediate) %imm12_26_12_0 26:1 12:3 0:8 %neg12_26_12_0 26:1 12:3 0:8 !function=negate @s0_rri_12 .... ... .... . rn:4 . ... rd:4 ........ \ &s_rri_rot imm=%imm12_26_12_0 rot=0 s=0 { ADR 1111 0.1 0000 0 1111 0 ... rd:4 ........ \ &ri imm=%imm12_26_12_0 ADD_rri 1111 0.1 0000 0 .... 0 ... .... ........ @s0_rri_12 } { ADR 1111 0.1 0101 0 1111 0 ... rd:4 ........ \ &ri imm=%neg12_26_12_0 SUB_rri 1111 0.1 0101 0 .... 0 ... .... ........ @s0_rri_12 } # Multiply and multiply accumulate @s0_rnadm .... .... .... rn:4 ra:4 rd:4 .... rm:4 &s_rrrr s=0 @s0_rn0dm .... .... .... rn:4 .... rd:4 .... rm:4 &s_rrrr ra=0 s=0 @rnadm .... .... .... rn:4 ra:4 rd:4 .... rm:4 &rrrr @rn0dm .... .... .... rn:4 .... rd:4 .... rm:4 &rrrr ra=0 @rndm .... .... .... rn:4 .... rd:4 .... rm:4 &rrr @rdm .... .... .... .... .... rd:4 .... rm:4 &rr { MUL 1111 1011 0000 .... 1111 .... 0000 .... @s0_rn0dm MLA 1111 1011 0000 .... .... .... 0000 .... @s0_rnadm } MLS 1111 1011 0000 .... .... .... 0001 .... @rnadm SMULL 1111 1011 1000 .... .... .... 0000 .... @s0_rnadm UMULL 1111 1011 1010 .... .... .... 0000 .... @s0_rnadm SMLAL 1111 1011 1100 .... .... .... 0000 .... @s0_rnadm UMLAL 1111 1011 1110 .... .... .... 0000 .... @s0_rnadm UMAAL 1111 1011 1110 .... .... .... 0110 .... @rnadm { SMULWB 1111 1011 0011 .... 1111 .... 0000 .... @rn0dm SMLAWB 1111 1011 0011 .... .... .... 0000 .... @rnadm } { SMULWT 1111 1011 0011 .... 1111 .... 0001 .... @rn0dm SMLAWT 1111 1011 0011 .... .... .... 0001 .... @rnadm } { SMULBB 1111 1011 0001 .... 1111 .... 0000 .... @rn0dm SMLABB 1111 1011 0001 .... .... .... 0000 .... @rnadm } { SMULBT 1111 1011 0001 .... 1111 .... 0001 .... @rn0dm SMLABT 1111 1011 0001 .... .... .... 0001 .... @rnadm } { SMULTB 1111 1011 0001 .... 1111 .... 0010 .... @rn0dm SMLATB 1111 1011 0001 .... .... .... 0010 .... @rnadm } { SMULTT 1111 1011 0001 .... 1111 .... 0011 .... @rn0dm SMLATT 1111 1011 0001 .... .... .... 0011 .... @rnadm } SMLALBB 1111 1011 1100 .... .... .... 1000 .... @rnadm SMLALBT 1111 1011 1100 .... .... .... 1001 .... @rnadm SMLALTB 1111 1011 1100 .... .... .... 1010 .... @rnadm SMLALTT 1111 1011 1100 .... .... .... 1011 .... @rnadm # Data-processing (two source registers) QADD 1111 1010 1000 .... 1111 .... 1000 .... @rndm QSUB 1111 1010 1000 .... 1111 .... 1010 .... @rndm QDADD 1111 1010 1000 .... 1111 .... 1001 .... @rndm QDSUB 1111 1010 1000 .... 1111 .... 1011 .... @rndm CRC32B 1111 1010 1100 .... 1111 .... 1000 .... @rndm CRC32H 1111 1010 1100 .... 1111 .... 1001 .... @rndm CRC32W 1111 1010 1100 .... 1111 .... 1010 .... @rndm CRC32CB 1111 1010 1101 .... 1111 .... 1000 .... @rndm CRC32CH 1111 1010 1101 .... 1111 .... 1001 .... @rndm CRC32CW 1111 1010 1101 .... 1111 .... 1010 .... @rndm # Note rn != rm is CONSTRAINED UNPREDICTABLE; we choose to ignore rn. CLZ 1111 1010 1011 ---- 1111 .... 1000 .... @rdm # Branches and miscellaneous control %msr_sysm 4:1 8:4 %mrs_sysm 4:1 16:4 %imm16_16_0 16:4 0:12 { { YIELD 1111 0011 1010 1111 1000 0000 0000 0001 WFE 1111 0011 1010 1111 1000 0000 0000 0010 WFI 1111 0011 1010 1111 1000 0000 0000 0011 # TODO: Implement SEV, SEVL; may help SMP performance. # SEV 1111 0011 1010 1111 1000 0000 0000 0100 # SEVL 1111 0011 1010 1111 1000 0000 0000 0101 # The canonical nop ends in 0000 0000, but the whole rest # of the space is "reserved hint, behaves as nop". NOP 1111 0011 1010 1111 1000 0000 ---- ---- } # Note that the v7m insn overlaps both the normal and banked insn. { MRS_bank 1111 0011 111 r:1 .... 1000 rd:4 001. 0000 \ &mrs_bank sysm=%mrs_sysm MRS_reg 1111 0011 111 r:1 1111 1000 rd:4 0000 0000 &mrs_reg MRS_v7m 1111 0011 111 0 1111 1000 rd:4 sysm:8 } { MSR_bank 1111 0011 100 r:1 rn:4 1000 .... 001. 0000 \ &msr_bank sysm=%msr_sysm MSR_reg 1111 0011 100 r:1 rn:4 1000 mask:4 0000 0000 &msr_reg MSR_v7m 1111 0011 100 0 rn:4 1000 mask:2 00 sysm:8 } BXJ 1111 0011 1100 rm:4 1000 1111 0000 0000 &r { # At v6T2, this is the T5 encoding of SUBS PC, LR, #IMM, and works as for # every other encoding of SUBS. With v7VE, IMM=0 is redefined as ERET. # The distinction between the two only matters for Hyp mode. ERET 1111 0011 1101 1110 1000 1111 0000 0000 SUB_rri 1111 0011 1101 1110 1000 1111 imm:8 \ &s_rri_rot rot=0 s=1 rd=15 rn=14 } SMC 1111 0111 1111 imm:4 1000 0000 0000 0000 &i HVC 1111 0111 1110 .... 1000 .... .... .... \ &i imm=%imm16_16_0 } # Load/store (register, immediate, literal) @ldst_rr .... .... .... rn:4 rt:4 ...... shimm:2 rm:4 \ &ldst_rr p=1 w=0 u=1 shtype=0 @ldst_ri_idx .... .... .... rn:4 rt:4 . p:1 u:1 . imm:8 \ &ldst_ri w=1 @ldst_ri_neg .... .... .... rn:4 rt:4 .... imm:8 \ &ldst_ri p=1 w=0 u=0 @ldst_ri_unp .... .... .... rn:4 rt:4 .... imm:8 \ &ldst_ri p=1 w=0 u=1 @ldst_ri_pos .... .... .... rn:4 rt:4 imm:12 \ &ldst_ri p=1 w=0 u=1 @ldst_ri_lit .... .... u:1 ... .... rt:4 imm:12 \ &ldst_ri p=1 w=0 rn=15 STRB_rr 1111 1000 0000 .... .... 000000 .. .... @ldst_rr STRB_ri 1111 1000 0000 .... .... 1..1 ........ @ldst_ri_idx STRB_ri 1111 1000 0000 .... .... 1100 ........ @ldst_ri_neg STRBT_ri 1111 1000 0000 .... .... 1110 ........ @ldst_ri_unp STRB_ri 1111 1000 1000 .... .... ............ @ldst_ri_pos STRH_rr 1111 1000 0010 .... .... 000000 .. .... @ldst_rr STRH_ri 1111 1000 0010 .... .... 1..1 ........ @ldst_ri_idx STRH_ri 1111 1000 0010 .... .... 1100 ........ @ldst_ri_neg STRHT_ri 1111 1000 0010 .... .... 1110 ........ @ldst_ri_unp STRH_ri 1111 1000 1010 .... .... ............ @ldst_ri_pos STR_rr 1111 1000 0100 .... .... 000000 .. .... @ldst_rr STR_ri 1111 1000 0100 .... .... 1..1 ........ @ldst_ri_idx STR_ri 1111 1000 0100 .... .... 1100 ........ @ldst_ri_neg STRT_ri 1111 1000 0100 .... .... 1110 ........ @ldst_ri_unp STR_ri 1111 1000 1100 .... .... ............ @ldst_ri_pos # Note that Load, unsigned (literal) overlaps all other load encodings. { { NOP 1111 1000 -001 1111 1111 ------------ # PLD LDRB_ri 1111 1000 .001 1111 .... ............ @ldst_ri_lit } { NOP 1111 1000 1001 ---- 1111 ------------ # PLD LDRB_ri 1111 1000 1001 .... .... ............ @ldst_ri_pos } LDRB_ri 1111 1000 0001 .... .... 1..1 ........ @ldst_ri_idx { NOP 1111 1000 0001 ---- 1111 1100 -------- # PLD LDRB_ri 1111 1000 0001 .... .... 1100 ........ @ldst_ri_neg } LDRBT_ri 1111 1000 0001 .... .... 1110 ........ @ldst_ri_unp { NOP 1111 1000 0001 ---- 1111 000000 -- ---- # PLD LDRB_rr 1111 1000 0001 .... .... 000000 .. .... @ldst_rr } } { { NOP 1111 1000 -011 1111 1111 ------------ # PLD LDRH_ri 1111 1000 .011 1111 .... ............ @ldst_ri_lit } { NOP 1111 1000 1011 ---- 1111 ------------ # PLDW LDRH_ri 1111 1000 1011 .... .... ............ @ldst_ri_pos } LDRH_ri 1111 1000 0011 .... .... 1..1 ........ @ldst_ri_idx { NOP 1111 1000 0011 ---- 1111 1100 -------- # PLDW LDRH_ri 1111 1000 0011 .... .... 1100 ........ @ldst_ri_neg } LDRHT_ri 1111 1000 0011 .... .... 1110 ........ @ldst_ri_unp { NOP 1111 1000 0011 ---- 1111 000000 -- ---- # PLDW LDRH_rr 1111 1000 0011 .... .... 000000 .. .... @ldst_rr } } { LDR_ri 1111 1000 .101 1111 .... ............ @ldst_ri_lit LDR_ri 1111 1000 1101 .... .... ............ @ldst_ri_pos LDR_ri 1111 1000 0101 .... .... 1..1 ........ @ldst_ri_idx LDR_ri 1111 1000 0101 .... .... 1100 ........ @ldst_ri_neg LDRT_ri 1111 1000 0101 .... .... 1110 ........ @ldst_ri_unp LDR_rr 1111 1000 0101 .... .... 000000 .. .... @ldst_rr } # NOPs here are PLI. { { NOP 1111 1001 -001 1111 1111 ------------ LDRSB_ri 1111 1001 .001 1111 .... ............ @ldst_ri_lit } { NOP 1111 1001 1001 ---- 1111 ------------ LDRSB_ri 1111 1001 1001 .... .... ............ @ldst_ri_pos } LDRSB_ri 1111 1001 0001 .... .... 1..1 ........ @ldst_ri_idx { NOP 1111 1001 0001 ---- 1111 1100 -------- LDRSB_ri 1111 1001 0001 .... .... 1100 ........ @ldst_ri_neg } LDRSBT_ri 1111 1001 0001 .... .... 1110 ........ @ldst_ri_unp { NOP 1111 1001 0001 ---- 1111 000000 -- ---- LDRSB_rr 1111 1001 0001 .... .... 000000 .. .... @ldst_rr } } # NOPs here are unallocated memory hints, treated as NOP. { { NOP 1111 1001 -011 1111 1111 ------------ LDRSH_ri 1111 1001 .011 1111 .... ............ @ldst_ri_lit } { NOP 1111 1001 1011 ---- 1111 ------------ LDRSH_ri 1111 1001 1011 .... .... ............ @ldst_ri_pos } LDRSH_ri 1111 1001 0011 .... .... 1..1 ........ @ldst_ri_idx { NOP 1111 1001 0011 ---- 1111 1100 -------- LDRSH_ri 1111 1001 0011 .... .... 1100 ........ @ldst_ri_neg } LDRSHT_ri 1111 1001 0011 .... .... 1110 ........ @ldst_ri_unp { NOP 1111 1001 0011 ---- 1111 000000 -- ---- LDRSH_rr 1111 1001 0011 .... .... 000000 .. .... @ldst_rr } } %imm8x4 0:8 !function=times_4 &ldst_ri2 p w u rn rt rt2 imm @ldstd_ri8 .... .... u:1 ... rn:4 rt:4 rt2:4 ........ \ &ldst_ri2 imm=%imm8x4 STRD_ri_t32 1110 1000 .110 .... .... .... ........ @ldstd_ri8 w=1 p=0 LDRD_ri_t32 1110 1000 .111 .... .... .... ........ @ldstd_ri8 w=1 p=0 STRD_ri_t32 1110 1001 .100 .... .... .... ........ @ldstd_ri8 w=0 p=1 LDRD_ri_t32 1110 1001 .101 .... .... .... ........ @ldstd_ri8 w=0 p=1 STRD_ri_t32 1110 1001 .110 .... .... .... ........ @ldstd_ri8 w=1 p=1 LDRD_ri_t32 1110 1001 .111 .... .... .... ........ @ldstd_ri8 w=1 p=1 # Load/Store Exclusive and Load-Acquire/Store-Release @strex_i .... .... .... rn:4 rt:4 rd:4 .... .... \ &strex rt2=15 imm=%imm8x4 @strex_0 .... .... .... rn:4 rt:4 .... .... rd:4 \ &strex rt2=15 imm=0 @strex_d .... .... .... rn:4 rt:4 rt2:4 .... rd:4 \ &strex imm=0 @ldrex_i .... .... .... rn:4 rt:4 .... .... .... \ &ldrex rt2=15 imm=%imm8x4 @ldrex_0 .... .... .... rn:4 rt:4 .... .... .... \ &ldrex rt2=15 imm=0 @ldrex_d .... .... .... rn:4 rt:4 rt2:4 .... .... \ &ldrex imm=0 STREX 1110 1000 0100 .... .... .... .... .... @strex_i STREXB 1110 1000 1100 .... .... 1111 0100 .... @strex_0 STREXH 1110 1000 1100 .... .... 1111 0101 .... @strex_0 STREXD_t32 1110 1000 1100 .... .... .... 0111 .... @strex_d STLEX 1110 1000 1100 .... .... 1111 1110 .... @strex_0 STLEXB 1110 1000 1100 .... .... 1111 1100 .... @strex_0 STLEXH 1110 1000 1100 .... .... 1111 1101 .... @strex_0 STLEXD_t32 1110 1000 1100 .... .... .... 1111 .... @strex_d STL 1110 1000 1100 .... .... 1111 1010 1111 @ldrex_0 STLB 1110 1000 1100 .... .... 1111 1000 1111 @ldrex_0 STLH 1110 1000 1100 .... .... 1111 1001 1111 @ldrex_0 LDREX 1110 1000 0101 .... .... 1111 .... .... @ldrex_i LDREXB 1110 1000 1101 .... .... 1111 0100 1111 @ldrex_0 LDREXH 1110 1000 1101 .... .... 1111 0101 1111 @ldrex_0 LDREXD_t32 1110 1000 1101 .... .... .... 0111 1111 @ldrex_d LDAEX 1110 1000 1101 .... .... 1111 1110 1111 @ldrex_0 LDAEXB 1110 1000 1101 .... .... 1111 1100 1111 @ldrex_0 LDAEXH 1110 1000 1101 .... .... 1111 1101 1111 @ldrex_0 LDAEXD_t32 1110 1000 1101 .... .... .... 1111 1111 @ldrex_d LDA 1110 1000 1101 .... .... 1111 1010 1111 @ldrex_0 LDAB 1110 1000 1101 .... .... 1111 1000 1111 @ldrex_0 LDAH 1110 1000 1101 .... .... 1111 1001 1111 @ldrex_0