1
From 3e80439264f306f75173ccd5ebc6c8939521d328 Mon Sep 17 00:00:00 2001
2
From: Claudio Fontana <claudio.fontana@linaro.org>
3
Date: Tue, 17 Dec 2013 19:42:32 +0000
4
Subject: [PATCH 29/49] target-arm: A64: provide skeleton for a64 insn decoding
6
Provide a skeleton for a64 instruction decoding in translate-a64.c,
7
by dividing instructions into the classes defined by the
8
ARM Architecture Reference Manual(DDI0487A_a) section C3.
10
Signed-off-by: Claudio Fontana <claudio.fontana@linaro.org>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Reviewed-by: Richard Henderson <rth@twiddle.net>
14
target-arm/translate-a64.c | 370 ++++++++++++++++++++++++++++++++++++++++++++-
15
1 file changed, 362 insertions(+), 8 deletions(-)
17
diff --git a/target-arm/translate-a64.c b/target-arm/translate-a64.c
18
index a713137..8e16cb1 100644
19
--- a/target-arm/translate-a64.c
20
+++ b/target-arm/translate-a64.c
21
@@ -146,17 +146,348 @@ static inline void gen_goto_tb(DisasContext *s, int n, uint64_t dest)
25
-static void real_unallocated_encoding(DisasContext *s)
26
+static void unallocated_encoding(DisasContext *s)
28
- fprintf(stderr, "Unknown instruction: %#x\n", s->insn);
29
gen_exception_insn(s, 4, EXCP_UDEF);
32
-#define unallocated_encoding(s) do { \
33
- fprintf(stderr, "unallocated encoding at line: %d\n", __LINE__); \
34
- real_unallocated_encoding(s); \
36
+#define unsupported_encoding(s, insn) \
38
+ qemu_log_mask(LOG_UNIMP, \
39
+ "%s:%d: unsupported instruction encoding 0x%08x " \
40
+ "at pc=%016" PRIx64 "\n", \
41
+ __FILE__, __LINE__, insn, s->pc - 4); \
42
+ unallocated_encoding(s); \
46
+ * the instruction disassembly implemented here matches
47
+ * the instruction encoding classifications in chapter 3 (C3)
48
+ * of the ARM Architecture Reference Manual (DDI0487A_a)
51
+/* Unconditional branch (immediate) */
52
+static void disas_uncond_b_imm(DisasContext *s, uint32_t insn)
54
+ unsupported_encoding(s, insn);
57
+/* Compare & branch (immediate) */
58
+static void disas_comp_b_imm(DisasContext *s, uint32_t insn)
60
+ unsupported_encoding(s, insn);
63
+/* Test & branch (immediate) */
64
+static void disas_test_b_imm(DisasContext *s, uint32_t insn)
66
+ unsupported_encoding(s, insn);
69
+/* Conditional branch (immediate) */
70
+static void disas_cond_b_imm(DisasContext *s, uint32_t insn)
72
+ unsupported_encoding(s, insn);
76
+static void disas_system(DisasContext *s, uint32_t insn)
78
+ unsupported_encoding(s, insn);
81
+/* Exception generation */
82
+static void disas_exc(DisasContext *s, uint32_t insn)
84
+ unsupported_encoding(s, insn);
87
+/* Unconditional branch (register) */
88
+static void disas_uncond_b_reg(DisasContext *s, uint32_t insn)
90
+ unsupported_encoding(s, insn);
93
+/* C3.2 Branches, exception generating and system instructions */
94
+static void disas_b_exc_sys(DisasContext *s, uint32_t insn)
96
+ switch (extract32(insn, 25, 7)) {
97
+ case 0x0a: case 0x0b:
98
+ case 0x4a: case 0x4b: /* Unconditional branch (immediate) */
99
+ disas_uncond_b_imm(s, insn);
101
+ case 0x1a: case 0x5a: /* Compare & branch (immediate) */
102
+ disas_comp_b_imm(s, insn);
104
+ case 0x1b: case 0x5b: /* Test & branch (immediate) */
105
+ disas_test_b_imm(s, insn);
107
+ case 0x2a: /* Conditional branch (immediate) */
108
+ disas_cond_b_imm(s, insn);
110
+ case 0x6a: /* Exception generation / System */
111
+ if (insn & (1 << 24)) {
112
+ disas_system(s, insn);
114
+ disas_exc(s, insn);
117
+ case 0x6b: /* Unconditional branch (register) */
118
+ disas_uncond_b_reg(s, insn);
121
+ unallocated_encoding(s);
126
+/* Load/store exclusive */
127
+static void disas_ldst_excl(DisasContext *s, uint32_t insn)
129
+ unsupported_encoding(s, insn);
132
+/* Load register (literal) */
133
+static void disas_ld_lit(DisasContext *s, uint32_t insn)
135
+ unsupported_encoding(s, insn);
138
+/* Load/store pair (all forms) */
139
+static void disas_ldst_pair(DisasContext *s, uint32_t insn)
141
+ unsupported_encoding(s, insn);
144
+/* Load/store register (all forms) */
145
+static void disas_ldst_reg(DisasContext *s, uint32_t insn)
147
+ unsupported_encoding(s, insn);
150
+/* AdvSIMD load/store multiple structures */
151
+static void disas_ldst_multiple_struct(DisasContext *s, uint32_t insn)
153
+ unsupported_encoding(s, insn);
156
+/* AdvSIMD load/store single structure */
157
+static void disas_ldst_single_struct(DisasContext *s, uint32_t insn)
159
+ unsupported_encoding(s, insn);
162
+/* C3.3 Loads and stores */
163
+static void disas_ldst(DisasContext *s, uint32_t insn)
165
+ switch (extract32(insn, 24, 6)) {
166
+ case 0x08: /* Load/store exclusive */
167
+ disas_ldst_excl(s, insn);
169
+ case 0x18: case 0x1c: /* Load register (literal) */
170
+ disas_ld_lit(s, insn);
172
+ case 0x28: case 0x29:
173
+ case 0x2c: case 0x2d: /* Load/store pair (all forms) */
174
+ disas_ldst_pair(s, insn);
176
+ case 0x38: case 0x39:
177
+ case 0x3c: case 0x3d: /* Load/store register (all forms) */
178
+ disas_ldst_reg(s, insn);
180
+ case 0x0c: /* AdvSIMD load/store multiple structures */
181
+ disas_ldst_multiple_struct(s, insn);
183
+ case 0x0d: /* AdvSIMD load/store single structure */
184
+ disas_ldst_single_struct(s, insn);
187
+ unallocated_encoding(s);
192
+/* PC-rel. addressing */
193
+static void disas_pc_rel_adr(DisasContext *s, uint32_t insn)
195
+ unsupported_encoding(s, insn);
198
+/* Add/subtract (immediate) */
199
+static void disas_add_sub_imm(DisasContext *s, uint32_t insn)
201
+ unsupported_encoding(s, insn);
204
+/* Logical (immediate) */
205
+static void disas_logic_imm(DisasContext *s, uint32_t insn)
207
+ unsupported_encoding(s, insn);
210
+/* Move wide (immediate) */
211
+static void disas_movw_imm(DisasContext *s, uint32_t insn)
213
+ unsupported_encoding(s, insn);
217
+static void disas_bitfield(DisasContext *s, uint32_t insn)
219
+ unsupported_encoding(s, insn);
223
+static void disas_extract(DisasContext *s, uint32_t insn)
225
+ unsupported_encoding(s, insn);
228
+/* C3.4 Data processing - immediate */
229
+static void disas_data_proc_imm(DisasContext *s, uint32_t insn)
231
+ switch (extract32(insn, 23, 6)) {
232
+ case 0x20: case 0x21: /* PC-rel. addressing */
233
+ disas_pc_rel_adr(s, insn);
235
+ case 0x22: case 0x23: /* Add/subtract (immediate) */
236
+ disas_add_sub_imm(s, insn);
238
+ case 0x24: /* Logical (immediate) */
239
+ disas_logic_imm(s, insn);
241
+ case 0x25: /* Move wide (immediate) */
242
+ disas_movw_imm(s, insn);
244
+ case 0x26: /* Bitfield */
245
+ disas_bitfield(s, insn);
247
+ case 0x27: /* Extract */
248
+ disas_extract(s, insn);
251
+ unallocated_encoding(s);
256
+/* Logical (shifted register) */
257
+static void disas_logic_reg(DisasContext *s, uint32_t insn)
259
+ unsupported_encoding(s, insn);
262
+/* Add/subtract (extended register) */
263
+static void disas_add_sub_ext_reg(DisasContext *s, uint32_t insn)
265
+ unsupported_encoding(s, insn);
268
+/* Add/subtract (shifted register) */
269
+static void disas_add_sub_reg(DisasContext *s, uint32_t insn)
271
+ unsupported_encoding(s, insn);
274
+/* Data-processing (3 source) */
275
+static void disas_data_proc_3src(DisasContext *s, uint32_t insn)
277
+ unsupported_encoding(s, insn);
280
+/* Add/subtract (with carry) */
281
+static void disas_adc_sbc(DisasContext *s, uint32_t insn)
283
+ unsupported_encoding(s, insn);
286
+/* Conditional compare (immediate) */
287
+static void disas_cc_imm(DisasContext *s, uint32_t insn)
289
+ unsupported_encoding(s, insn);
292
+/* Conditional compare (register) */
293
+static void disas_cc_reg(DisasContext *s, uint32_t insn)
295
+ unsupported_encoding(s, insn);
298
+/* Conditional select */
299
+static void disas_cond_select(DisasContext *s, uint32_t insn)
301
+ unsupported_encoding(s, insn);
304
+/* Data-processing (1 source) */
305
+static void disas_data_proc_1src(DisasContext *s, uint32_t insn)
307
+ unsupported_encoding(s, insn);
310
+/* Data-processing (2 source) */
311
+static void disas_data_proc_2src(DisasContext *s, uint32_t insn)
313
+ unsupported_encoding(s, insn);
316
+/* C3.5 Data processing - register */
317
+static void disas_data_proc_reg(DisasContext *s, uint32_t insn)
319
+ switch (extract32(insn, 24, 5)) {
320
+ case 0x0a: /* Logical (shifted register) */
321
+ disas_logic_reg(s, insn);
323
+ case 0x0b: /* Add/subtract */
324
+ if (insn & (1 << 21)) { /* (extended register) */
325
+ disas_add_sub_ext_reg(s, insn);
327
+ disas_add_sub_reg(s, insn);
330
+ case 0x1b: /* Data-processing (3 source) */
331
+ disas_data_proc_3src(s, insn);
334
+ switch (extract32(insn, 21, 3)) {
335
+ case 0x0: /* Add/subtract (with carry) */
336
+ disas_adc_sbc(s, insn);
338
+ case 0x2: /* Conditional compare */
339
+ if (insn & (1 << 11)) { /* (immediate) */
340
+ disas_cc_imm(s, insn);
341
+ } else { /* (register) */
342
+ disas_cc_reg(s, insn);
345
+ case 0x4: /* Conditional select */
346
+ disas_cond_select(s, insn);
348
+ case 0x6: /* Data-processing */
349
+ if (insn & (1 << 30)) { /* (1 source) */
350
+ disas_data_proc_1src(s, insn);
351
+ } else { /* (2 source) */
352
+ disas_data_proc_2src(s, insn);
356
+ unallocated_encoding(s);
361
+ unallocated_encoding(s);
366
+/* C3.6 Data processing - SIMD and floating point */
367
+static void disas_data_proc_simd_fp(DisasContext *s, uint32_t insn)
369
+ unsupported_encoding(s, insn);
372
+/* C3.1 A64 instruction index by encoding */
373
static void disas_a64_insn(CPUARMState *env, DisasContext *s)
376
@@ -165,10 +496,33 @@ static void disas_a64_insn(CPUARMState *env, DisasContext *s)
380
- switch ((insn >> 24) & 0x1f) {
382
+ switch (extract32(insn, 25, 4)) {
383
+ case 0x0: case 0x1: case 0x2: case 0x3: /* UNALLOCATED */
384
unallocated_encoding(s);
386
+ case 0x8: case 0x9: /* Data processing - immediate */
387
+ disas_data_proc_imm(s, insn);
389
+ case 0xa: case 0xb: /* Branch, exception generation and system insns */
390
+ disas_b_exc_sys(s, insn);
395
+ case 0xe: /* Loads and stores */
396
+ disas_ldst(s, insn);
399
+ case 0xd: /* Data processing - register */
400
+ disas_data_proc_reg(s, insn);
403
+ case 0xf: /* Data processing - SIMD and floating point */
404
+ disas_data_proc_simd_fp(s, insn);
407
+ assert(FALSE); /* all 15 cases should be handled above */