From: Peter Maydell <peter.maydell@linaro.org>
To: qemu-devel@nongnu.org
Cc: patches@linaro.org, "Michael Matz" <matz@suse.de>,
"Alexander Graf" <agraf@suse.de>,
"Claudio Fontana" <claudio.fontana@linaro.org>,
"Dirk Mueller" <dmueller@suse.de>,
"Will Newton" <will.newton@linaro.org>,
"Laurent Desnogues" <laurent.desnogues@gmail.com>,
"Alex Bennée" <alex.bennee@linaro.org>,
kvmarm@lists.cs.columbia.edu,
"Christoffer Dall" <christoffer.dall@linaro.org>,
"Richard Henderson" <rth@twiddle.net>
Subject: [Qemu-devel] [PATCH 02/10] target-arm: A64: Add SIMD ld/st single
Date: Fri, 10 Jan 2014 17:12:44 +0000 [thread overview]
Message-ID: <1389373972-27686-3-git-send-email-peter.maydell@linaro.org> (raw)
In-Reply-To: <1389373972-27686-1-git-send-email-peter.maydell@linaro.org>
Implement the SIMD ld/st single structure instructions.
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
target-arm/translate-a64.c | 141 ++++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 139 insertions(+), 2 deletions(-)
diff --git a/target-arm/translate-a64.c b/target-arm/translate-a64.c
index 4482e73..ee56588 100644
--- a/target-arm/translate-a64.c
+++ b/target-arm/translate-a64.c
@@ -2084,10 +2084,147 @@ static void disas_ldst_multiple_struct(DisasContext *s, uint32_t insn)
}
}
-/* AdvSIMD load/store single structure */
+/* C3.3.3 AdvSIMD load/store single structure
+ *
+ * 31 30 29 23 22 21 20 16 15 13 12 11 10 9 5 4 0
+ * +---+---+---------------+-----+-----------+-----+---+------+------+------+
+ * | 0 | Q | 0 0 1 1 0 1 0 | L R | 0 0 0 0 0 | opc | S | size | Rn | Rt |
+ * +---+---+---------------+-----+-----------+-----+---+------+------+------+
+ *
+ * C3.3.4 AdvSIMD load/store single structure (post-indexed)
+ *
+ * 31 30 29 23 22 21 20 16 15 13 12 11 10 9 5 4 0
+ * +---+---+---------------+-----+-----------+-----+---+------+------+------+
+ * | 0 | Q | 0 0 1 1 0 1 1 | L R | Rm | opc | S | size | Rn | Rt |
+ * +---+---+---------------+-----+-----------+-----+---+------+------+------+
+ *
+ * Rt: first (or only) SIMD&FP register to be transferred
+ * Rn: base address or SP
+ * Rm (post-index only): post-index register (when !31) or size dependent #imm
+ * index = encoded in Q:S:size dependent on size
+ *
+ * lane_size = encoded in R, opc
+ * transfer width = encoded in opc, S, size
+ */
static void disas_ldst_single_struct(DisasContext *s, uint32_t insn)
{
- unsupported_encoding(s, insn);
+ int rt = extract32(insn, 0, 5);
+ int rn = extract32(insn, 5, 5);
+ int size = extract32(insn, 10, 2);
+ int S = extract32(insn, 12, 1);
+ int opc = extract32(insn, 13, 3);
+ int R = extract32(insn, 21, 1);
+ int is_load = extract32(insn, 22, 1);
+ int is_postidx = extract32(insn, 23, 1);
+ int is_q = extract32(insn, 30, 1);
+
+ int scale = extract32(opc, 1, 2);
+ int selem = (extract32(opc, 0, 1) << 1 | R) + 1;
+ bool replicate = false;
+ int index = is_q << 3 | S << 2 | size;
+ int ebytes, xs;
+ TCGv_i64 tcg_addr;
+
+ switch (scale) {
+ case 3:
+ if (!is_load || S) {
+ unallocated_encoding(s);
+ return;
+ }
+ scale = size;
+ replicate = true;
+ break;
+ case 0:
+ break;
+ case 1:
+ if (extract32(size, 0, 1)) {
+ unallocated_encoding(s);
+ return;
+ }
+ index >>= 1;
+ break;
+ case 2:
+ if (extract32(size, 1, 1)) {
+ unallocated_encoding(s);
+ return;
+ }
+ if (!extract32(size, 0, 1)) {
+ index >>= 2;
+ } else {
+ if (S) {
+ unallocated_encoding(s);
+ return;
+ }
+ index >>= 3;
+ scale = 3;
+ }
+ break;
+ default:
+ g_assert_not_reached();
+ }
+
+ ebytes = 1 << scale;
+
+ tcg_addr = read_cpu_reg_sp(s, rn, 1);
+
+ if (rn == 31) {
+ gen_check_sp_alignment(s);
+ }
+
+ for (xs = 0; xs < selem; xs++) {
+ if (replicate) {
+ /* Load and replicate to all elements */
+ uint64_t mulconst;
+ TCGv_i64 tcg_tmp = tcg_temp_new_i64();
+
+ tcg_gen_qemu_ld_i64(tcg_tmp, tcg_addr,
+ get_mem_index(s), MO_TE + scale);
+ switch (scale) {
+ case 0:
+ mulconst = 0x0101010101010101ULL;
+ break;
+ case 1:
+ mulconst = 0x0001000100010001ULL;
+ break;
+ case 2:
+ mulconst = 0x0000000100000001ULL;
+ break;
+ case 3:
+ mulconst = 0;
+ break;
+ default:
+ g_assert_not_reached();
+ }
+ if (mulconst) {
+ tcg_gen_muli_i64(tcg_tmp, tcg_tmp, mulconst);
+ }
+ write_vec_element(s, tcg_tmp, rt, 0, MO_64);
+ if (is_q) {
+ write_vec_element(s, tcg_tmp, rt, 1, MO_64);
+ } else {
+ clear_vec_high(s, rt);
+ }
+ tcg_temp_free_i64(tcg_tmp);
+ } else {
+ /* Load/store one element per register */
+ if (is_load) {
+ do_vec_ld(s, rt, index, tcg_addr, MO_TE + scale);
+ } else {
+ do_vec_st(s, rt, index, tcg_addr, MO_TE + scale);
+ }
+ }
+ tcg_gen_addi_i64(tcg_addr, tcg_addr, ebytes);
+ rt = (rt + 1) % 32;
+ }
+
+ if (is_postidx) {
+ int rm = extract32(insn, 16, 5);
+ if (rm == 31) {
+ tcg_gen_mov_i64(cpu_reg_sp(s, rn), tcg_addr);
+ } else {
+ tcg_gen_add_i64(cpu_reg_sp(s, rn), cpu_reg(s, rn), cpu_reg(s, rm));
+ }
+ }
}
/* C3.3 Loads and stores */
--
1.8.5
next prev parent reply other threads:[~2014-01-10 17:13 UTC|newest]
Thread overview: 30+ messages / expand[flat|nested] mbox.gz Atom feed top
2014-01-10 17:12 [Qemu-devel] [PATCH 00/10] A64 SIMD patchset one: ld/st, C3.6.1..C3.6.7 Peter Maydell
2014-01-10 17:12 ` [Qemu-devel] [PATCH 01/10] target-arm: A64: Add SIMD ld/st multiple Peter Maydell
2014-01-10 18:05 ` Richard Henderson
2014-01-10 18:18 ` Peter Maydell
2014-01-10 18:28 ` Richard Henderson
2014-01-10 18:37 ` Peter Maydell
2014-01-10 19:00 ` Richard Henderson
2014-01-10 17:12 ` Peter Maydell [this message]
2014-01-10 18:12 ` [Qemu-devel] [PATCH 02/10] target-arm: A64: Add SIMD ld/st single Richard Henderson
2014-01-10 17:12 ` [Qemu-devel] [PATCH 03/10] target-arm: A64: Add decode skeleton for SIMD data processing insns Peter Maydell
2014-01-10 18:55 ` Richard Henderson
2014-01-10 19:05 ` Richard Henderson
2014-01-11 0:01 ` Peter Maydell
2014-01-10 17:12 ` [Qemu-devel] [PATCH 04/10] target-arm: A64: Add SIMD EXT Peter Maydell
2014-01-10 19:13 ` Richard Henderson
2014-01-10 17:12 ` [Qemu-devel] [PATCH 05/10] target-arm: A64: Add SIMD TBL/TBLX Peter Maydell
2014-01-10 19:19 ` Richard Henderson
2014-01-10 17:12 ` [Qemu-devel] [PATCH 06/10] target-arm: A64: Add SIMD ZIP/UZP/TRN Peter Maydell
2014-01-10 19:29 ` Richard Henderson
2014-01-11 8:30 ` Alex Bennée
2014-01-10 17:12 ` [Qemu-devel] [PATCH 07/10] target-arm: A64: Add SIMD across-lanes instructions Peter Maydell
2014-01-10 19:38 ` Richard Henderson
2014-01-10 17:12 ` [Qemu-devel] [PATCH 08/10] target-arm: A64: Add SIMD copy operations Peter Maydell
2014-01-10 19:50 ` Richard Henderson
2014-01-10 17:12 ` [Qemu-devel] [PATCH 09/10] target-arm: A64: Add SIMD modified immediate group Peter Maydell
2014-01-10 20:00 ` Richard Henderson
2014-01-10 17:12 ` [Qemu-devel] [PATCH 10/10] target-arm: A64: Add SIMD scalar copy instructions Peter Maydell
2014-01-10 20:03 ` Richard Henderson
2014-01-15 15:10 ` Claudio Fontana
2014-01-15 18:01 ` Peter Maydell
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1389373972-27686-3-git-send-email-peter.maydell@linaro.org \
--to=peter.maydell@linaro.org \
--cc=agraf@suse.de \
--cc=alex.bennee@linaro.org \
--cc=christoffer.dall@linaro.org \
--cc=claudio.fontana@linaro.org \
--cc=dmueller@suse.de \
--cc=kvmarm@lists.cs.columbia.edu \
--cc=laurent.desnogues@gmail.com \
--cc=matz@suse.de \
--cc=patches@linaro.org \
--cc=qemu-devel@nongnu.org \
--cc=rth@twiddle.net \
--cc=will.newton@linaro.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).