1
From d3b0b46e22de9f2b8855232d792c4e8568016205 Mon Sep 17 00:00:00 2001
2
From: Claudio Fontana <claudio.fontana@linaro.org>
3
Date: Tue, 17 Dec 2013 19:42:35 +0000
4
Subject: [PATCH 45/49] target-arm: A64: add support for bitfield insns
6
This patch implements the C3.4.2 Bitfield instructions:
9
Signed-off-by: Claudio Fontana <claudio.fontana@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Reviewed-by: Richard Henderson <rth@twiddle.net>
13
target-arm/translate-a64.c | 56 ++++++++++++++++++++++++++++++++++++++++++++--
14
1 file changed, 54 insertions(+), 2 deletions(-)
16
diff --git a/target-arm/translate-a64.c b/target-arm/translate-a64.c
17
index 3c702a9..2111bcd 100644
18
--- a/target-arm/translate-a64.c
19
+++ b/target-arm/translate-a64.c
20
@@ -698,10 +698,62 @@ static void disas_movw_imm(DisasContext *s, uint32_t insn)
21
unsupported_encoding(s, insn);
26
+ * 31 30 29 28 23 22 21 16 15 10 9 5 4 0
27
+ * +----+-----+-------------+---+------+------+------+------+
28
+ * | sf | opc | 1 0 0 1 1 0 | N | immr | imms | Rn | Rd |
29
+ * +----+-----+-------------+---+------+------+------+------+
31
static void disas_bitfield(DisasContext *s, uint32_t insn)
33
- unsupported_encoding(s, insn);
34
+ unsigned int sf, n, opc, ri, si, rn, rd, bitsize, pos, len;
35
+ TCGv_i64 tcg_rd, tcg_tmp;
37
+ sf = extract32(insn, 31, 1);
38
+ opc = extract32(insn, 29, 2);
39
+ n = extract32(insn, 22, 1);
40
+ ri = extract32(insn, 16, 6);
41
+ si = extract32(insn, 10, 6);
42
+ rn = extract32(insn, 5, 5);
43
+ rd = extract32(insn, 0, 5);
44
+ bitsize = sf ? 64 : 32;
46
+ if (sf != n || ri >= bitsize || si >= bitsize || opc > 2) {
47
+ unallocated_encoding(s);
51
+ tcg_rd = cpu_reg(s, rd);
52
+ tcg_tmp = read_cpu_reg(s, rn, sf);
54
+ /* OPTME: probably worth recognizing common cases of ext{8,16,32}{u,s} */
56
+ if (opc != 1) { /* SBFM or UBFM */
57
+ tcg_gen_movi_i64(tcg_rd, 0);
60
+ /* do the bit move operation */
62
+ /* Wd<s-r:0> = Wn<s:r> */
63
+ tcg_gen_shri_i64(tcg_tmp, tcg_tmp, ri);
65
+ len = (si - ri) + 1;
67
+ /* Wd<32+s-r,32-r> = Wn<s:0> */
72
+ tcg_gen_deposit_i64(tcg_rd, tcg_rd, tcg_tmp, pos, len);
74
+ if (opc == 0) { /* SBFM - sign extend the destination field */
75
+ tcg_gen_shli_i64(tcg_rd, tcg_rd, 64 - (pos + len));
76
+ tcg_gen_sari_i64(tcg_rd, tcg_rd, 64 - (pos + len));
79
+ if (!sf) { /* zero extend final result */
80
+ tcg_gen_ext32u_i64(tcg_rd, tcg_rd);