target/arm: Add stubs for AArch32 Neon decodetree

Add the infrastructure for building and invoking a decodetree decoder
for the AArch32 Neon encodings.  At the moment the new decoder covers
nothing, so we always fall back to the existing hand-written decode.

We follow the same pattern we did for the VFP decodetree conversion
(commit 78e138bc1f and following): code that deals
with Neon will be moving gradually out to translate-neon.vfp.inc,
which we #include into translate.c.

In order to share the decode files between A32 and T32, we
split Neon into 3 parts:
 * data-processing
 * load-store
 * 'shared' encodings

The first two groups of instructions have similar but not identical
A32 and T32 encodings, so we need to manually transform the T32
encoding into the A32 one before calling the decoder; the third group
covers the Neon instructions which are identical in A32 and T32.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-id: 20200430181003.21682-4-peter.maydell@linaro.org
This commit is contained in:
Peter Maydell 2020-04-30 19:09:30 +01:00
parent d1a6d3b594
commit 625e3dd44a
6 changed files with 169 additions and 2 deletions

View File

@ -18,6 +18,21 @@ target/arm/decode-sve.inc.c: $(SRC_PATH)/target/arm/sve.decode $(DECODETREE)
$(PYTHON) $(DECODETREE) --decode disas_sve -o $@ $<,\ $(PYTHON) $(DECODETREE) --decode disas_sve -o $@ $<,\
"GEN", $(TARGET_DIR)$@) "GEN", $(TARGET_DIR)$@)
target/arm/decode-neon-shared.inc.c: $(SRC_PATH)/target/arm/neon-shared.decode $(DECODETREE)
$(call quiet-command,\
$(PYTHON) $(DECODETREE) --static-decode disas_neon_shared -o $@ $<,\
"GEN", $(TARGET_DIR)$@)
target/arm/decode-neon-dp.inc.c: $(SRC_PATH)/target/arm/neon-dp.decode $(DECODETREE)
$(call quiet-command,\
$(PYTHON) $(DECODETREE) --static-decode disas_neon_dp -o $@ $<,\
"GEN", $(TARGET_DIR)$@)
target/arm/decode-neon-ls.inc.c: $(SRC_PATH)/target/arm/neon-ls.decode $(DECODETREE)
$(call quiet-command,\
$(PYTHON) $(DECODETREE) --static-decode disas_neon_ls -o $@ $<,\
"GEN", $(TARGET_DIR)$@)
target/arm/decode-vfp.inc.c: $(SRC_PATH)/target/arm/vfp.decode $(DECODETREE) target/arm/decode-vfp.inc.c: $(SRC_PATH)/target/arm/vfp.decode $(DECODETREE)
$(call quiet-command,\ $(call quiet-command,\
$(PYTHON) $(DECODETREE) --static-decode disas_vfp -o $@ $<,\ $(PYTHON) $(DECODETREE) --static-decode disas_vfp -o $@ $<,\
@ -49,6 +64,9 @@ target/arm/decode-t16.inc.c: $(SRC_PATH)/target/arm/t16.decode $(DECODETREE)
"GEN", $(TARGET_DIR)$@) "GEN", $(TARGET_DIR)$@)
target/arm/translate-sve.o: target/arm/decode-sve.inc.c target/arm/translate-sve.o: target/arm/decode-sve.inc.c
target/arm/translate.o: target/arm/decode-neon-shared.inc.c
target/arm/translate.o: target/arm/decode-neon-dp.inc.c
target/arm/translate.o: target/arm/decode-neon-ls.inc.c
target/arm/translate.o: target/arm/decode-vfp.inc.c target/arm/translate.o: target/arm/decode-vfp.inc.c
target/arm/translate.o: target/arm/decode-vfp-uncond.inc.c target/arm/translate.o: target/arm/decode-vfp-uncond.inc.c
target/arm/translate.o: target/arm/decode-a32.inc.c target/arm/translate.o: target/arm/decode-a32.inc.c

29
target/arm/neon-dp.decode Normal file
View File

@ -0,0 +1,29 @@
# AArch32 Neon data-processing instruction descriptions
#
# Copyright (c) 2020 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 <http://www.gnu.org/licenses/>.
#
# This file is processed by scripts/decodetree.py
#
# Encodings for Neon data processing instructions where the T32 encoding
# is a simple transformation of the A32 encoding.
# More specifically, this file covers instructions where the A32 encoding is
# 0b1111_001p_qqqq_qqqq_qqqq_qqqq_qqqq_qqqq
# and the T32 encoding is
# 0b111p_1111_qqqq_qqqq_qqqq_qqqq_qqqq_qqqq
# This file works on the A32 encoding only; calling code for T32 has to
# transform the insn into the A32 version first.

29
target/arm/neon-ls.decode Normal file
View File

