mirror of
https://github.com/yuzu-emu/unicorn.git
synced 2024-12-24 00:25:42 +00:00
c7f6786089
There is no "version 2" of the "Lesser" General Public License. It is either "GPL version 2.0" or "Lesser GPL version 2.1". This patch replaces all occurrences of "Lesser GPL version 2" with "Lesser GPL version 2.1" in comment section. Backports 50f57e09fda4b7ffbc5ba62aad6cebf660824023
282 lines
9.4 KiB
Plaintext
282 lines
9.4 KiB
Plaintext
# Thumb1 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.1 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 <http://www.gnu.org/licenses/>.
|
|
|
|
#
|
|
# 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
|
|
&rrr_rot !extern rd rn rm rot
|
|
&rr !extern rd rm
|
|
&ri !extern rd imm
|
|
&r !extern rm
|
|
&i !extern imm
|
|
&ldst_rr !extern p w u rn rt rm shimm shtype
|
|
&ldst_ri !extern p w u rn rt imm
|
|
&ldst_block !extern rn i b u w list
|
|
&setend !extern E
|
|
&cps !extern mode imod M A I F
|
|
&ci !extern cond imm
|
|
|
|
# Set S if the instruction is outside of an IT block.
|
|
%s !function=t16_setflags
|
|
|
|
# Data-processing (two low registers)
|
|
|
|
%reg_0 0:3
|
|
|
|
@lll_noshr ...... .... rm:3 rd:3 \
|
|
&s_rrr_shi %s rn=%reg_0 shim=0 shty=0
|
|
@xll_noshr ...... .... rm:3 rn:3 \
|
|
&s_rrr_shi s=1 rd=0 shim=0 shty=0
|
|
@lxl_shr ...... .... rs:3 rd:3 \
|
|
&s_rrr_shr %s rm=%reg_0 rn=0
|
|
|
|
AND_rrri 010000 0000 ... ... @lll_noshr
|
|
EOR_rrri 010000 0001 ... ... @lll_noshr
|
|
MOV_rxrr 010000 0010 ... ... @lxl_shr shty=0 # LSL
|
|
MOV_rxrr 010000 0011 ... ... @lxl_shr shty=1 # LSR
|
|
MOV_rxrr 010000 0100 ... ... @lxl_shr shty=2 # ASR
|
|
ADC_rrri 010000 0101 ... ... @lll_noshr
|
|
SBC_rrri 010000 0110 ... ... @lll_noshr
|
|
MOV_rxrr 010000 0111 ... ... @lxl_shr shty=3 # ROR
|
|
TST_xrri 010000 1000 ... ... @xll_noshr
|
|
RSB_rri 010000 1001 rn:3 rd:3 &s_rri_rot %s imm=0 rot=0
|
|
CMP_xrri 010000 1010 ... ... @xll_noshr
|
|
CMN_xrri 010000 1011 ... ... @xll_noshr
|
|
ORR_rrri 010000 1100 ... ... @lll_noshr
|
|
MUL 010000 1101 rn:3 rd:3 &s_rrrr %s rm=%reg_0 ra=0
|
|
BIC_rrri 010000 1110 ... ... @lll_noshr
|
|
MVN_rxri 010000 1111 ... ... @lll_noshr
|
|
|
|
# Load/store (register offset)
|
|
|
|
@ldst_rr ....... rm:3 rn:3 rt:3 \
|
|
&ldst_rr p=1 w=0 u=1 shimm=0 shtype=0
|
|
|
|
STR_rr 0101 000 ... ... ... @ldst_rr
|
|
STRH_rr 0101 001 ... ... ... @ldst_rr
|
|
STRB_rr 0101 010 ... ... ... @ldst_rr
|
|
LDRSB_rr 0101 011 ... ... ... @ldst_rr
|
|
LDR_rr 0101 100 ... ... ... @ldst_rr
|
|
LDRH_rr 0101 101 ... ... ... @ldst_rr
|
|
LDRB_rr 0101 110 ... ... ... @ldst_rr
|
|
LDRSH_rr 0101 111 ... ... ... @ldst_rr
|
|
|
|
# Load/store word/byte (immediate offset)
|
|
|
|
%imm5_6x4 6:5 !function=times_4
|
|
|
|
@ldst_ri_1 ..... imm:5 rn:3 rt:3 \
|
|
&ldst_ri p=1 w=0 u=1
|
|
@ldst_ri_4 ..... ..... rn:3 rt:3 \
|
|
&ldst_ri p=1 w=0 u=1 imm=%imm5_6x4
|
|
|
|
STR_ri 01100 ..... ... ... @ldst_ri_4
|
|
LDR_ri 01101 ..... ... ... @ldst_ri_4
|
|
STRB_ri 01110 ..... ... ... @ldst_ri_1
|
|
LDRB_ri 01111 ..... ... ... @ldst_ri_1
|
|
|
|
# Load/store halfword (immediate offset)
|
|
|
|
%imm5_6x2 6:5 !function=times_2
|
|
@ldst_ri_2 ..... ..... rn:3 rt:3 \
|
|
&ldst_ri p=1 w=0 u=1 imm=%imm5_6x2
|
|
|
|
STRH_ri 10000 ..... ... ... @ldst_ri_2
|
|
LDRH_ri 10001 ..... ... ... @ldst_ri_2
|
|
|
|
# Load/store (SP-relative)
|
|
|
|
%imm8_0x4 0:8 !function=times_4
|
|
@ldst_spec_i ..... rt:3 ........ \
|
|
&ldst_ri p=1 w=0 u=1 imm=%imm8_0x4
|
|
|
|
STR_ri 10010 ... ........ @ldst_spec_i rn=13
|
|
LDR_ri 10011 ... ........ @ldst_spec_i rn=13
|
|
|
|
# Load (PC-relative)
|
|
|
|
LDR_ri 01001 ... ........ @ldst_spec_i rn=15
|
|
|
|
# Add PC/SP (immediate)
|
|
|
|
ADR 10100 rd:3 ........ imm=%imm8_0x4
|
|
ADD_rri 10101 rd:3 ........ \
|
|
&s_rri_rot rn=13 s=0 rot=0 imm=%imm8_0x4 # SP
|
|
|
|
# Load/store multiple
|
|
|
|
@ldstm ..... rn:3 list:8 &ldst_block i=1 b=0 u=0 w=1
|
|
|
|
STM 11000 ... ........ @ldstm
|
|
LDM_t16 11001 ... ........ @ldstm
|
|
|
|
# Shift (immediate)
|
|
|
|
@shift_i ..... shim:5 rm:3 rd:3 &s_rrr_shi %s rn=%reg_0
|
|
|
|
MOV_rxri 000 00 ..... ... ... @shift_i shty=0 # LSL
|
|
MOV_rxri 000 01 ..... ... ... @shift_i shty=1 # LSR
|
|
MOV_rxri 000 10 ..... ... ... @shift_i shty=2 # ASR
|
|
|
|
# Add/subtract (three low registers)
|
|
|
|
@addsub_3 ....... rm:3 rn:3 rd:3 \
|
|
&s_rrr_shi %s shim=0 shty=0
|
|
|
|
ADD_rrri 0001100 ... ... ... @addsub_3
|
|
SUB_rrri 0001101 ... ... ... @addsub_3
|
|
|
|
# Add/subtract (two low registers and immediate)
|
|
|
|
@addsub_2i ....... imm:3 rn:3 rd:3 \
|
|
&s_rri_rot %s rot=0
|
|
|
|
ADD_rri 0001 110 ... ... ... @addsub_2i
|
|
SUB_rri 0001 111 ... ... ... @addsub_2i
|
|
|
|
# Add, subtract, compare, move (one low register and immediate)
|
|
|
|
%reg_8 8:3
|
|
@arith_1i ..... rd:3 imm:8 \
|
|
&s_rri_rot rot=0 rn=%reg_8
|
|
|
|
MOV_rxi 00100 ... ........ @arith_1i %s
|
|
CMP_xri 00101 ... ........ @arith_1i s=1
|
|
ADD_rri 00110 ... ........ @arith_1i %s
|
|
SUB_rri 00111 ... ........ @arith_1i %s
|
|
|
|
# Add, compare, move (two high registers)
|
|
|
|
%reg_0_7 7:1 0:3
|
|
@addsub_2h .... .... . rm:4 ... \
|
|
&s_rrr_shi rd=%reg_0_7 rn=%reg_0_7 shim=0 shty=0
|
|
|
|
ADD_rrri 0100 0100 . .... ... @addsub_2h s=0
|
|
CMP_xrri 0100 0101 . .... ... @addsub_2h s=1
|
|
MOV_rxri 0100 0110 . .... ... @addsub_2h s=0
|
|
|
|
# Adjust SP (immediate)
|
|
|
|
%imm7_0x4 0:7 !function=times_4
|
|
@addsub_sp_i .... .... . ....... \
|
|
&s_rri_rot s=0 rd=13 rn=13 rot=0 imm=%imm7_0x4
|
|
|
|
ADD_rri 1011 0000 0 ....... @addsub_sp_i
|
|
SUB_rri 1011 0000 1 ....... @addsub_sp_i
|
|
|
|
# Branch and exchange
|
|
|
|
@branchr .... .... . rm:4 ... &r
|
|
|
|
BX 0100 0111 0 .... 000 @branchr
|
|
BLX_r 0100 0111 1 .... 000 @branchr
|
|
BXNS 0100 0111 0 .... 100 @branchr
|
|
BLXNS 0100 0111 1 .... 100 @branchr
|
|
|
|
# Extend
|
|
|
|
@extend .... .... .. rm:3 rd:3 &rrr_rot rn=15 rot=0
|
|
|
|
SXTAH 1011 0010 00 ... ... @extend
|
|
SXTAB 1011 0010 01 ... ... @extend
|
|
UXTAH 1011 0010 10 ... ... @extend
|
|
UXTAB 1011 0010 11 ... ... @extend
|
|
|
|
# Change processor state
|
|
|
|
%imod 4:1 !function=plus_2
|
|
|
|
SETEND 1011 0110 010 1 E:1 000 &setend
|
|
{
|
|
CPS 1011 0110 011 . 0 A:1 I:1 F:1 &cps mode=0 M=0 %imod
|
|
CPS_v7m 1011 0110 011 im:1 00 I:1 F:1
|
|
}
|
|
|
|
# Reverse bytes
|
|
|
|
@rdm .... .... .. rm:3 rd:3 &rr
|
|
|
|
REV 1011 1010 00 ... ... @rdm
|
|
REV16 1011 1010 01 ... ... @rdm
|
|
REVSH 1011 1010 11 ... ... @rdm
|
|
|
|
# Hints
|
|
|
|
{
|
|
{
|
|
YIELD 1011 1111 0001 0000
|
|
WFE 1011 1111 0010 0000
|
|
WFI 1011 1111 0011 0000
|
|
|
|
# TODO: Implement SEV, SEVL; may help SMP performance.
|
|
# SEV 1011 1111 0100 0000
|
|
# SEVL 1011 1111 0101 0000
|
|
|
|
# The canonical nop has the second nibble as 0000, but the whole of the
|
|
# rest of the space is a reserved hint, behaves as nop.
|
|
NOP 1011 1111 ---- 0000
|
|
}
|
|
IT 1011 1111 cond_mask:8
|
|
}
|
|
|
|
# Miscellaneous 16-bit instructions
|
|
|
|
%imm6_9_3 9:1 3:5 !function=times_2
|
|
|
|
HLT 1011 1010 10 imm:6 &i
|
|
BKPT 1011 1110 imm:8 &i
|
|
CBZ 1011 nz:1 0.1 ..... rn:3 imm=%imm6_9_3
|
|
|
|
# Push and Pop
|
|
|
|
%push_list 0:9 !function=t16_push_list
|
|
%pop_list 0:9 !function=t16_pop_list
|
|
|
|
STM 1011 010 ......... \
|
|
&ldst_block i=0 b=1 u=0 w=1 rn=13 list=%push_list
|
|
LDM_t16 1011 110 ......... \
|
|
&ldst_block i=1 b=0 u=0 w=1 rn=13 list=%pop_list
|
|
|
|
# Conditional branches, Supervisor call
|
|
|
|
%imm8_0x2 0:s8 !function=times_2
|
|
|
|
{
|
|
UDF 1101 1110 ---- ----
|
|
SVC 1101 1111 imm:8 &i
|
|
B_cond_thumb 1101 cond:4 ........ &ci imm=%imm8_0x2
|
|
}
|
|
|
|
# Unconditional Branch
|
|
|
|
%imm11_0x2 0:s11 !function=times_2
|
|
|
|
B 11100 ........... &i imm=%imm11_0x2
|
|
|
|
# thumb_insn_is_16bit() ensures we won't be decoding these as
|
|
# T16 instructions for a Thumb2 CPU, so these patterns must be
|
|
# a Thumb1 split BL/BLX.
|
|
BLX_suffix 11101 imm:11 &i
|
|
BL_BLX_prefix 11110 imm:s11 &i
|
|
BL_suffix 11111 imm:11 &i
|