unicorn/qemu/target/arm/t16.decode
Chetan Pant c7f6786089 arm tcg cpus: Fix Lesser GPL version number
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
2021-03-02 13:30:35 -05:00

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