@ -0,0 +1,29 @@
# AArch32 Neon load/store instruction descriptions
#
# Copyright (c) 2020 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 <http://www.gnu.org/licenses/>.
#
# This file is processed by scripts/decodetree.py
#
# Encodings for Neon load/store instructions where the T32 encoding
# is a simple transformation of the A32 encoding.
# More specifically, this file covers instructions where the A32 encoding is
# 0b1111_0100_xxx0_xxxx_xxxx_xxxx_xxxx_xxxx
# and the T32 encoding is
# 0b1111_1001_xxx0_xxxx_xxxx_xxxx_xxxx_xxxx
# This file works on the A32 encoding only; calling code for T32 has to
# transform the insn into the A32 version first.

View File

@ -0,0 +1,27 @@
# AArch32 Neon instruction descriptions
#
# Copyright (c) 2020 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 <http://www.gnu.org/licenses/>.
#
# This file is processed by scripts/decodetree.py
#
# Encodings for Neon instructions whose encoding is the same for
# both A32 and T32.
# More specifically, this covers:
# 2reg scalar ext: 0b1111_1110_xxxx_xxxx_xxxx_1x0x_xxxx_xxxx
# 3same ext: 0b1111_110x_xxxx_xxxx_xxxx_1x0x_xxxx_xxxx

View File

@ -0,0 +1,32 @@
/*
* ARM translation: AArch32 Neon instructions
*
* Copyright (c) 2003 Fabrice Bellard
* Copyright (c) 2005-2007 CodeSourcery
* Copyright (c) 2007 OpenedHand, Ltd.
* Copyright (c) 2020 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 <http://www.gnu.org/licenses/>.
*/
/*
* This file is intended to be included from translate.c; it uses
* some macros and definitions provided by that file.
* It might be possible to convert it to a standalone .c file eventually.
*/
/* Include the generated Neon decoder */
#include "decode-neon-dp.inc.c"
#include "decode-neon-ls.inc.c"
#include "decode-neon-shared.inc.c"

View File

@ -1313,8 +1313,9 @@ static TCGv_ptr vfp_reg_ptr(bool dp, int reg)
#define ARM_CP_RW_BIT (1 << 20) #define ARM_CP_RW_BIT (1 << 20)
/* Include the VFP decoder */ /* Include the VFP and Neon decoders */
#include "translate-vfp.inc.c" #include "translate-vfp.inc.c"
#include "translate-neon.inc.c"
static inline void iwmmxt_load_reg(TCGv_i64 var, int reg) static inline void iwmmxt_load_reg(TCGv_i64 var, int reg)
{ {
@ -10949,7 +10950,10 @@ static void disas_arm_insn(DisasContext *s, unsigned int insn)
/* Unconditional instructions. */ /* Unconditional instructions. */
/* TODO: Perhaps merge these into one decodetree output file. */ /* TODO: Perhaps merge these into one decodetree output file. */
if (disas_a32_uncond(s, insn) || if (disas_a32_uncond(s, insn) ||
disas_vfp_uncond(s, insn)) { disas_vfp_uncond(s, insn) ||
disas_neon_dp(s, insn) ||
disas_neon_ls(s, insn) ||
disas_neon_shared(s, insn)) {
return; return;
} }
/* fall back to legacy decoder */ /* fall back to legacy decoder */
@ -11102,6 +11106,33 @@ static void disas_thumb2_insn(DisasContext *s, uint32_t insn)
ARCH(6T2); ARCH(6T2);
} }
if ((insn & 0xef000000) == 0xef000000) {
/*
* T32 encodings 0b111p_1111_qqqq_qqqq_qqqq_qqqq_qqqq_qqqq
* transform into
* A32 encodings 0b1111_001p_qqqq_qqqq_qqqq_qqqq_qqqq_qqqq
*/
uint32_t a32_insn = (insn & 0xe2ffffff) |
((insn & (1 << 28)) >> 4) | (1 << 28);
if (disas_neon_dp(s, a32_insn)) {
return;
}
}
if ((insn & 0xff100000) == 0xf9000000) {
/*
* T32 encodings 0b1111_1001_ppp0_qqqq_qqqq_qqqq_qqqq_qqqq
* transform into
* A32 encodings 0b1111_0100_ppp0_qqqq_qqqq_qqqq_qqqq_qqqq
*/
uint32_t a32_insn = (insn & 0x00ffffff) | 0xf4000000;
if (disas_neon_ls(s, a32_insn)) {
return;
}
}
/* /*
* TODO: Perhaps merge these into one decodetree output file. * TODO: Perhaps merge these into one decodetree output file.
* Note disas_vfp is written for a32 with cond field in the * Note disas_vfp is written for a32 with cond field in the
@ -11109,6 +11140,7 @@ static void disas_thumb2_insn(DisasContext *s, uint32_t insn)
*/ */
if (disas_t32(s, insn) || if (disas_t32(s, insn) ||
disas_vfp_uncond(s, insn) || disas_vfp_uncond(s, insn) ||
disas_neon_shared(s, insn) ||
((insn >> 28) == 0xe && disas_vfp(s, insn))) { ((insn >> 28) == 0xe && disas_vfp(s, insn))) {
return; return;
} }