]> Git Repo - qemu.git/blob - target-arm/translate-a64.c
target-arm: A64: Implement minimal set of EL0-visible sysregs
[qemu.git] / target-arm / translate-a64.c
1 /*
2  *  AArch64 translation
3  *
4  *  Copyright (c) 2013 Alexander Graf <[email protected]>
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, see <http://www.gnu.org/licenses/>.
18  */
19 #include <stdarg.h>
20 #include <stdlib.h>
21 #include <stdio.h>
22 #include <string.h>
23 #include <inttypes.h>
24
25 #include "cpu.h"
26 #include "tcg-op.h"
27 #include "qemu/log.h"
28 #include "translate.h"
29 #include "qemu/host-utils.h"
30
31 #include "exec/gen-icount.h"
32
33 #include "helper.h"
34 #define GEN_HELPER 1
35 #include "helper.h"
36
37 static TCGv_i64 cpu_X[32];
38 static TCGv_i64 cpu_pc;
39 static TCGv_i32 cpu_NF, cpu_ZF, cpu_CF, cpu_VF;
40
41 static const char *regnames[] = {
42     "x0", "x1", "x2", "x3", "x4", "x5", "x6", "x7",
43     "x8", "x9", "x10", "x11", "x12", "x13", "x14", "x15",
44     "x16", "x17", "x18", "x19", "x20", "x21", "x22", "x23",
45     "x24", "x25", "x26", "x27", "x28", "x29", "lr", "sp"
46 };
47
48 enum a64_shift_type {
49     A64_SHIFT_TYPE_LSL = 0,
50     A64_SHIFT_TYPE_LSR = 1,
51     A64_SHIFT_TYPE_ASR = 2,
52     A64_SHIFT_TYPE_ROR = 3
53 };
54
55 /* initialize TCG globals.  */
56 void a64_translate_init(void)
57 {
58     int i;
59
60     cpu_pc = tcg_global_mem_new_i64(TCG_AREG0,
61                                     offsetof(CPUARMState, pc),
62                                     "pc");
63     for (i = 0; i < 32; i++) {
64         cpu_X[i] = tcg_global_mem_new_i64(TCG_AREG0,
65                                           offsetof(CPUARMState, xregs[i]),
66                                           regnames[i]);
67     }
68
69     cpu_NF = tcg_global_mem_new_i32(TCG_AREG0, offsetof(CPUARMState, NF), "NF");
70     cpu_ZF = tcg_global_mem_new_i32(TCG_AREG0, offsetof(CPUARMState, ZF), "ZF");
71     cpu_CF = tcg_global_mem_new_i32(TCG_AREG0, offsetof(CPUARMState, CF), "CF");
72     cpu_VF = tcg_global_mem_new_i32(TCG_AREG0, offsetof(CPUARMState, VF), "VF");
73 }
74
75 void aarch64_cpu_dump_state(CPUState *cs, FILE *f,
76                             fprintf_function cpu_fprintf, int flags)
77 {
78     ARMCPU *cpu = ARM_CPU(cs);
79     CPUARMState *env = &cpu->env;
80     uint32_t psr = pstate_read(env);
81     int i;
82
83     cpu_fprintf(f, "PC=%016"PRIx64"  SP=%016"PRIx64"\n",
84             env->pc, env->xregs[31]);
85     for (i = 0; i < 31; i++) {
86         cpu_fprintf(f, "X%02d=%016"PRIx64, i, env->xregs[i]);
87         if ((i % 4) == 3) {
88             cpu_fprintf(f, "\n");
89         } else {
90             cpu_fprintf(f, " ");
91         }
92     }
93     cpu_fprintf(f, "PSTATE=%08x (flags %c%c%c%c)\n",
94                 psr,
95                 psr & PSTATE_N ? 'N' : '-',
96                 psr & PSTATE_Z ? 'Z' : '-',
97                 psr & PSTATE_C ? 'C' : '-',
98                 psr & PSTATE_V ? 'V' : '-');
99     cpu_fprintf(f, "\n");
100 }
101
102 static int get_mem_index(DisasContext *s)
103 {
104 #ifdef CONFIG_USER_ONLY
105     return 1;
106 #else
107     return s->user;
108 #endif
109 }
110
111 void gen_a64_set_pc_im(uint64_t val)
112 {
113     tcg_gen_movi_i64(cpu_pc, val);
114 }
115
116 static void gen_exception(int excp)
117 {
118     TCGv_i32 tmp = tcg_temp_new_i32();
119     tcg_gen_movi_i32(tmp, excp);
120     gen_helper_exception(cpu_env, tmp);
121     tcg_temp_free_i32(tmp);
122 }
123
124 static void gen_exception_insn(DisasContext *s, int offset, int excp)
125 {
126     gen_a64_set_pc_im(s->pc - offset);
127     gen_exception(excp);
128     s->is_jmp = DISAS_EXC;
129 }
130
131 static inline bool use_goto_tb(DisasContext *s, int n, uint64_t dest)
132 {
133     /* No direct tb linking with singlestep or deterministic io */
134     if (s->singlestep_enabled || (s->tb->cflags & CF_LAST_IO)) {
135         return false;
136     }
137
138     /* Only link tbs from inside the same guest page */
139     if ((s->tb->pc & TARGET_PAGE_MASK) != (dest & TARGET_PAGE_MASK)) {
140         return false;
141     }
142
143     return true;
144 }
145
146 static inline void gen_goto_tb(DisasContext *s, int n, uint64_t dest)
147 {
148     TranslationBlock *tb;
149
150     tb = s->tb;
151     if (use_goto_tb(s, n, dest)) {
152         tcg_gen_goto_tb(n);
153         gen_a64_set_pc_im(dest);
154         tcg_gen_exit_tb((tcg_target_long)tb + n);
155         s->is_jmp = DISAS_TB_JUMP;
156     } else {
157         gen_a64_set_pc_im(dest);
158         if (s->singlestep_enabled) {
159             gen_exception(EXCP_DEBUG);
160         }
161         tcg_gen_exit_tb(0);
162         s->is_jmp = DISAS_JUMP;
163     }
164 }
165
166 static void unallocated_encoding(DisasContext *s)
167 {
168     gen_exception_insn(s, 4, EXCP_UDEF);
169 }
170
171 #define unsupported_encoding(s, insn)                                    \
172     do {                                                                 \
173         qemu_log_mask(LOG_UNIMP,                                         \
174                       "%s:%d: unsupported instruction encoding 0x%08x "  \
175                       "at pc=%016" PRIx64 "\n",                          \
176                       __FILE__, __LINE__, insn, s->pc - 4);              \
177         unallocated_encoding(s);                                         \
178     } while (0);
179
180 static void init_tmp_a64_array(DisasContext *s)
181 {
182 #ifdef CONFIG_DEBUG_TCG
183     int i;
184     for (i = 0; i < ARRAY_SIZE(s->tmp_a64); i++) {
185         TCGV_UNUSED_I64(s->tmp_a64[i]);
186     }
187 #endif
188     s->tmp_a64_count = 0;
189 }
190
191 static void free_tmp_a64(DisasContext *s)
192 {
193     int i;
194     for (i = 0; i < s->tmp_a64_count; i++) {
195         tcg_temp_free_i64(s->tmp_a64[i]);
196     }
197     init_tmp_a64_array(s);
198 }
199
200 static TCGv_i64 new_tmp_a64(DisasContext *s)
201 {
202     assert(s->tmp_a64_count < TMP_A64_MAX);
203     return s->tmp_a64[s->tmp_a64_count++] = tcg_temp_new_i64();
204 }
205
206 static TCGv_i64 new_tmp_a64_zero(DisasContext *s)
207 {
208     TCGv_i64 t = new_tmp_a64(s);
209     tcg_gen_movi_i64(t, 0);
210     return t;
211 }
212
213 /*
214  * Register access functions
215  *
216  * These functions are used for directly accessing a register in where
217  * changes to the final register value are likely to be made. If you
218  * need to use a register for temporary calculation (e.g. index type
219  * operations) use the read_* form.
220  *
221  * B1.2.1 Register mappings
222  *
223  * In instruction register encoding 31 can refer to ZR (zero register) or
224  * the SP (stack pointer) depending on context. In QEMU's case we map SP
225  * to cpu_X[31] and ZR accesses to a temporary which can be discarded.
226  * This is the point of the _sp forms.
227  */
228 static TCGv_i64 cpu_reg(DisasContext *s, int reg)
229 {
230     if (reg == 31) {
231         return new_tmp_a64_zero(s);
232     } else {
233         return cpu_X[reg];
234     }
235 }
236
237 /* register access for when 31 == SP */
238 static TCGv_i64 cpu_reg_sp(DisasContext *s, int reg)
239 {
240     return cpu_X[reg];
241 }
242
243 /* read a cpu register in 32bit/64bit mode. Returns a TCGv_i64
244  * representing the register contents. This TCGv is an auto-freed
245  * temporary so it need not be explicitly freed, and may be modified.
246  */
247 static TCGv_i64 read_cpu_reg(DisasContext *s, int reg, int sf)
248 {
249     TCGv_i64 v = new_tmp_a64(s);
250     if (reg != 31) {
251         if (sf) {
252             tcg_gen_mov_i64(v, cpu_X[reg]);
253         } else {
254             tcg_gen_ext32u_i64(v, cpu_X[reg]);
255         }
256     } else {
257         tcg_gen_movi_i64(v, 0);
258     }
259     return v;
260 }
261
262 static TCGv_i64 read_cpu_reg_sp(DisasContext *s, int reg, int sf)
263 {
264     TCGv_i64 v = new_tmp_a64(s);
265     if (sf) {
266         tcg_gen_mov_i64(v, cpu_X[reg]);
267     } else {
268         tcg_gen_ext32u_i64(v, cpu_X[reg]);
269     }
270     return v;
271 }
272
273 /* Set ZF and NF based on a 64 bit result. This is alas fiddlier
274  * than the 32 bit equivalent.
275  */
276 static inline void gen_set_NZ64(TCGv_i64 result)
277 {
278     TCGv_i64 flag = tcg_temp_new_i64();
279
280     tcg_gen_setcondi_i64(TCG_COND_NE, flag, result, 0);
281     tcg_gen_trunc_i64_i32(cpu_ZF, flag);
282     tcg_gen_shri_i64(flag, result, 32);
283     tcg_gen_trunc_i64_i32(cpu_NF, flag);
284     tcg_temp_free_i64(flag);
285 }
286
287 /* Set NZCV as for a logical operation: NZ as per result, CV cleared. */
288 static inline void gen_logic_CC(int sf, TCGv_i64 result)
289 {
290     if (sf) {
291         gen_set_NZ64(result);
292     } else {
293         tcg_gen_trunc_i64_i32(cpu_ZF, result);
294         tcg_gen_trunc_i64_i32(cpu_NF, result);
295     }
296     tcg_gen_movi_i32(cpu_CF, 0);
297     tcg_gen_movi_i32(cpu_VF, 0);
298 }
299
300 /* dest = T0 + T1; compute C, N, V and Z flags */
301 static void gen_add_CC(int sf, TCGv_i64 dest, TCGv_i64 t0, TCGv_i64 t1)
302 {
303     if (sf) {
304         TCGv_i64 result, flag, tmp;
305         result = tcg_temp_new_i64();
306         flag = tcg_temp_new_i64();
307         tmp = tcg_temp_new_i64();
308
309         tcg_gen_movi_i64(tmp, 0);
310         tcg_gen_add2_i64(result, flag, t0, tmp, t1, tmp);
311
312         tcg_gen_trunc_i64_i32(cpu_CF, flag);
313
314         gen_set_NZ64(result);
315
316         tcg_gen_xor_i64(flag, result, t0);
317         tcg_gen_xor_i64(tmp, t0, t1);
318         tcg_gen_andc_i64(flag, flag, tmp);
319         tcg_temp_free_i64(tmp);
320         tcg_gen_shri_i64(flag, flag, 32);
321         tcg_gen_trunc_i64_i32(cpu_VF, flag);
322
323         tcg_gen_mov_i64(dest, result);
324         tcg_temp_free_i64(result);
325         tcg_temp_free_i64(flag);
326     } else {
327         /* 32 bit arithmetic */
328         TCGv_i32 t0_32 = tcg_temp_new_i32();
329         TCGv_i32 t1_32 = tcg_temp_new_i32();
330         TCGv_i32 tmp = tcg_temp_new_i32();
331
332         tcg_gen_movi_i32(tmp, 0);
333         tcg_gen_trunc_i64_i32(t0_32, t0);
334         tcg_gen_trunc_i64_i32(t1_32, t1);
335         tcg_gen_add2_i32(cpu_NF, cpu_CF, t0_32, tmp, t1_32, tmp);
336         tcg_gen_mov_i32(cpu_ZF, cpu_NF);
337         tcg_gen_xor_i32(cpu_VF, cpu_NF, t0_32);
338         tcg_gen_xor_i32(tmp, t0_32, t1_32);
339         tcg_gen_andc_i32(cpu_VF, cpu_VF, tmp);
340         tcg_gen_extu_i32_i64(dest, cpu_NF);
341
342         tcg_temp_free_i32(tmp);
343         tcg_temp_free_i32(t0_32);
344         tcg_temp_free_i32(t1_32);
345     }
346 }
347
348 /* dest = T0 - T1; compute C, N, V and Z flags */
349 static void gen_sub_CC(int sf, TCGv_i64 dest, TCGv_i64 t0, TCGv_i64 t1)
350 {
351     if (sf) {
352         /* 64 bit arithmetic */
353         TCGv_i64 result, flag, tmp;
354
355         result = tcg_temp_new_i64();
356         flag = tcg_temp_new_i64();
357         tcg_gen_sub_i64(result, t0, t1);
358
359         gen_set_NZ64(result);
360
361         tcg_gen_setcond_i64(TCG_COND_GEU, flag, t0, t1);
362         tcg_gen_trunc_i64_i32(cpu_CF, flag);
363
364         tcg_gen_xor_i64(flag, result, t0);
365         tmp = tcg_temp_new_i64();
366         tcg_gen_xor_i64(tmp, t0, t1);
367         tcg_gen_and_i64(flag, flag, tmp);
368         tcg_temp_free_i64(tmp);
369         tcg_gen_shri_i64(flag, flag, 32);
370         tcg_gen_trunc_i64_i32(cpu_VF, flag);
371         tcg_gen_mov_i64(dest, result);
372         tcg_temp_free_i64(flag);
373         tcg_temp_free_i64(result);
374     } else {
375         /* 32 bit arithmetic */
376         TCGv_i32 t0_32 = tcg_temp_new_i32();
377         TCGv_i32 t1_32 = tcg_temp_new_i32();
378         TCGv_i32 tmp;
379
380         tcg_gen_trunc_i64_i32(t0_32, t0);
381         tcg_gen_trunc_i64_i32(t1_32, t1);
382         tcg_gen_sub_i32(cpu_NF, t0_32, t1_32);
383         tcg_gen_mov_i32(cpu_ZF, cpu_NF);
384         tcg_gen_setcond_i32(TCG_COND_GEU, cpu_CF, t0_32, t1_32);
385         tcg_gen_xor_i32(cpu_VF, cpu_NF, t0_32);
386         tmp = tcg_temp_new_i32();
387         tcg_gen_xor_i32(tmp, t0_32, t1_32);
388         tcg_temp_free_i32(t0_32);
389         tcg_temp_free_i32(t1_32);
390         tcg_gen_and_i32(cpu_VF, cpu_VF, tmp);
391         tcg_temp_free_i32(tmp);
392         tcg_gen_extu_i32_i64(dest, cpu_NF);
393     }
394 }
395
396 /*
397  * Load/Store generators
398  */
399
400 /*
401  * Store from GPR register to memory
402  */
403 static void do_gpr_st(DisasContext *s, TCGv_i64 source,
404                       TCGv_i64 tcg_addr, int size)
405 {
406     g_assert(size <= 3);
407     tcg_gen_qemu_st_i64(source, tcg_addr, get_mem_index(s), MO_TE + size);
408 }
409
410 /*
411  * Load from memory to GPR register
412  */
413 static void do_gpr_ld(DisasContext *s, TCGv_i64 dest, TCGv_i64 tcg_addr,
414                       int size, bool is_signed, bool extend)
415 {
416     TCGMemOp memop = MO_TE + size;
417
418     g_assert(size <= 3);
419
420     if (is_signed) {
421         memop += MO_SIGN;
422     }
423
424     tcg_gen_qemu_ld_i64(dest, tcg_addr, get_mem_index(s), memop);
425
426     if (extend && is_signed) {
427         g_assert(size < 3);
428         tcg_gen_ext32u_i64(dest, dest);
429     }
430 }
431
432 /*
433  * Store from FP register to memory
434  */
435 static void do_fp_st(DisasContext *s, int srcidx, TCGv_i64 tcg_addr, int size)
436 {
437     /* This writes the bottom N bits of a 128 bit wide vector to memory */
438     int freg_offs = offsetof(CPUARMState, vfp.regs[srcidx * 2]);
439     TCGv_i64 tmp = tcg_temp_new_i64();
440
441     if (size < 4) {
442         switch (size) {
443         case 0:
444             tcg_gen_ld8u_i64(tmp, cpu_env, freg_offs);
445             break;
446         case 1:
447             tcg_gen_ld16u_i64(tmp, cpu_env, freg_offs);
448             break;
449         case 2:
450             tcg_gen_ld32u_i64(tmp, cpu_env, freg_offs);
451             break;
452         case 3:
453             tcg_gen_ld_i64(tmp, cpu_env, freg_offs);
454             break;
455         }
456         tcg_gen_qemu_st_i64(tmp, tcg_addr, get_mem_index(s), MO_TE + size);
457     } else {
458         TCGv_i64 tcg_hiaddr = tcg_temp_new_i64();
459         tcg_gen_ld_i64(tmp, cpu_env, freg_offs);
460         tcg_gen_qemu_st_i64(tmp, tcg_addr, get_mem_index(s), MO_TEQ);
461         tcg_gen_qemu_st64(tmp, tcg_addr, get_mem_index(s));
462         tcg_gen_ld_i64(tmp, cpu_env, freg_offs + sizeof(float64));
463         tcg_gen_addi_i64(tcg_hiaddr, tcg_addr, 8);
464         tcg_gen_qemu_st_i64(tmp, tcg_hiaddr, get_mem_index(s), MO_TEQ);
465         tcg_temp_free_i64(tcg_hiaddr);
466     }
467
468     tcg_temp_free_i64(tmp);
469 }
470
471 /*
472  * Load from memory to FP register
473  */
474 static void do_fp_ld(DisasContext *s, int destidx, TCGv_i64 tcg_addr, int size)
475 {
476     /* This always zero-extends and writes to a full 128 bit wide vector */
477     int freg_offs = offsetof(CPUARMState, vfp.regs[destidx * 2]);
478     TCGv_i64 tmplo = tcg_temp_new_i64();
479     TCGv_i64 tmphi;
480
481     if (size < 4) {
482         TCGMemOp memop = MO_TE + size;
483         tmphi = tcg_const_i64(0);
484         tcg_gen_qemu_ld_i64(tmplo, tcg_addr, get_mem_index(s), memop);
485     } else {
486         TCGv_i64 tcg_hiaddr;
487         tmphi = tcg_temp_new_i64();
488         tcg_hiaddr = tcg_temp_new_i64();
489
490         tcg_gen_qemu_ld_i64(tmplo, tcg_addr, get_mem_index(s), MO_TEQ);
491         tcg_gen_addi_i64(tcg_hiaddr, tcg_addr, 8);
492         tcg_gen_qemu_ld_i64(tmphi, tcg_hiaddr, get_mem_index(s), MO_TEQ);
493         tcg_temp_free_i64(tcg_hiaddr);
494     }
495
496     tcg_gen_st_i64(tmplo, cpu_env, freg_offs);
497     tcg_gen_st_i64(tmphi, cpu_env, freg_offs + sizeof(float64));
498
499     tcg_temp_free_i64(tmplo);
500     tcg_temp_free_i64(tmphi);
501 }
502
503 /*
504  * This utility function is for doing register extension with an
505  * optional shift. You will likely want to pass a temporary for the
506  * destination register. See DecodeRegExtend() in the ARM ARM.
507  */
508 static void ext_and_shift_reg(TCGv_i64 tcg_out, TCGv_i64 tcg_in,
509                               int option, unsigned int shift)
510 {
511     int extsize = extract32(option, 0, 2);
512     bool is_signed = extract32(option, 2, 1);
513
514     if (is_signed) {
515         switch (extsize) {
516         case 0:
517             tcg_gen_ext8s_i64(tcg_out, tcg_in);
518             break;
519         case 1:
520             tcg_gen_ext16s_i64(tcg_out, tcg_in);
521             break;
522         case 2:
523             tcg_gen_ext32s_i64(tcg_out, tcg_in);
524             break;
525         case 3:
526             tcg_gen_mov_i64(tcg_out, tcg_in);
527             break;
528         }
529     } else {
530         switch (extsize) {
531         case 0:
532             tcg_gen_ext8u_i64(tcg_out, tcg_in);
533             break;
534         case 1:
535             tcg_gen_ext16u_i64(tcg_out, tcg_in);
536             break;
537         case 2:
538             tcg_gen_ext32u_i64(tcg_out, tcg_in);
539             break;
540         case 3:
541             tcg_gen_mov_i64(tcg_out, tcg_in);
542             break;
543         }
544     }
545
546     if (shift) {
547         tcg_gen_shli_i64(tcg_out, tcg_out, shift);
548     }
549 }
550
551 static inline void gen_check_sp_alignment(DisasContext *s)
552 {
553     /* The AArch64 architecture mandates that (if enabled via PSTATE
554      * or SCTLR bits) there is a check that SP is 16-aligned on every
555      * SP-relative load or store (with an exception generated if it is not).
556      * In line with general QEMU practice regarding misaligned accesses,
557      * we omit these checks for the sake of guest program performance.
558      * This function is provided as a hook so we can more easily add these
559      * checks in future (possibly as a "favour catching guest program bugs
560      * over speed" user selectable option).
561      */
562 }
563
564 /*
565  * the instruction disassembly implemented here matches
566  * the instruction encoding classifications in chapter 3 (C3)
567  * of the ARM Architecture Reference Manual (DDI0487A_a)
568  */
569
570 /* C3.2.7 Unconditional branch (immediate)
571  *   31  30       26 25                                  0
572  * +----+-----------+-------------------------------------+
573  * | op | 0 0 1 0 1 |                 imm26               |
574  * +----+-----------+-------------------------------------+
575  */
576 static void disas_uncond_b_imm(DisasContext *s, uint32_t insn)
577 {
578     uint64_t addr = s->pc + sextract32(insn, 0, 26) * 4 - 4;
579
580     if (insn & (1 << 31)) {
581         /* C5.6.26 BL Branch with link */
582         tcg_gen_movi_i64(cpu_reg(s, 30), s->pc);
583     }
584
585     /* C5.6.20 B Branch / C5.6.26 BL Branch with link */
586     gen_goto_tb(s, 0, addr);
587 }
588
589 /* C3.2.1 Compare & branch (immediate)
590  *   31  30         25  24  23                  5 4      0
591  * +----+-------------+----+---------------------+--------+
592  * | sf | 0 1 1 0 1 0 | op |         imm19       |   Rt   |
593  * +----+-------------+----+---------------------+--------+
594  */
595 static void disas_comp_b_imm(DisasContext *s, uint32_t insn)
596 {
597     unsigned int sf, op, rt;
598     uint64_t addr;
599     int label_match;
600     TCGv_i64 tcg_cmp;
601
602     sf = extract32(insn, 31, 1);
603     op = extract32(insn, 24, 1); /* 0: CBZ; 1: CBNZ */
604     rt = extract32(insn, 0, 5);
605     addr = s->pc + sextract32(insn, 5, 19) * 4 - 4;
606
607     tcg_cmp = read_cpu_reg(s, rt, sf);
608     label_match = gen_new_label();
609
610     tcg_gen_brcondi_i64(op ? TCG_COND_NE : TCG_COND_EQ,
611                         tcg_cmp, 0, label_match);
612
613     gen_goto_tb(s, 0, s->pc);
614     gen_set_label(label_match);
615     gen_goto_tb(s, 1, addr);
616 }
617
618 /* C3.2.5 Test & branch (immediate)
619  *   31  30         25  24  23   19 18          5 4    0
620  * +----+-------------+----+-------+-------------+------+
621  * | b5 | 0 1 1 0 1 1 | op |  b40  |    imm14    |  Rt  |
622  * +----+-------------+----+-------+-------------+------+
623  */
624 static void disas_test_b_imm(DisasContext *s, uint32_t insn)
625 {
626     unsigned int bit_pos, op, rt;
627     uint64_t addr;
628     int label_match;
629     TCGv_i64 tcg_cmp;
630
631     bit_pos = (extract32(insn, 31, 1) << 5) | extract32(insn, 19, 5);
632     op = extract32(insn, 24, 1); /* 0: TBZ; 1: TBNZ */
633     addr = s->pc + sextract32(insn, 5, 14) * 4 - 4;
634     rt = extract32(insn, 0, 5);
635
636     tcg_cmp = tcg_temp_new_i64();
637     tcg_gen_andi_i64(tcg_cmp, cpu_reg(s, rt), (1ULL << bit_pos));
638     label_match = gen_new_label();
639     tcg_gen_brcondi_i64(op ? TCG_COND_NE : TCG_COND_EQ,
640                         tcg_cmp, 0, label_match);
641     tcg_temp_free_i64(tcg_cmp);
642     gen_goto_tb(s, 0, s->pc);
643     gen_set_label(label_match);
644     gen_goto_tb(s, 1, addr);
645 }
646
647 /* C3.2.2 / C5.6.19 Conditional branch (immediate)
648  *  31           25  24  23                  5   4  3    0
649  * +---------------+----+---------------------+----+------+
650  * | 0 1 0 1 0 1 0 | o1 |         imm19       | o0 | cond |
651  * +---------------+----+---------------------+----+------+
652  */
653 static void disas_cond_b_imm(DisasContext *s, uint32_t insn)
654 {
655     unsigned int cond;
656     uint64_t addr;
657
658     if ((insn & (1 << 4)) || (insn & (1 << 24))) {
659         unallocated_encoding(s);
660         return;
661     }
662     addr = s->pc + sextract32(insn, 5, 19) * 4 - 4;
663     cond = extract32(insn, 0, 4);
664
665     if (cond < 0x0e) {
666         /* genuinely conditional branches */
667         int label_match = gen_new_label();
668         arm_gen_test_cc(cond, label_match);
669         gen_goto_tb(s, 0, s->pc);
670         gen_set_label(label_match);
671         gen_goto_tb(s, 1, addr);
672     } else {
673         /* 0xe and 0xf are both "always" conditions */
674         gen_goto_tb(s, 0, addr);
675     }
676 }
677
678 /* C5.6.68 HINT */
679 static void handle_hint(DisasContext *s, uint32_t insn,
680                         unsigned int op1, unsigned int op2, unsigned int crm)
681 {
682     unsigned int selector = crm << 3 | op2;
683
684     if (op1 != 3) {
685         unallocated_encoding(s);
686         return;
687     }
688
689     switch (selector) {
690     case 0: /* NOP */
691         return;
692     case 1: /* YIELD */
693     case 2: /* WFE */
694     case 3: /* WFI */
695     case 4: /* SEV */
696     case 5: /* SEVL */
697         /* we treat all as NOP at least for now */
698         return;
699     default:
700         /* default specified as NOP equivalent */
701         return;
702     }
703 }
704
705 /* CLREX, DSB, DMB, ISB */
706 static void handle_sync(DisasContext *s, uint32_t insn,
707                         unsigned int op1, unsigned int op2, unsigned int crm)
708 {
709     if (op1 != 3) {
710         unallocated_encoding(s);
711         return;
712     }
713
714     switch (op2) {
715     case 2: /* CLREX */
716         unsupported_encoding(s, insn);
717         return;
718     case 4: /* DSB */
719     case 5: /* DMB */
720     case 6: /* ISB */
721         /* We don't emulate caches so barriers are no-ops */
722         return;
723     default:
724         unallocated_encoding(s);
725         return;
726     }
727 }
728
729 /* C5.6.130 MSR (immediate) - move immediate to processor state field */
730 static void handle_msr_i(DisasContext *s, uint32_t insn,
731                          unsigned int op1, unsigned int op2, unsigned int crm)
732 {
733     unsupported_encoding(s, insn);
734 }
735
736 static void gen_get_nzcv(TCGv_i64 tcg_rt)
737 {
738     TCGv_i32 tmp = tcg_temp_new_i32();
739     TCGv_i32 nzcv = tcg_temp_new_i32();
740
741     /* build bit 31, N */
742     tcg_gen_andi_i32(nzcv, cpu_NF, (1 << 31));
743     /* build bit 30, Z */
744     tcg_gen_setcondi_i32(TCG_COND_EQ, tmp, cpu_ZF, 0);
745     tcg_gen_deposit_i32(nzcv, nzcv, tmp, 30, 1);
746     /* build bit 29, C */
747     tcg_gen_deposit_i32(nzcv, nzcv, cpu_CF, 29, 1);
748     /* build bit 28, V */
749     tcg_gen_shri_i32(tmp, cpu_VF, 31);
750     tcg_gen_deposit_i32(nzcv, nzcv, tmp, 28, 1);
751     /* generate result */
752     tcg_gen_extu_i32_i64(tcg_rt, nzcv);
753
754     tcg_temp_free_i32(nzcv);
755     tcg_temp_free_i32(tmp);
756 }
757
758 static void gen_set_nzcv(TCGv_i64 tcg_rt)
759
760 {
761     TCGv_i32 nzcv = tcg_temp_new_i32();
762
763     /* take NZCV from R[t] */
764     tcg_gen_trunc_i64_i32(nzcv, tcg_rt);
765
766     /* bit 31, N */
767     tcg_gen_andi_i32(cpu_NF, nzcv, (1 << 31));
768     /* bit 30, Z */
769     tcg_gen_andi_i32(cpu_ZF, nzcv, (1 << 30));
770     tcg_gen_setcondi_i32(TCG_COND_EQ, cpu_ZF, cpu_ZF, 0);
771     /* bit 29, C */
772     tcg_gen_andi_i32(cpu_CF, nzcv, (1 << 29));
773     tcg_gen_shri_i32(cpu_CF, cpu_CF, 29);
774     /* bit 28, V */
775     tcg_gen_andi_i32(cpu_VF, nzcv, (1 << 28));
776     tcg_gen_shli_i32(cpu_VF, cpu_VF, 3);
777     tcg_temp_free_i32(nzcv);
778 }
779
780 /* C5.6.129 MRS - move from system register
781  * C5.6.131 MSR (register) - move to system register
782  * C5.6.204 SYS
783  * C5.6.205 SYSL
784  * These are all essentially the same insn in 'read' and 'write'
785  * versions, with varying op0 fields.
786  */
787 static void handle_sys(DisasContext *s, uint32_t insn, bool isread,
788                        unsigned int op0, unsigned int op1, unsigned int op2,
789                        unsigned int crn, unsigned int crm, unsigned int rt)
790 {
791     const ARMCPRegInfo *ri;
792     TCGv_i64 tcg_rt;
793
794     ri = get_arm_cp_reginfo(s->cp_regs,
795                             ENCODE_AA64_CP_REG(CP_REG_ARM64_SYSREG_CP,
796                                                crn, crm, op0, op1, op2));
797
798     if (!ri) {
799         /* Unknown register */
800         unallocated_encoding(s);
801         return;
802     }
803
804     /* Check access permissions */
805     if (!cp_access_ok(s->current_pl, ri, isread)) {
806         unallocated_encoding(s);
807         return;
808     }
809
810     /* Handle special cases first */
811     switch (ri->type & ~(ARM_CP_FLAG_MASK & ~ARM_CP_SPECIAL)) {
812     case ARM_CP_NOP:
813         return;
814     case ARM_CP_NZCV:
815         tcg_rt = cpu_reg(s, rt);
816         if (isread) {
817             gen_get_nzcv(tcg_rt);
818         } else {
819             gen_set_nzcv(tcg_rt);
820         }
821         return;
822     default:
823         break;
824     }
825
826     if (use_icount && (ri->type & ARM_CP_IO)) {
827         gen_io_start();
828     }
829
830     tcg_rt = cpu_reg(s, rt);
831
832     if (isread) {
833         if (ri->type & ARM_CP_CONST) {
834             tcg_gen_movi_i64(tcg_rt, ri->resetvalue);
835         } else if (ri->readfn) {
836             TCGv_ptr tmpptr;
837             gen_a64_set_pc_im(s->pc - 4);
838             tmpptr = tcg_const_ptr(ri);
839             gen_helper_get_cp_reg64(tcg_rt, cpu_env, tmpptr);
840             tcg_temp_free_ptr(tmpptr);
841         } else {
842             tcg_gen_ld_i64(tcg_rt, cpu_env, ri->fieldoffset);
843         }
844     } else {
845         if (ri->type & ARM_CP_CONST) {
846             /* If not forbidden by access permissions, treat as WI */
847             return;
848         } else if (ri->writefn) {
849             TCGv_ptr tmpptr;
850             gen_a64_set_pc_im(s->pc - 4);
851             tmpptr = tcg_const_ptr(ri);
852             gen_helper_set_cp_reg64(cpu_env, tmpptr, tcg_rt);
853             tcg_temp_free_ptr(tmpptr);
854         } else {
855             tcg_gen_st_i64(tcg_rt, cpu_env, ri->fieldoffset);
856         }
857     }
858
859     if (use_icount && (ri->type & ARM_CP_IO)) {
860         /* I/O operations must end the TB here (whether read or write) */
861         gen_io_end();
862         s->is_jmp = DISAS_UPDATE;
863     } else if (!isread && !(ri->type & ARM_CP_SUPPRESS_TB_END)) {
864         /* We default to ending the TB on a coprocessor register write,
865          * but allow this to be suppressed by the register definition
866          * (usually only necessary to work around guest bugs).
867          */
868         s->is_jmp = DISAS_UPDATE;
869     }
870 }
871
872 /* C3.2.4 System
873  *  31                 22 21  20 19 18 16 15   12 11    8 7   5 4    0
874  * +---------------------+---+-----+-----+-------+-------+-----+------+
875  * | 1 1 0 1 0 1 0 1 0 0 | L | op0 | op1 |  CRn  |  CRm  | op2 |  Rt  |
876  * +---------------------+---+-----+-----+-------+-------+-----+------+
877  */
878 static void disas_system(DisasContext *s, uint32_t insn)
879 {
880     unsigned int l, op0, op1, crn, crm, op2, rt;
881     l = extract32(insn, 21, 1);
882     op0 = extract32(insn, 19, 2);
883     op1 = extract32(insn, 16, 3);
884     crn = extract32(insn, 12, 4);
885     crm = extract32(insn, 8, 4);
886     op2 = extract32(insn, 5, 3);
887     rt = extract32(insn, 0, 5);
888
889     if (op0 == 0) {
890         if (l || rt != 31) {
891             unallocated_encoding(s);
892             return;
893         }
894         switch (crn) {
895         case 2: /* C5.6.68 HINT */
896             handle_hint(s, insn, op1, op2, crm);
897             break;
898         case 3: /* CLREX, DSB, DMB, ISB */
899             handle_sync(s, insn, op1, op2, crm);
900             break;
901         case 4: /* C5.6.130 MSR (immediate) */
902             handle_msr_i(s, insn, op1, op2, crm);
903             break;
904         default:
905             unallocated_encoding(s);
906             break;
907         }
908         return;
909     }
910     handle_sys(s, insn, l, op0, op1, op2, crn, crm, rt);
911 }
912
913 /* C3.2.3 Exception generation
914  *
915  *  31             24 23 21 20                     5 4   2 1  0
916  * +-----------------+-----+------------------------+-----+----+
917  * | 1 1 0 1 0 1 0 0 | opc |          imm16         | op2 | LL |
918  * +-----------------------+------------------------+----------+
919  */
920 static void disas_exc(DisasContext *s, uint32_t insn)
921 {
922     int opc = extract32(insn, 21, 3);
923     int op2_ll = extract32(insn, 0, 5);
924
925     switch (opc) {
926     case 0:
927         /* SVC, HVC, SMC; since we don't support the Virtualization
928          * or TrustZone extensions these all UNDEF except SVC.
929          */
930         if (op2_ll != 1) {
931             unallocated_encoding(s);
932             break;
933         }
934         gen_exception_insn(s, 0, EXCP_SWI);
935         break;
936     case 1:
937         if (op2_ll != 0) {
938             unallocated_encoding(s);
939             break;
940         }
941         /* BRK */
942         gen_exception_insn(s, 0, EXCP_BKPT);
943         break;
944     case 2:
945         if (op2_ll != 0) {
946             unallocated_encoding(s);
947             break;
948         }
949         /* HLT */
950         unsupported_encoding(s, insn);
951         break;
952     case 5:
953         if (op2_ll < 1 || op2_ll > 3) {
954             unallocated_encoding(s);
955             break;
956         }
957         /* DCPS1, DCPS2, DCPS3 */
958         unsupported_encoding(s, insn);
959         break;
960     default:
961         unallocated_encoding(s);
962         break;
963     }
964 }
965
966 /* C3.2.7 Unconditional branch (register)
967  *  31           25 24   21 20   16 15   10 9    5 4     0
968  * +---------------+-------+-------+-------+------+-------+
969  * | 1 1 0 1 0 1 1 |  opc  |  op2  |  op3  |  Rn  |  op4  |
970  * +---------------+-------+-------+-------+------+-------+
971  */
972 static void disas_uncond_b_reg(DisasContext *s, uint32_t insn)
973 {
974     unsigned int opc, op2, op3, rn, op4;
975
976     opc = extract32(insn, 21, 4);
977     op2 = extract32(insn, 16, 5);
978     op3 = extract32(insn, 10, 6);
979     rn = extract32(insn, 5, 5);
980     op4 = extract32(insn, 0, 5);
981
982     if (op4 != 0x0 || op3 != 0x0 || op2 != 0x1f) {
983         unallocated_encoding(s);
984         return;
985     }
986
987     switch (opc) {
988     case 0: /* BR */
989     case 2: /* RET */
990         break;
991     case 1: /* BLR */
992         tcg_gen_movi_i64(cpu_reg(s, 30), s->pc);
993         break;
994     case 4: /* ERET */
995     case 5: /* DRPS */
996         if (rn != 0x1f) {
997             unallocated_encoding(s);
998         } else {
999             unsupported_encoding(s, insn);
1000         }
1001         return;
1002     default:
1003         unallocated_encoding(s);
1004         return;
1005     }
1006
1007     tcg_gen_mov_i64(cpu_pc, cpu_reg(s, rn));
1008     s->is_jmp = DISAS_JUMP;
1009 }
1010
1011 /* C3.2 Branches, exception generating and system instructions */
1012 static void disas_b_exc_sys(DisasContext *s, uint32_t insn)
1013 {
1014     switch (extract32(insn, 25, 7)) {
1015     case 0x0a: case 0x0b:
1016     case 0x4a: case 0x4b: /* Unconditional branch (immediate) */
1017         disas_uncond_b_imm(s, insn);
1018         break;
1019     case 0x1a: case 0x5a: /* Compare & branch (immediate) */
1020         disas_comp_b_imm(s, insn);
1021         break;
1022     case 0x1b: case 0x5b: /* Test & branch (immediate) */
1023         disas_test_b_imm(s, insn);
1024         break;
1025     case 0x2a: /* Conditional branch (immediate) */
1026         disas_cond_b_imm(s, insn);
1027         break;
1028     case 0x6a: /* Exception generation / System */
1029         if (insn & (1 << 24)) {
1030             disas_system(s, insn);
1031         } else {
1032             disas_exc(s, insn);
1033         }
1034         break;
1035     case 0x6b: /* Unconditional branch (register) */
1036         disas_uncond_b_reg(s, insn);
1037         break;
1038     default:
1039         unallocated_encoding(s);
1040         break;
1041     }
1042 }
1043
1044 /* Load/store exclusive */
1045 static void disas_ldst_excl(DisasContext *s, uint32_t insn)
1046 {
1047     unsupported_encoding(s, insn);
1048 }
1049
1050 /* Load register (literal) */
1051 static void disas_ld_lit(DisasContext *s, uint32_t insn)
1052 {
1053     unsupported_encoding(s, insn);
1054 }
1055
1056 /*
1057  * C5.6.80 LDNP (Load Pair - non-temporal hint)
1058  * C5.6.81 LDP (Load Pair - non vector)
1059  * C5.6.82 LDPSW (Load Pair Signed Word - non vector)
1060  * C5.6.176 STNP (Store Pair - non-temporal hint)
1061  * C5.6.177 STP (Store Pair - non vector)
1062  * C6.3.165 LDNP (Load Pair of SIMD&FP - non-temporal hint)
1063  * C6.3.165 LDP (Load Pair of SIMD&FP)
1064  * C6.3.284 STNP (Store Pair of SIMD&FP - non-temporal hint)
1065  * C6.3.284 STP (Store Pair of SIMD&FP)
1066  *
1067  *  31 30 29   27  26  25 24   23  22 21   15 14   10 9    5 4    0
1068  * +-----+-------+---+---+-------+---+-----------------------------+
1069  * | opc | 1 0 1 | V | 0 | index | L |  imm7 |  Rt2  |  Rn  | Rt   |
1070  * +-----+-------+---+---+-------+---+-------+-------+------+------+
1071  *
1072  * opc: LDP/STP/LDNP/STNP        00 -> 32 bit, 10 -> 64 bit
1073  *      LDPSW                    01
1074  *      LDP/STP/LDNP/STNP (SIMD) 00 -> 32 bit, 01 -> 64 bit, 10 -> 128 bit
1075  *   V: 0 -> GPR, 1 -> Vector
1076  * idx: 00 -> signed offset with non-temporal hint, 01 -> post-index,
1077  *      10 -> signed offset, 11 -> pre-index
1078  *   L: 0 -> Store 1 -> Load
1079  *
1080  * Rt, Rt2 = GPR or SIMD registers to be stored
1081  * Rn = general purpose register containing address
1082  * imm7 = signed offset (multiple of 4 or 8 depending on size)
1083  */
1084 static void disas_ldst_pair(DisasContext *s, uint32_t insn)
1085 {
1086     int rt = extract32(insn, 0, 5);
1087     int rn = extract32(insn, 5, 5);
1088     int rt2 = extract32(insn, 10, 5);
1089     int64_t offset = sextract32(insn, 15, 7);
1090     int index = extract32(insn, 23, 2);
1091     bool is_vector = extract32(insn, 26, 1);
1092     bool is_load = extract32(insn, 22, 1);
1093     int opc = extract32(insn, 30, 2);
1094
1095     bool is_signed = false;
1096     bool postindex = false;
1097     bool wback = false;
1098
1099     TCGv_i64 tcg_addr; /* calculated address */
1100     int size;
1101
1102     if (opc == 3) {
1103         unallocated_encoding(s);
1104         return;
1105     }
1106
1107     if (is_vector) {
1108         size = 2 + opc;
1109     } else {
1110         size = 2 + extract32(opc, 1, 1);
1111         is_signed = extract32(opc, 0, 1);
1112         if (!is_load && is_signed) {
1113             unallocated_encoding(s);
1114             return;
1115         }
1116     }
1117
1118     switch (index) {
1119     case 1: /* post-index */
1120         postindex = true;
1121         wback = true;
1122         break;
1123     case 0:
1124         /* signed offset with "non-temporal" hint. Since we don't emulate
1125          * caches we don't care about hints to the cache system about
1126          * data access patterns, and handle this identically to plain
1127          * signed offset.
1128          */
1129         if (is_signed) {
1130             /* There is no non-temporal-hint version of LDPSW */
1131             unallocated_encoding(s);
1132             return;
1133         }
1134         postindex = false;
1135         break;
1136     case 2: /* signed offset, rn not updated */
1137         postindex = false;
1138         break;
1139     case 3: /* pre-index */
1140         postindex = false;
1141         wback = true;
1142         break;
1143     }
1144
1145     offset <<= size;
1146
1147     if (rn == 31) {
1148         gen_check_sp_alignment(s);
1149     }
1150
1151     tcg_addr = read_cpu_reg_sp(s, rn, 1);
1152
1153     if (!postindex) {
1154         tcg_gen_addi_i64(tcg_addr, tcg_addr, offset);
1155     }
1156
1157     if (is_vector) {
1158         if (is_load) {
1159             do_fp_ld(s, rt, tcg_addr, size);
1160         } else {
1161             do_fp_st(s, rt, tcg_addr, size);
1162         }
1163     } else {
1164         TCGv_i64 tcg_rt = cpu_reg(s, rt);
1165         if (is_load) {
1166             do_gpr_ld(s, tcg_rt, tcg_addr, size, is_signed, false);
1167         } else {
1168             do_gpr_st(s, tcg_rt, tcg_addr, size);
1169         }
1170     }
1171     tcg_gen_addi_i64(tcg_addr, tcg_addr, 1 << size);
1172     if (is_vector) {
1173         if (is_load) {
1174             do_fp_ld(s, rt2, tcg_addr, size);
1175         } else {
1176             do_fp_st(s, rt2, tcg_addr, size);
1177         }
1178     } else {
1179         TCGv_i64 tcg_rt2 = cpu_reg(s, rt2);
1180         if (is_load) {
1181             do_gpr_ld(s, tcg_rt2, tcg_addr, size, is_signed, false);
1182         } else {
1183             do_gpr_st(s, tcg_rt2, tcg_addr, size);
1184         }
1185     }
1186
1187     if (wback) {
1188         if (postindex) {
1189             tcg_gen_addi_i64(tcg_addr, tcg_addr, offset - (1 << size));
1190         } else {
1191             tcg_gen_subi_i64(tcg_addr, tcg_addr, 1 << size);
1192         }
1193         tcg_gen_mov_i64(cpu_reg_sp(s, rn), tcg_addr);
1194     }
1195 }
1196
1197 /*
1198  * C3.3.8 Load/store (immediate post-indexed)
1199  * C3.3.9 Load/store (immediate pre-indexed)
1200  * C3.3.12 Load/store (unscaled immediate)
1201  *
1202  * 31 30 29   27  26 25 24 23 22 21  20    12 11 10 9    5 4    0
1203  * +----+-------+---+-----+-----+---+--------+-----+------+------+
1204  * |size| 1 1 1 | V | 0 0 | opc | 0 |  imm9  | idx |  Rn  |  Rt  |
1205  * +----+-------+---+-----+-----+---+--------+-----+------+------+
1206  *
1207  * idx = 01 -> post-indexed, 11 pre-indexed, 00 unscaled imm. (no writeback)
1208  * V = 0 -> non-vector
1209  * size: 00 -> 8 bit, 01 -> 16 bit, 10 -> 32 bit, 11 -> 64bit
1210  * opc: 00 -> store, 01 -> loadu, 10 -> loads 64, 11 -> loads 32
1211  */
1212 static void disas_ldst_reg_imm9(DisasContext *s, uint32_t insn)
1213 {
1214     int rt = extract32(insn, 0, 5);
1215     int rn = extract32(insn, 5, 5);
1216     int imm9 = sextract32(insn, 12, 9);
1217     int opc = extract32(insn, 22, 2);
1218     int size = extract32(insn, 30, 2);
1219     int idx = extract32(insn, 10, 2);
1220     bool is_signed = false;
1221     bool is_store = false;
1222     bool is_extended = false;
1223     bool is_vector = extract32(insn, 26, 1);
1224     bool post_index;
1225     bool writeback;
1226
1227     TCGv_i64 tcg_addr;
1228
1229     if (is_vector) {
1230         size |= (opc & 2) << 1;
1231         if (size > 4) {
1232             unallocated_encoding(s);
1233             return;
1234         }
1235         is_store = ((opc & 1) == 0);
1236     } else {
1237         if (size == 3 && opc == 2) {
1238             /* PRFM - prefetch */
1239             return;
1240         }
1241         if (opc == 3 && size > 1) {
1242             unallocated_encoding(s);
1243             return;
1244         }
1245         is_store = (opc == 0);
1246         is_signed = opc & (1<<1);
1247         is_extended = (size < 3) && (opc & 1);
1248     }
1249
1250     switch (idx) {
1251     case 0:
1252         post_index = false;
1253         writeback = false;
1254         break;
1255     case 1:
1256         post_index = true;
1257         writeback = true;
1258         break;
1259     case 3:
1260         post_index = false;
1261         writeback = true;
1262         break;
1263     case 2:
1264         g_assert(false);
1265         break;
1266     }
1267
1268     if (rn == 31) {
1269         gen_check_sp_alignment(s);
1270     }
1271     tcg_addr = read_cpu_reg_sp(s, rn, 1);
1272
1273     if (!post_index) {
1274         tcg_gen_addi_i64(tcg_addr, tcg_addr, imm9);
1275     }
1276
1277     if (is_vector) {
1278         if (is_store) {
1279             do_fp_st(s, rt, tcg_addr, size);
1280         } else {
1281             do_fp_ld(s, rt, tcg_addr, size);
1282         }
1283     } else {
1284         TCGv_i64 tcg_rt = cpu_reg(s, rt);
1285         if (is_store) {
1286             do_gpr_st(s, tcg_rt, tcg_addr, size);
1287         } else {
1288             do_gpr_ld(s, tcg_rt, tcg_addr, size, is_signed, is_extended);
1289         }
1290     }
1291
1292     if (writeback) {
1293         TCGv_i64 tcg_rn = cpu_reg_sp(s, rn);
1294         if (post_index) {
1295             tcg_gen_addi_i64(tcg_addr, tcg_addr, imm9);
1296         }
1297         tcg_gen_mov_i64(tcg_rn, tcg_addr);
1298     }
1299 }
1300
1301 /*
1302  * C3.3.10 Load/store (register offset)
1303  *
1304  * 31 30 29   27  26 25 24 23 22 21  20  16 15 13 12 11 10 9  5 4  0
1305  * +----+-------+---+-----+-----+---+------+-----+--+-----+----+----+
1306  * |size| 1 1 1 | V | 0 0 | opc | 1 |  Rm  | opt | S| 1 0 | Rn | Rt |
1307  * +----+-------+---+-----+-----+---+------+-----+--+-----+----+----+
1308  *
1309  * For non-vector:
1310  *   size: 00-> byte, 01 -> 16 bit, 10 -> 32bit, 11 -> 64bit
1311  *   opc: 00 -> store, 01 -> loadu, 10 -> loads 64, 11 -> loads 32
1312  * For vector:
1313  *   size is opc<1>:size<1:0> so 100 -> 128 bit; 110 and 111 unallocated
1314  *   opc<0>: 0 -> store, 1 -> load
1315  * V: 1 -> vector/simd
1316  * opt: extend encoding (see DecodeRegExtend)
1317  * S: if S=1 then scale (essentially index by sizeof(size))
1318  * Rt: register to transfer into/out of
1319  * Rn: address register or SP for base
1320  * Rm: offset register or ZR for offset
1321  */
1322 static void disas_ldst_reg_roffset(DisasContext *s, uint32_t insn)
1323 {
1324     int rt = extract32(insn, 0, 5);
1325     int rn = extract32(insn, 5, 5);
1326     int shift = extract32(insn, 12, 1);
1327     int rm = extract32(insn, 16, 5);
1328     int opc = extract32(insn, 22, 2);
1329     int opt = extract32(insn, 13, 3);
1330     int size = extract32(insn, 30, 2);
1331     bool is_signed = false;
1332     bool is_store = false;
1333     bool is_extended = false;
1334     bool is_vector = extract32(insn, 26, 1);
1335
1336     TCGv_i64 tcg_rm;
1337     TCGv_i64 tcg_addr;
1338
1339     if (extract32(opt, 1, 1) == 0) {
1340         unallocated_encoding(s);
1341         return;
1342     }
1343
1344     if (is_vector) {
1345         size |= (opc & 2) << 1;
1346         if (size > 4) {
1347             unallocated_encoding(s);
1348             return;
1349         }
1350         is_store = !extract32(opc, 0, 1);
1351     } else {
1352         if (size == 3 && opc == 2) {
1353             /* PRFM - prefetch */
1354             return;
1355         }
1356         if (opc == 3 && size > 1) {
1357             unallocated_encoding(s);
1358             return;
1359         }
1360         is_store = (opc == 0);
1361         is_signed = extract32(opc, 1, 1);
1362         is_extended = (size < 3) && extract32(opc, 0, 1);
1363     }
1364
1365     if (rn == 31) {
1366         gen_check_sp_alignment(s);
1367     }
1368     tcg_addr = read_cpu_reg_sp(s, rn, 1);
1369
1370     tcg_rm = read_cpu_reg(s, rm, 1);
1371     ext_and_shift_reg(tcg_rm, tcg_rm, opt, shift ? size : 0);
1372
1373     tcg_gen_add_i64(tcg_addr, tcg_addr, tcg_rm);
1374
1375     if (is_vector) {
1376         if (is_store) {
1377             do_fp_st(s, rt, tcg_addr, size);
1378         } else {
1379             do_fp_ld(s, rt, tcg_addr, size);
1380         }
1381     } else {
1382         TCGv_i64 tcg_rt = cpu_reg(s, rt);
1383         if (is_store) {
1384             do_gpr_st(s, tcg_rt, tcg_addr, size);
1385         } else {
1386             do_gpr_ld(s, tcg_rt, tcg_addr, size, is_signed, is_extended);
1387         }
1388     }
1389 }
1390
1391 /*
1392  * C3.3.13 Load/store (unsigned immediate)
1393  *
1394  * 31 30 29   27  26 25 24 23 22 21        10 9     5
1395  * +----+-------+---+-----+-----+------------+-------+------+
1396  * |size| 1 1 1 | V | 0 1 | opc |   imm12    |  Rn   |  Rt  |
1397  * +----+-------+---+-----+-----+------------+-------+------+
1398  *
1399  * For non-vector:
1400  *   size: 00-> byte, 01 -> 16 bit, 10 -> 32bit, 11 -> 64bit
1401  *   opc: 00 -> store, 01 -> loadu, 10 -> loads 64, 11 -> loads 32
1402  * For vector:
1403  *   size is opc<1>:size<1:0> so 100 -> 128 bit; 110 and 111 unallocated
1404  *   opc<0>: 0 -> store, 1 -> load
1405  * Rn: base address register (inc SP)
1406  * Rt: target register
1407  */
1408 static void disas_ldst_reg_unsigned_imm(DisasContext *s, uint32_t insn)
1409 {
1410     int rt = extract32(insn, 0, 5);
1411     int rn = extract32(insn, 5, 5);
1412     unsigned int imm12 = extract32(insn, 10, 12);
1413     bool is_vector = extract32(insn, 26, 1);
1414     int size = extract32(insn, 30, 2);
1415     int opc = extract32(insn, 22, 2);
1416     unsigned int offset;
1417
1418     TCGv_i64 tcg_addr;
1419
1420     bool is_store;
1421     bool is_signed = false;
1422     bool is_extended = false;
1423
1424     if (is_vector) {
1425         size |= (opc & 2) << 1;
1426         if (size > 4) {
1427             unallocated_encoding(s);
1428             return;
1429         }
1430         is_store = !extract32(opc, 0, 1);
1431     } else {
1432         if (size == 3 && opc == 2) {
1433             /* PRFM - prefetch */
1434             return;
1435         }
1436         if (opc == 3 && size > 1) {
1437             unallocated_encoding(s);
1438             return;
1439         }
1440         is_store = (opc == 0);
1441         is_signed = extract32(opc, 1, 1);
1442         is_extended = (size < 3) && extract32(opc, 0, 1);
1443     }
1444
1445     if (rn == 31) {
1446         gen_check_sp_alignment(s);
1447     }
1448     tcg_addr = read_cpu_reg_sp(s, rn, 1);
1449     offset = imm12 << size;
1450     tcg_gen_addi_i64(tcg_addr, tcg_addr, offset);
1451
1452     if (is_vector) {
1453         if (is_store) {
1454             do_fp_st(s, rt, tcg_addr, size);
1455         } else {
1456             do_fp_ld(s, rt, tcg_addr, size);
1457         }
1458     } else {
1459         TCGv_i64 tcg_rt = cpu_reg(s, rt);
1460         if (is_store) {
1461             do_gpr_st(s, tcg_rt, tcg_addr, size);
1462         } else {
1463             do_gpr_ld(s, tcg_rt, tcg_addr, size, is_signed, is_extended);
1464         }
1465     }
1466 }
1467
1468 /* Load/store register (immediate forms) */
1469 static void disas_ldst_reg_imm(DisasContext *s, uint32_t insn)
1470 {
1471     switch (extract32(insn, 10, 2)) {
1472     case 0: case 1: case 3:
1473         /* Load/store register (unscaled immediate) */
1474         /* Load/store immediate pre/post-indexed */
1475         disas_ldst_reg_imm9(s, insn);
1476         break;
1477     case 2:
1478         /* Load/store register unprivileged */
1479         unsupported_encoding(s, insn);
1480         break;
1481     default:
1482         unallocated_encoding(s);
1483         break;
1484     }
1485 }
1486
1487 /* Load/store register (all forms) */
1488 static void disas_ldst_reg(DisasContext *s, uint32_t insn)
1489 {
1490     switch (extract32(insn, 24, 2)) {
1491     case 0:
1492         if (extract32(insn, 21, 1) == 1 && extract32(insn, 10, 2) == 2) {
1493             disas_ldst_reg_roffset(s, insn);
1494         } else {
1495             disas_ldst_reg_imm(s, insn);
1496         }
1497         break;
1498     case 1:
1499         disas_ldst_reg_unsigned_imm(s, insn);
1500         break;
1501     default:
1502         unallocated_encoding(s);
1503         break;
1504     }
1505 }
1506
1507 /* AdvSIMD load/store multiple structures */
1508 static void disas_ldst_multiple_struct(DisasContext *s, uint32_t insn)
1509 {
1510     unsupported_encoding(s, insn);
1511 }
1512
1513 /* AdvSIMD load/store single structure */
1514 static void disas_ldst_single_struct(DisasContext *s, uint32_t insn)
1515 {
1516     unsupported_encoding(s, insn);
1517 }
1518
1519 /* C3.3 Loads and stores */
1520 static void disas_ldst(DisasContext *s, uint32_t insn)
1521 {
1522     switch (extract32(insn, 24, 6)) {
1523     case 0x08: /* Load/store exclusive */
1524         disas_ldst_excl(s, insn);
1525         break;
1526     case 0x18: case 0x1c: /* Load register (literal) */
1527         disas_ld_lit(s, insn);
1528         break;
1529     case 0x28: case 0x29:
1530     case 0x2c: case 0x2d: /* Load/store pair (all forms) */
1531         disas_ldst_pair(s, insn);
1532         break;
1533     case 0x38: case 0x39:
1534     case 0x3c: case 0x3d: /* Load/store register (all forms) */
1535         disas_ldst_reg(s, insn);
1536         break;
1537     case 0x0c: /* AdvSIMD load/store multiple structures */
1538         disas_ldst_multiple_struct(s, insn);
1539         break;
1540     case 0x0d: /* AdvSIMD load/store single structure */
1541         disas_ldst_single_struct(s, insn);
1542         break;
1543     default:
1544         unallocated_encoding(s);
1545         break;
1546     }
1547 }
1548
1549 /* C3.4.6 PC-rel. addressing
1550  *   31  30   29 28       24 23                5 4    0
1551  * +----+-------+-----------+-------------------+------+
1552  * | op | immlo | 1 0 0 0 0 |       immhi       |  Rd  |
1553  * +----+-------+-----------+-------------------+------+
1554  */
1555 static void disas_pc_rel_adr(DisasContext *s, uint32_t insn)
1556 {
1557     unsigned int page, rd;
1558     uint64_t base;
1559     int64_t offset;
1560
1561     page = extract32(insn, 31, 1);
1562     /* SignExtend(immhi:immlo) -> offset */
1563     offset = ((int64_t)sextract32(insn, 5, 19) << 2) | extract32(insn, 29, 2);
1564     rd = extract32(insn, 0, 5);
1565     base = s->pc - 4;
1566
1567     if (page) {
1568         /* ADRP (page based) */
1569         base &= ~0xfff;
1570         offset <<= 12;
1571     }
1572
1573     tcg_gen_movi_i64(cpu_reg(s, rd), base + offset);
1574 }
1575
1576 /*
1577  * C3.4.1 Add/subtract (immediate)
1578  *
1579  *  31 30 29 28       24 23 22 21         10 9   5 4   0
1580  * +--+--+--+-----------+-----+-------------+-----+-----+
1581  * |sf|op| S| 1 0 0 0 1 |shift|    imm12    |  Rn | Rd  |
1582  * +--+--+--+-----------+-----+-------------+-----+-----+
1583  *
1584  *    sf: 0 -> 32bit, 1 -> 64bit
1585  *    op: 0 -> add  , 1 -> sub
1586  *     S: 1 -> set flags
1587  * shift: 00 -> LSL imm by 0, 01 -> LSL imm by 12
1588  */
1589 static void disas_add_sub_imm(DisasContext *s, uint32_t insn)
1590 {
1591     int rd = extract32(insn, 0, 5);
1592     int rn = extract32(insn, 5, 5);
1593     uint64_t imm = extract32(insn, 10, 12);
1594     int shift = extract32(insn, 22, 2);
1595     bool setflags = extract32(insn, 29, 1);
1596     bool sub_op = extract32(insn, 30, 1);
1597     bool is_64bit = extract32(insn, 31, 1);
1598
1599     TCGv_i64 tcg_rn = cpu_reg_sp(s, rn);
1600     TCGv_i64 tcg_rd = setflags ? cpu_reg(s, rd) : cpu_reg_sp(s, rd);
1601     TCGv_i64 tcg_result;
1602
1603     switch (shift) {
1604     case 0x0:
1605         break;
1606     case 0x1:
1607         imm <<= 12;
1608         break;
1609     default:
1610         unallocated_encoding(s);
1611         return;
1612     }
1613
1614     tcg_result = tcg_temp_new_i64();
1615     if (!setflags) {
1616         if (sub_op) {
1617             tcg_gen_subi_i64(tcg_result, tcg_rn, imm);
1618         } else {
1619             tcg_gen_addi_i64(tcg_result, tcg_rn, imm);
1620         }
1621     } else {
1622         TCGv_i64 tcg_imm = tcg_const_i64(imm);
1623         if (sub_op) {
1624             gen_sub_CC(is_64bit, tcg_result, tcg_rn, tcg_imm);
1625         } else {
1626             gen_add_CC(is_64bit, tcg_result, tcg_rn, tcg_imm);
1627         }
1628         tcg_temp_free_i64(tcg_imm);
1629     }
1630
1631     if (is_64bit) {
1632         tcg_gen_mov_i64(tcg_rd, tcg_result);
1633     } else {
1634         tcg_gen_ext32u_i64(tcg_rd, tcg_result);
1635     }
1636
1637     tcg_temp_free_i64(tcg_result);
1638 }
1639
1640 /* The input should be a value in the bottom e bits (with higher
1641  * bits zero); returns that value replicated into every element
1642  * of size e in a 64 bit integer.
1643  */
1644 static uint64_t bitfield_replicate(uint64_t mask, unsigned int e)
1645 {
1646     assert(e != 0);
1647     while (e < 64) {
1648         mask |= mask << e;
1649         e *= 2;
1650     }
1651     return mask;
1652 }
1653
1654 /* Return a value with the bottom len bits set (where 0 < len <= 64) */
1655 static inline uint64_t bitmask64(unsigned int length)
1656 {
1657     assert(length > 0 && length <= 64);
1658     return ~0ULL >> (64 - length);
1659 }
1660
1661 /* Simplified variant of pseudocode DecodeBitMasks() for the case where we
1662  * only require the wmask. Returns false if the imms/immr/immn are a reserved
1663  * value (ie should cause a guest UNDEF exception), and true if they are
1664  * valid, in which case the decoded bit pattern is written to result.
1665  */
1666 static bool logic_imm_decode_wmask(uint64_t *result, unsigned int immn,
1667                                    unsigned int imms, unsigned int immr)
1668 {
1669     uint64_t mask;
1670     unsigned e, levels, s, r;
1671     int len;
1672
1673     assert(immn < 2 && imms < 64 && immr < 64);
1674
1675     /* The bit patterns we create here are 64 bit patterns which
1676      * are vectors of identical elements of size e = 2, 4, 8, 16, 32 or
1677      * 64 bits each. Each element contains the same value: a run
1678      * of between 1 and e-1 non-zero bits, rotated within the
1679      * element by between 0 and e-1 bits.
1680      *
1681      * The element size and run length are encoded into immn (1 bit)
1682      * and imms (6 bits) as follows:
1683      * 64 bit elements: immn = 1, imms = <length of run - 1>
1684      * 32 bit elements: immn = 0, imms = 0 : <length of run - 1>
1685      * 16 bit elements: immn = 0, imms = 10 : <length of run - 1>
1686      *  8 bit elements: immn = 0, imms = 110 : <length of run - 1>
1687      *  4 bit elements: immn = 0, imms = 1110 : <length of run - 1>
1688      *  2 bit elements: immn = 0, imms = 11110 : <length of run - 1>
1689      * Notice that immn = 0, imms = 11111x is the only combination
1690      * not covered by one of the above options; this is reserved.
1691      * Further, <length of run - 1> all-ones is a reserved pattern.
1692      *
1693      * In all cases the rotation is by immr % e (and immr is 6 bits).
1694      */
1695
1696     /* First determine the element size */
1697     len = 31 - clz32((immn << 6) | (~imms & 0x3f));
1698     if (len < 1) {
1699         /* This is the immn == 0, imms == 0x11111x case */
1700         return false;
1701     }
1702     e = 1 << len;
1703
1704     levels = e - 1;
1705     s = imms & levels;
1706     r = immr & levels;
1707
1708     if (s == levels) {
1709         /* <length of run - 1> mustn't be all-ones. */
1710         return false;
1711     }
1712
1713     /* Create the value of one element: s+1 set bits rotated
1714      * by r within the element (which is e bits wide)...
1715      */
1716     mask = bitmask64(s + 1);
1717     mask = (mask >> r) | (mask << (e - r));
1718     /* ...then replicate the element over the whole 64 bit value */
1719     mask = bitfield_replicate(mask, e);
1720     *result = mask;
1721     return true;
1722 }
1723
1724 /* C3.4.4 Logical (immediate)
1725  *   31  30 29 28         23 22  21  16 15  10 9    5 4    0
1726  * +----+-----+-------------+---+------+------+------+------+
1727  * | sf | opc | 1 0 0 1 0 0 | N | immr | imms |  Rn  |  Rd  |
1728  * +----+-----+-------------+---+------+------+------+------+
1729  */
1730 static void disas_logic_imm(DisasContext *s, uint32_t insn)
1731 {
1732     unsigned int sf, opc, is_n, immr, imms, rn, rd;
1733     TCGv_i64 tcg_rd, tcg_rn;
1734     uint64_t wmask;
1735     bool is_and = false;
1736
1737     sf = extract32(insn, 31, 1);
1738     opc = extract32(insn, 29, 2);
1739     is_n = extract32(insn, 22, 1);
1740     immr = extract32(insn, 16, 6);
1741     imms = extract32(insn, 10, 6);
1742     rn = extract32(insn, 5, 5);
1743     rd = extract32(insn, 0, 5);
1744
1745     if (!sf && is_n) {
1746         unallocated_encoding(s);
1747         return;
1748     }
1749
1750     if (opc == 0x3) { /* ANDS */
1751         tcg_rd = cpu_reg(s, rd);
1752     } else {
1753         tcg_rd = cpu_reg_sp(s, rd);
1754     }
1755     tcg_rn = cpu_reg(s, rn);
1756
1757     if (!logic_imm_decode_wmask(&wmask, is_n, imms, immr)) {
1758         /* some immediate field values are reserved */
1759         unallocated_encoding(s);
1760         return;
1761     }
1762
1763     if (!sf) {
1764         wmask &= 0xffffffff;
1765     }
1766
1767     switch (opc) {
1768     case 0x3: /* ANDS */
1769     case 0x0: /* AND */
1770         tcg_gen_andi_i64(tcg_rd, tcg_rn, wmask);
1771         is_and = true;
1772         break;
1773     case 0x1: /* ORR */
1774         tcg_gen_ori_i64(tcg_rd, tcg_rn, wmask);
1775         break;
1776     case 0x2: /* EOR */
1777         tcg_gen_xori_i64(tcg_rd, tcg_rn, wmask);
1778         break;
1779     default:
1780         assert(FALSE); /* must handle all above */
1781         break;
1782     }
1783
1784     if (!sf && !is_and) {
1785         /* zero extend final result; we know we can skip this for AND
1786          * since the immediate had the high 32 bits clear.
1787          */
1788         tcg_gen_ext32u_i64(tcg_rd, tcg_rd);
1789     }
1790
1791     if (opc == 3) { /* ANDS */
1792         gen_logic_CC(sf, tcg_rd);
1793     }
1794 }
1795
1796 /*
1797  * C3.4.5 Move wide (immediate)
1798  *
1799  *  31 30 29 28         23 22 21 20             5 4    0
1800  * +--+-----+-------------+-----+----------------+------+
1801  * |sf| opc | 1 0 0 1 0 1 |  hw |  imm16         |  Rd  |
1802  * +--+-----+-------------+-----+----------------+------+
1803  *
1804  * sf: 0 -> 32 bit, 1 -> 64 bit
1805  * opc: 00 -> N, 10 -> Z, 11 -> K
1806  * hw: shift/16 (0,16, and sf only 32, 48)
1807  */
1808 static void disas_movw_imm(DisasContext *s, uint32_t insn)
1809 {
1810     int rd = extract32(insn, 0, 5);
1811     uint64_t imm = extract32(insn, 5, 16);
1812     int sf = extract32(insn, 31, 1);
1813     int opc = extract32(insn, 29, 2);
1814     int pos = extract32(insn, 21, 2) << 4;
1815     TCGv_i64 tcg_rd = cpu_reg(s, rd);
1816     TCGv_i64 tcg_imm;
1817
1818     if (!sf && (pos >= 32)) {
1819         unallocated_encoding(s);
1820         return;
1821     }
1822
1823     switch (opc) {
1824     case 0: /* MOVN */
1825     case 2: /* MOVZ */
1826         imm <<= pos;
1827         if (opc == 0) {
1828             imm = ~imm;
1829         }
1830         if (!sf) {
1831             imm &= 0xffffffffu;
1832         }
1833         tcg_gen_movi_i64(tcg_rd, imm);
1834         break;
1835     case 3: /* MOVK */
1836         tcg_imm = tcg_const_i64(imm);
1837         tcg_gen_deposit_i64(tcg_rd, tcg_rd, tcg_imm, pos, 16);
1838         tcg_temp_free_i64(tcg_imm);
1839         if (!sf) {
1840             tcg_gen_ext32u_i64(tcg_rd, tcg_rd);
1841         }
1842         break;
1843     default:
1844         unallocated_encoding(s);
1845         break;
1846     }
1847 }
1848
1849 /* C3.4.2 Bitfield
1850  *   31  30 29 28         23 22  21  16 15  10 9    5 4    0
1851  * +----+-----+-------------+---+------+------+------+------+
1852  * | sf | opc | 1 0 0 1 1 0 | N | immr | imms |  Rn  |  Rd  |
1853  * +----+-----+-------------+---+------+------+------+------+
1854  */
1855 static void disas_bitfield(DisasContext *s, uint32_t insn)
1856 {
1857     unsigned int sf, n, opc, ri, si, rn, rd, bitsize, pos, len;
1858     TCGv_i64 tcg_rd, tcg_tmp;
1859
1860     sf = extract32(insn, 31, 1);
1861     opc = extract32(insn, 29, 2);
1862     n = extract32(insn, 22, 1);
1863     ri = extract32(insn, 16, 6);
1864     si = extract32(insn, 10, 6);
1865     rn = extract32(insn, 5, 5);
1866     rd = extract32(insn, 0, 5);
1867     bitsize = sf ? 64 : 32;
1868
1869     if (sf != n || ri >= bitsize || si >= bitsize || opc > 2) {
1870         unallocated_encoding(s);
1871         return;
1872     }
1873
1874     tcg_rd = cpu_reg(s, rd);
1875     tcg_tmp = read_cpu_reg(s, rn, sf);
1876
1877     /* OPTME: probably worth recognizing common cases of ext{8,16,32}{u,s} */
1878
1879     if (opc != 1) { /* SBFM or UBFM */
1880         tcg_gen_movi_i64(tcg_rd, 0);
1881     }
1882
1883     /* do the bit move operation */
1884     if (si >= ri) {
1885         /* Wd<s-r:0> = Wn<s:r> */
1886         tcg_gen_shri_i64(tcg_tmp, tcg_tmp, ri);
1887         pos = 0;
1888         len = (si - ri) + 1;
1889     } else {
1890         /* Wd<32+s-r,32-r> = Wn<s:0> */
1891         pos = bitsize - ri;
1892         len = si + 1;
1893     }
1894
1895     tcg_gen_deposit_i64(tcg_rd, tcg_rd, tcg_tmp, pos, len);
1896
1897     if (opc == 0) { /* SBFM - sign extend the destination field */
1898         tcg_gen_shli_i64(tcg_rd, tcg_rd, 64 - (pos + len));
1899         tcg_gen_sari_i64(tcg_rd, tcg_rd, 64 - (pos + len));
1900     }
1901
1902     if (!sf) { /* zero extend final result */
1903         tcg_gen_ext32u_i64(tcg_rd, tcg_rd);
1904     }
1905 }
1906
1907 /* C3.4.3 Extract
1908  *   31  30  29 28         23 22   21  20  16 15    10 9    5 4    0
1909  * +----+------+-------------+---+----+------+--------+------+------+
1910  * | sf | op21 | 1 0 0 1 1 1 | N | o0 |  Rm  |  imms  |  Rn  |  Rd  |
1911  * +----+------+-------------+---+----+------+--------+------+------+
1912  */
1913 static void disas_extract(DisasContext *s, uint32_t insn)
1914 {
1915     unsigned int sf, n, rm, imm, rn, rd, bitsize, op21, op0;
1916
1917     sf = extract32(insn, 31, 1);
1918     n = extract32(insn, 22, 1);
1919     rm = extract32(insn, 16, 5);
1920     imm = extract32(insn, 10, 6);
1921     rn = extract32(insn, 5, 5);
1922     rd = extract32(insn, 0, 5);
1923     op21 = extract32(insn, 29, 2);
1924     op0 = extract32(insn, 21, 1);
1925     bitsize = sf ? 64 : 32;
1926
1927     if (sf != n || op21 || op0 || imm >= bitsize) {
1928         unallocated_encoding(s);
1929     } else {
1930         TCGv_i64 tcg_rd, tcg_rm, tcg_rn;
1931
1932         tcg_rd = cpu_reg(s, rd);
1933
1934         if (imm) {
1935             /* OPTME: we can special case rm==rn as a rotate */
1936             tcg_rm = read_cpu_reg(s, rm, sf);
1937             tcg_rn = read_cpu_reg(s, rn, sf);
1938             tcg_gen_shri_i64(tcg_rm, tcg_rm, imm);
1939             tcg_gen_shli_i64(tcg_rn, tcg_rn, bitsize - imm);
1940             tcg_gen_or_i64(tcg_rd, tcg_rm, tcg_rn);
1941             if (!sf) {
1942                 tcg_gen_ext32u_i64(tcg_rd, tcg_rd);
1943             }
1944         } else {
1945             /* tcg shl_i32/shl_i64 is undefined for 32/64 bit shifts,
1946              * so an extract from bit 0 is a special case.
1947              */
1948             if (sf) {
1949                 tcg_gen_mov_i64(tcg_rd, cpu_reg(s, rm));
1950             } else {
1951                 tcg_gen_ext32u_i64(tcg_rd, cpu_reg(s, rm));
1952             }
1953         }
1954
1955     }
1956 }
1957
1958 /* C3.4 Data processing - immediate */
1959 static void disas_data_proc_imm(DisasContext *s, uint32_t insn)
1960 {
1961     switch (extract32(insn, 23, 6)) {
1962     case 0x20: case 0x21: /* PC-rel. addressing */
1963         disas_pc_rel_adr(s, insn);
1964         break;
1965     case 0x22: case 0x23: /* Add/subtract (immediate) */
1966         disas_add_sub_imm(s, insn);
1967         break;
1968     case 0x24: /* Logical (immediate) */
1969         disas_logic_imm(s, insn);
1970         break;
1971     case 0x25: /* Move wide (immediate) */
1972         disas_movw_imm(s, insn);
1973         break;
1974     case 0x26: /* Bitfield */
1975         disas_bitfield(s, insn);
1976         break;
1977     case 0x27: /* Extract */
1978         disas_extract(s, insn);
1979         break;
1980     default:
1981         unallocated_encoding(s);
1982         break;
1983     }
1984 }
1985
1986 /* Shift a TCGv src by TCGv shift_amount, put result in dst.
1987  * Note that it is the caller's responsibility to ensure that the
1988  * shift amount is in range (ie 0..31 or 0..63) and provide the ARM
1989  * mandated semantics for out of range shifts.
1990  */
1991 static void shift_reg(TCGv_i64 dst, TCGv_i64 src, int sf,
1992                       enum a64_shift_type shift_type, TCGv_i64 shift_amount)
1993 {
1994     switch (shift_type) {
1995     case A64_SHIFT_TYPE_LSL:
1996         tcg_gen_shl_i64(dst, src, shift_amount);
1997         break;
1998     case A64_SHIFT_TYPE_LSR:
1999         tcg_gen_shr_i64(dst, src, shift_amount);
2000         break;
2001     case A64_SHIFT_TYPE_ASR:
2002         if (!sf) {
2003             tcg_gen_ext32s_i64(dst, src);
2004         }
2005         tcg_gen_sar_i64(dst, sf ? src : dst, shift_amount);
2006         break;
2007     case A64_SHIFT_TYPE_ROR:
2008         if (sf) {
2009             tcg_gen_rotr_i64(dst, src, shift_amount);
2010         } else {
2011             TCGv_i32 t0, t1;
2012             t0 = tcg_temp_new_i32();
2013             t1 = tcg_temp_new_i32();
2014             tcg_gen_trunc_i64_i32(t0, src);
2015             tcg_gen_trunc_i64_i32(t1, shift_amount);
2016             tcg_gen_rotr_i32(t0, t0, t1);
2017             tcg_gen_extu_i32_i64(dst, t0);
2018             tcg_temp_free_i32(t0);
2019             tcg_temp_free_i32(t1);
2020         }
2021         break;
2022     default:
2023         assert(FALSE); /* all shift types should be handled */
2024         break;
2025     }
2026
2027     if (!sf) { /* zero extend final result */
2028         tcg_gen_ext32u_i64(dst, dst);
2029     }
2030 }
2031
2032 /* Shift a TCGv src by immediate, put result in dst.
2033  * The shift amount must be in range (this should always be true as the
2034  * relevant instructions will UNDEF on bad shift immediates).
2035  */
2036 static void shift_reg_imm(TCGv_i64 dst, TCGv_i64 src, int sf,
2037                           enum a64_shift_type shift_type, unsigned int shift_i)
2038 {
2039     assert(shift_i < (sf ? 64 : 32));
2040
2041     if (shift_i == 0) {
2042         tcg_gen_mov_i64(dst, src);
2043     } else {
2044         TCGv_i64 shift_const;
2045
2046         shift_const = tcg_const_i64(shift_i);
2047         shift_reg(dst, src, sf, shift_type, shift_const);
2048         tcg_temp_free_i64(shift_const);
2049     }
2050 }
2051
2052 /* C3.5.10 Logical (shifted register)
2053  *   31  30 29 28       24 23   22 21  20  16 15    10 9    5 4    0
2054  * +----+-----+-----------+-------+---+------+--------+------+------+
2055  * | sf | opc | 0 1 0 1 0 | shift | N |  Rm  |  imm6  |  Rn  |  Rd  |
2056  * +----+-----+-----------+-------+---+------+--------+------+------+
2057  */
2058 static void disas_logic_reg(DisasContext *s, uint32_t insn)
2059 {
2060     TCGv_i64 tcg_rd, tcg_rn, tcg_rm;
2061     unsigned int sf, opc, shift_type, invert, rm, shift_amount, rn, rd;
2062
2063     sf = extract32(insn, 31, 1);
2064     opc = extract32(insn, 29, 2);
2065     shift_type = extract32(insn, 22, 2);
2066     invert = extract32(insn, 21, 1);
2067     rm = extract32(insn, 16, 5);
2068     shift_amount = extract32(insn, 10, 6);
2069     rn = extract32(insn, 5, 5);
2070     rd = extract32(insn, 0, 5);
2071
2072     if (!sf && (shift_amount & (1 << 5))) {
2073         unallocated_encoding(s);
2074         return;
2075     }
2076
2077     tcg_rd = cpu_reg(s, rd);
2078
2079     if (opc == 1 && shift_amount == 0 && shift_type == 0 && rn == 31) {
2080         /* Unshifted ORR and ORN with WZR/XZR is the standard encoding for
2081          * register-register MOV and MVN, so it is worth special casing.
2082          */
2083         tcg_rm = cpu_reg(s, rm);
2084         if (invert) {
2085             tcg_gen_not_i64(tcg_rd, tcg_rm);
2086             if (!sf) {
2087                 tcg_gen_ext32u_i64(tcg_rd, tcg_rd);
2088             }
2089         } else {
2090             if (sf) {
2091                 tcg_gen_mov_i64(tcg_rd, tcg_rm);
2092             } else {
2093                 tcg_gen_ext32u_i64(tcg_rd, tcg_rm);
2094             }
2095         }
2096         return;
2097     }
2098
2099     tcg_rm = read_cpu_reg(s, rm, sf);
2100
2101     if (shift_amount) {
2102         shift_reg_imm(tcg_rm, tcg_rm, sf, shift_type, shift_amount);
2103     }
2104
2105     tcg_rn = cpu_reg(s, rn);
2106
2107     switch (opc | (invert << 2)) {
2108     case 0: /* AND */
2109     case 3: /* ANDS */
2110         tcg_gen_and_i64(tcg_rd, tcg_rn, tcg_rm);
2111         break;
2112     case 1: /* ORR */
2113         tcg_gen_or_i64(tcg_rd, tcg_rn, tcg_rm);
2114         break;
2115     case 2: /* EOR */
2116         tcg_gen_xor_i64(tcg_rd, tcg_rn, tcg_rm);
2117         break;
2118     case 4: /* BIC */
2119     case 7: /* BICS */
2120         tcg_gen_andc_i64(tcg_rd, tcg_rn, tcg_rm);
2121         break;
2122     case 5: /* ORN */
2123         tcg_gen_orc_i64(tcg_rd, tcg_rn, tcg_rm);
2124         break;
2125     case 6: /* EON */
2126         tcg_gen_eqv_i64(tcg_rd, tcg_rn, tcg_rm);
2127         break;
2128     default:
2129         assert(FALSE);
2130         break;
2131     }
2132
2133     if (!sf) {
2134         tcg_gen_ext32u_i64(tcg_rd, tcg_rd);
2135     }
2136
2137     if (opc == 3) {
2138         gen_logic_CC(sf, tcg_rd);
2139     }
2140 }
2141
2142 /*
2143  * C3.5.1 Add/subtract (extended register)
2144  *
2145  *  31|30|29|28       24|23 22|21|20   16|15  13|12  10|9  5|4  0|
2146  * +--+--+--+-----------+-----+--+-------+------+------+----+----+
2147  * |sf|op| S| 0 1 0 1 1 | opt | 1|  Rm   |option| imm3 | Rn | Rd |
2148  * +--+--+--+-----------+-----+--+-------+------+------+----+----+
2149  *
2150  *  sf: 0 -> 32bit, 1 -> 64bit
2151  *  op: 0 -> add  , 1 -> sub
2152  *   S: 1 -> set flags
2153  * opt: 00
2154  * option: extension type (see DecodeRegExtend)
2155  * imm3: optional shift to Rm
2156  *
2157  * Rd = Rn + LSL(extend(Rm), amount)
2158  */
2159 static void disas_add_sub_ext_reg(DisasContext *s, uint32_t insn)
2160 {
2161     int rd = extract32(insn, 0, 5);
2162     int rn = extract32(insn, 5, 5);
2163     int imm3 = extract32(insn, 10, 3);
2164     int option = extract32(insn, 13, 3);
2165     int rm = extract32(insn, 16, 5);
2166     bool setflags = extract32(insn, 29, 1);
2167     bool sub_op = extract32(insn, 30, 1);
2168     bool sf = extract32(insn, 31, 1);
2169
2170     TCGv_i64 tcg_rm, tcg_rn; /* temps */
2171     TCGv_i64 tcg_rd;
2172     TCGv_i64 tcg_result;
2173
2174     if (imm3 > 4) {
2175         unallocated_encoding(s);
2176         return;
2177     }
2178
2179     /* non-flag setting ops may use SP */
2180     if (!setflags) {
2181         tcg_rn = read_cpu_reg_sp(s, rn, sf);
2182         tcg_rd = cpu_reg_sp(s, rd);
2183     } else {
2184         tcg_rn = read_cpu_reg(s, rn, sf);
2185         tcg_rd = cpu_reg(s, rd);
2186     }
2187
2188     tcg_rm = read_cpu_reg(s, rm, sf);
2189     ext_and_shift_reg(tcg_rm, tcg_rm, option, imm3);
2190
2191     tcg_result = tcg_temp_new_i64();
2192
2193     if (!setflags) {
2194         if (sub_op) {
2195             tcg_gen_sub_i64(tcg_result, tcg_rn, tcg_rm);
2196         } else {
2197             tcg_gen_add_i64(tcg_result, tcg_rn, tcg_rm);
2198         }
2199     } else {
2200         if (sub_op) {
2201             gen_sub_CC(sf, tcg_result, tcg_rn, tcg_rm);
2202         } else {
2203             gen_add_CC(sf, tcg_result, tcg_rn, tcg_rm);
2204         }
2205     }
2206
2207     if (sf) {
2208         tcg_gen_mov_i64(tcg_rd, tcg_result);
2209     } else {
2210         tcg_gen_ext32u_i64(tcg_rd, tcg_result);
2211     }
2212
2213     tcg_temp_free_i64(tcg_result);
2214 }
2215
2216 /*
2217  * C3.5.2 Add/subtract (shifted register)
2218  *
2219  *  31 30 29 28       24 23 22 21 20   16 15     10 9    5 4    0
2220  * +--+--+--+-----------+-----+--+-------+---------+------+------+
2221  * |sf|op| S| 0 1 0 1 1 |shift| 0|  Rm   |  imm6   |  Rn  |  Rd  |
2222  * +--+--+--+-----------+-----+--+-------+---------+------+------+
2223  *
2224  *    sf: 0 -> 32bit, 1 -> 64bit
2225  *    op: 0 -> add  , 1 -> sub
2226  *     S: 1 -> set flags
2227  * shift: 00 -> LSL, 01 -> LSR, 10 -> ASR, 11 -> RESERVED
2228  *  imm6: Shift amount to apply to Rm before the add/sub
2229  */
2230 static void disas_add_sub_reg(DisasContext *s, uint32_t insn)
2231 {
2232     int rd = extract32(insn, 0, 5);
2233     int rn = extract32(insn, 5, 5);
2234     int imm6 = extract32(insn, 10, 6);
2235     int rm = extract32(insn, 16, 5);
2236     int shift_type = extract32(insn, 22, 2);
2237     bool setflags = extract32(insn, 29, 1);
2238     bool sub_op = extract32(insn, 30, 1);
2239     bool sf = extract32(insn, 31, 1);
2240
2241     TCGv_i64 tcg_rd = cpu_reg(s, rd);
2242     TCGv_i64 tcg_rn, tcg_rm;
2243     TCGv_i64 tcg_result;
2244
2245     if ((shift_type == 3) || (!sf && (imm6 > 31))) {
2246         unallocated_encoding(s);
2247         return;
2248     }
2249
2250     tcg_rn = read_cpu_reg(s, rn, sf);
2251     tcg_rm = read_cpu_reg(s, rm, sf);
2252
2253     shift_reg_imm(tcg_rm, tcg_rm, sf, shift_type, imm6);
2254
2255     tcg_result = tcg_temp_new_i64();
2256
2257     if (!setflags) {
2258         if (sub_op) {
2259             tcg_gen_sub_i64(tcg_result, tcg_rn, tcg_rm);
2260         } else {
2261             tcg_gen_add_i64(tcg_result, tcg_rn, tcg_rm);
2262         }
2263     } else {
2264         if (sub_op) {
2265             gen_sub_CC(sf, tcg_result, tcg_rn, tcg_rm);
2266         } else {
2267             gen_add_CC(sf, tcg_result, tcg_rn, tcg_rm);
2268         }
2269     }
2270
2271     if (sf) {
2272         tcg_gen_mov_i64(tcg_rd, tcg_result);
2273     } else {
2274         tcg_gen_ext32u_i64(tcg_rd, tcg_result);
2275     }
2276
2277     tcg_temp_free_i64(tcg_result);
2278 }
2279
2280 /* C3.5.9 Data-processing (3 source)
2281
2282    31 30  29 28       24 23 21  20  16  15  14  10 9    5 4    0
2283   +--+------+-----------+------+------+----+------+------+------+
2284   |sf| op54 | 1 1 0 1 1 | op31 |  Rm  | o0 |  Ra  |  Rn  |  Rd  |
2285   +--+------+-----------+------+------+----+------+------+------+
2286
2287  */
2288 static void disas_data_proc_3src(DisasContext *s, uint32_t insn)
2289 {
2290     int rd = extract32(insn, 0, 5);
2291     int rn = extract32(insn, 5, 5);
2292     int ra = extract32(insn, 10, 5);
2293     int rm = extract32(insn, 16, 5);
2294     int op_id = (extract32(insn, 29, 3) << 4) |
2295         (extract32(insn, 21, 3) << 1) |
2296         extract32(insn, 15, 1);
2297     bool sf = extract32(insn, 31, 1);
2298     bool is_sub = extract32(op_id, 0, 1);
2299     bool is_high = extract32(op_id, 2, 1);
2300     bool is_signed = false;
2301     TCGv_i64 tcg_op1;
2302     TCGv_i64 tcg_op2;
2303     TCGv_i64 tcg_tmp;
2304
2305     /* Note that op_id is sf:op54:op31:o0 so it includes the 32/64 size flag */
2306     switch (op_id) {
2307     case 0x42: /* SMADDL */
2308     case 0x43: /* SMSUBL */
2309     case 0x44: /* SMULH */
2310         is_signed = true;
2311         break;
2312     case 0x0: /* MADD (32bit) */
2313     case 0x1: /* MSUB (32bit) */
2314     case 0x40: /* MADD (64bit) */
2315     case 0x41: /* MSUB (64bit) */
2316     case 0x4a: /* UMADDL */
2317     case 0x4b: /* UMSUBL */
2318     case 0x4c: /* UMULH */
2319         break;
2320     default:
2321         unallocated_encoding(s);
2322         return;
2323     }
2324
2325     if (is_high) {
2326         TCGv_i64 low_bits = tcg_temp_new_i64(); /* low bits discarded */
2327         TCGv_i64 tcg_rd = cpu_reg(s, rd);
2328         TCGv_i64 tcg_rn = cpu_reg(s, rn);
2329         TCGv_i64 tcg_rm = cpu_reg(s, rm);
2330
2331         if (is_signed) {
2332             tcg_gen_muls2_i64(low_bits, tcg_rd, tcg_rn, tcg_rm);
2333         } else {
2334             tcg_gen_mulu2_i64(low_bits, tcg_rd, tcg_rn, tcg_rm);
2335         }
2336
2337         tcg_temp_free_i64(low_bits);
2338         return;
2339     }
2340
2341     tcg_op1 = tcg_temp_new_i64();
2342     tcg_op2 = tcg_temp_new_i64();
2343     tcg_tmp = tcg_temp_new_i64();
2344
2345     if (op_id < 0x42) {
2346         tcg_gen_mov_i64(tcg_op1, cpu_reg(s, rn));
2347         tcg_gen_mov_i64(tcg_op2, cpu_reg(s, rm));
2348     } else {
2349         if (is_signed) {
2350             tcg_gen_ext32s_i64(tcg_op1, cpu_reg(s, rn));
2351             tcg_gen_ext32s_i64(tcg_op2, cpu_reg(s, rm));
2352         } else {
2353             tcg_gen_ext32u_i64(tcg_op1, cpu_reg(s, rn));
2354             tcg_gen_ext32u_i64(tcg_op2, cpu_reg(s, rm));
2355         }
2356     }
2357
2358     if (ra == 31 && !is_sub) {
2359         /* Special-case MADD with rA == XZR; it is the standard MUL alias */
2360         tcg_gen_mul_i64(cpu_reg(s, rd), tcg_op1, tcg_op2);
2361     } else {
2362         tcg_gen_mul_i64(tcg_tmp, tcg_op1, tcg_op2);
2363         if (is_sub) {
2364             tcg_gen_sub_i64(cpu_reg(s, rd), cpu_reg(s, ra), tcg_tmp);
2365         } else {
2366             tcg_gen_add_i64(cpu_reg(s, rd), cpu_reg(s, ra), tcg_tmp);
2367         }
2368     }
2369
2370     if (!sf) {
2371         tcg_gen_ext32u_i64(cpu_reg(s, rd), cpu_reg(s, rd));
2372     }
2373
2374     tcg_temp_free_i64(tcg_op1);
2375     tcg_temp_free_i64(tcg_op2);
2376     tcg_temp_free_i64(tcg_tmp);
2377 }
2378
2379 /* Add/subtract (with carry) */
2380 static void disas_adc_sbc(DisasContext *s, uint32_t insn)
2381 {
2382     unsupported_encoding(s, insn);
2383 }
2384
2385 /* Conditional compare (immediate) */
2386 static void disas_cc_imm(DisasContext *s, uint32_t insn)
2387 {
2388     unsupported_encoding(s, insn);
2389 }
2390
2391 /* Conditional compare (register) */
2392 static void disas_cc_reg(DisasContext *s, uint32_t insn)
2393 {
2394     unsupported_encoding(s, insn);
2395 }
2396
2397 /* C3.5.6 Conditional select
2398  *   31   30  29  28             21 20  16 15  12 11 10 9    5 4    0
2399  * +----+----+---+-----------------+------+------+-----+------+------+
2400  * | sf | op | S | 1 1 0 1 0 1 0 0 |  Rm  | cond | op2 |  Rn  |  Rd  |
2401  * +----+----+---+-----------------+------+------+-----+------+------+
2402  */
2403 static void disas_cond_select(DisasContext *s, uint32_t insn)
2404 {
2405     unsigned int sf, else_inv, rm, cond, else_inc, rn, rd;
2406     TCGv_i64 tcg_rd, tcg_src;
2407
2408     if (extract32(insn, 29, 1) || extract32(insn, 11, 1)) {
2409         /* S == 1 or op2<1> == 1 */
2410         unallocated_encoding(s);
2411         return;
2412     }
2413     sf = extract32(insn, 31, 1);
2414     else_inv = extract32(insn, 30, 1);
2415     rm = extract32(insn, 16, 5);
2416     cond = extract32(insn, 12, 4);
2417     else_inc = extract32(insn, 10, 1);
2418     rn = extract32(insn, 5, 5);
2419     rd = extract32(insn, 0, 5);
2420
2421     if (rd == 31) {
2422         /* silly no-op write; until we use movcond we must special-case
2423          * this to avoid a dead temporary across basic blocks.
2424          */
2425         return;
2426     }
2427
2428     tcg_rd = cpu_reg(s, rd);
2429
2430     if (cond >= 0x0e) { /* condition "always" */
2431         tcg_src = read_cpu_reg(s, rn, sf);
2432         tcg_gen_mov_i64(tcg_rd, tcg_src);
2433     } else {
2434         /* OPTME: we could use movcond here, at the cost of duplicating
2435          * a lot of the arm_gen_test_cc() logic.
2436          */
2437         int label_match = gen_new_label();
2438         int label_continue = gen_new_label();
2439
2440         arm_gen_test_cc(cond, label_match);
2441         /* nomatch: */
2442         tcg_src = cpu_reg(s, rm);
2443
2444         if (else_inv && else_inc) {
2445             tcg_gen_neg_i64(tcg_rd, tcg_src);
2446         } else if (else_inv) {
2447             tcg_gen_not_i64(tcg_rd, tcg_src);
2448         } else if (else_inc) {
2449             tcg_gen_addi_i64(tcg_rd, tcg_src, 1);
2450         } else {
2451             tcg_gen_mov_i64(tcg_rd, tcg_src);
2452         }
2453         if (!sf) {
2454             tcg_gen_ext32u_i64(tcg_rd, tcg_rd);
2455         }
2456         tcg_gen_br(label_continue);
2457         /* match: */
2458         gen_set_label(label_match);
2459         tcg_src = read_cpu_reg(s, rn, sf);
2460         tcg_gen_mov_i64(tcg_rd, tcg_src);
2461         /* continue: */
2462         gen_set_label(label_continue);
2463     }
2464 }
2465
2466 static void handle_clz(DisasContext *s, unsigned int sf,
2467                        unsigned int rn, unsigned int rd)
2468 {
2469     TCGv_i64 tcg_rd, tcg_rn;
2470     tcg_rd = cpu_reg(s, rd);
2471     tcg_rn = cpu_reg(s, rn);
2472
2473     if (sf) {
2474         gen_helper_clz64(tcg_rd, tcg_rn);
2475     } else {
2476         TCGv_i32 tcg_tmp32 = tcg_temp_new_i32();
2477         tcg_gen_trunc_i64_i32(tcg_tmp32, tcg_rn);
2478         gen_helper_clz(tcg_tmp32, tcg_tmp32);
2479         tcg_gen_extu_i32_i64(tcg_rd, tcg_tmp32);
2480         tcg_temp_free_i32(tcg_tmp32);
2481     }
2482 }
2483
2484 static void handle_cls(DisasContext *s, unsigned int sf,
2485                        unsigned int rn, unsigned int rd)
2486 {
2487     TCGv_i64 tcg_rd, tcg_rn;
2488     tcg_rd = cpu_reg(s, rd);
2489     tcg_rn = cpu_reg(s, rn);
2490
2491     if (sf) {
2492         gen_helper_cls64(tcg_rd, tcg_rn);
2493     } else {
2494         TCGv_i32 tcg_tmp32 = tcg_temp_new_i32();
2495         tcg_gen_trunc_i64_i32(tcg_tmp32, tcg_rn);
2496         gen_helper_cls32(tcg_tmp32, tcg_tmp32);
2497         tcg_gen_extu_i32_i64(tcg_rd, tcg_tmp32);
2498         tcg_temp_free_i32(tcg_tmp32);
2499     }
2500 }
2501
2502 static void handle_rbit(DisasContext *s, unsigned int sf,
2503                         unsigned int rn, unsigned int rd)
2504 {
2505     TCGv_i64 tcg_rd, tcg_rn;
2506     tcg_rd = cpu_reg(s, rd);
2507     tcg_rn = cpu_reg(s, rn);
2508
2509     if (sf) {
2510         gen_helper_rbit64(tcg_rd, tcg_rn);
2511     } else {
2512         TCGv_i32 tcg_tmp32 = tcg_temp_new_i32();
2513         tcg_gen_trunc_i64_i32(tcg_tmp32, tcg_rn);
2514         gen_helper_rbit(tcg_tmp32, tcg_tmp32);
2515         tcg_gen_extu_i32_i64(tcg_rd, tcg_tmp32);
2516         tcg_temp_free_i32(tcg_tmp32);
2517     }
2518 }
2519
2520 /* C5.6.149 REV with sf==1, opcode==3 ("REV64") */
2521 static void handle_rev64(DisasContext *s, unsigned int sf,
2522                          unsigned int rn, unsigned int rd)
2523 {
2524     if (!sf) {
2525         unallocated_encoding(s);
2526         return;
2527     }
2528     tcg_gen_bswap64_i64(cpu_reg(s, rd), cpu_reg(s, rn));
2529 }
2530
2531 /* C5.6.149 REV with sf==0, opcode==2
2532  * C5.6.151 REV32 (sf==1, opcode==2)
2533  */
2534 static void handle_rev32(DisasContext *s, unsigned int sf,
2535                          unsigned int rn, unsigned int rd)
2536 {
2537     TCGv_i64 tcg_rd = cpu_reg(s, rd);
2538
2539     if (sf) {
2540         TCGv_i64 tcg_tmp = tcg_temp_new_i64();
2541         TCGv_i64 tcg_rn = read_cpu_reg(s, rn, sf);
2542
2543         /* bswap32_i64 requires zero high word */
2544         tcg_gen_ext32u_i64(tcg_tmp, tcg_rn);
2545         tcg_gen_bswap32_i64(tcg_rd, tcg_tmp);
2546         tcg_gen_shri_i64(tcg_tmp, tcg_rn, 32);
2547         tcg_gen_bswap32_i64(tcg_tmp, tcg_tmp);
2548         tcg_gen_concat32_i64(tcg_rd, tcg_rd, tcg_tmp);
2549
2550         tcg_temp_free_i64(tcg_tmp);
2551     } else {
2552         tcg_gen_ext32u_i64(tcg_rd, cpu_reg(s, rn));
2553         tcg_gen_bswap32_i64(tcg_rd, tcg_rd);
2554     }
2555 }
2556
2557 /* C5.6.150 REV16 (opcode==1) */
2558 static void handle_rev16(DisasContext *s, unsigned int sf,
2559                          unsigned int rn, unsigned int rd)
2560 {
2561     TCGv_i64 tcg_rd = cpu_reg(s, rd);
2562     TCGv_i64 tcg_tmp = tcg_temp_new_i64();
2563     TCGv_i64 tcg_rn = read_cpu_reg(s, rn, sf);
2564
2565     tcg_gen_andi_i64(tcg_tmp, tcg_rn, 0xffff);
2566     tcg_gen_bswap16_i64(tcg_rd, tcg_tmp);
2567
2568     tcg_gen_shri_i64(tcg_tmp, tcg_rn, 16);
2569     tcg_gen_andi_i64(tcg_tmp, tcg_tmp, 0xffff);
2570     tcg_gen_bswap16_i64(tcg_tmp, tcg_tmp);
2571     tcg_gen_deposit_i64(tcg_rd, tcg_rd, tcg_tmp, 16, 16);
2572
2573     if (sf) {
2574         tcg_gen_shri_i64(tcg_tmp, tcg_rn, 32);
2575         tcg_gen_andi_i64(tcg_tmp, tcg_tmp, 0xffff);
2576         tcg_gen_bswap16_i64(tcg_tmp, tcg_tmp);
2577         tcg_gen_deposit_i64(tcg_rd, tcg_rd, tcg_tmp, 32, 16);
2578
2579         tcg_gen_shri_i64(tcg_tmp, tcg_rn, 48);
2580         tcg_gen_bswap16_i64(tcg_tmp, tcg_tmp);
2581         tcg_gen_deposit_i64(tcg_rd, tcg_rd, tcg_tmp, 48, 16);
2582     }
2583
2584     tcg_temp_free_i64(tcg_tmp);
2585 }
2586
2587 /* C3.5.7 Data-processing (1 source)
2588  *   31  30  29  28             21 20     16 15    10 9    5 4    0
2589  * +----+---+---+-----------------+---------+--------+------+------+
2590  * | sf | 1 | S | 1 1 0 1 0 1 1 0 | opcode2 | opcode |  Rn  |  Rd  |
2591  * +----+---+---+-----------------+---------+--------+------+------+
2592  */
2593 static void disas_data_proc_1src(DisasContext *s, uint32_t insn)
2594 {
2595     unsigned int sf, opcode, rn, rd;
2596
2597     if (extract32(insn, 29, 1) || extract32(insn, 16, 5)) {
2598         unallocated_encoding(s);
2599         return;
2600     }
2601
2602     sf = extract32(insn, 31, 1);
2603     opcode = extract32(insn, 10, 6);
2604     rn = extract32(insn, 5, 5);
2605     rd = extract32(insn, 0, 5);
2606
2607     switch (opcode) {
2608     case 0: /* RBIT */
2609         handle_rbit(s, sf, rn, rd);
2610         break;
2611     case 1: /* REV16 */
2612         handle_rev16(s, sf, rn, rd);
2613         break;
2614     case 2: /* REV32 */
2615         handle_rev32(s, sf, rn, rd);
2616         break;
2617     case 3: /* REV64 */
2618         handle_rev64(s, sf, rn, rd);
2619         break;
2620     case 4: /* CLZ */
2621         handle_clz(s, sf, rn, rd);
2622         break;
2623     case 5: /* CLS */
2624         handle_cls(s, sf, rn, rd);
2625         break;
2626     }
2627 }
2628
2629 static void handle_div(DisasContext *s, bool is_signed, unsigned int sf,
2630                        unsigned int rm, unsigned int rn, unsigned int rd)
2631 {
2632     TCGv_i64 tcg_n, tcg_m, tcg_rd;
2633     tcg_rd = cpu_reg(s, rd);
2634
2635     if (!sf && is_signed) {
2636         tcg_n = new_tmp_a64(s);
2637         tcg_m = new_tmp_a64(s);
2638         tcg_gen_ext32s_i64(tcg_n, cpu_reg(s, rn));
2639         tcg_gen_ext32s_i64(tcg_m, cpu_reg(s, rm));
2640     } else {
2641         tcg_n = read_cpu_reg(s, rn, sf);
2642         tcg_m = read_cpu_reg(s, rm, sf);
2643     }
2644
2645     if (is_signed) {
2646         gen_helper_sdiv64(tcg_rd, tcg_n, tcg_m);
2647     } else {
2648         gen_helper_udiv64(tcg_rd, tcg_n, tcg_m);
2649     }
2650
2651     if (!sf) { /* zero extend final result */
2652         tcg_gen_ext32u_i64(tcg_rd, tcg_rd);
2653     }
2654 }
2655
2656 /* C5.6.115 LSLV, C5.6.118 LSRV, C5.6.17 ASRV, C5.6.154 RORV */
2657 static void handle_shift_reg(DisasContext *s,
2658                              enum a64_shift_type shift_type, unsigned int sf,
2659                              unsigned int rm, unsigned int rn, unsigned int rd)
2660 {
2661     TCGv_i64 tcg_shift = tcg_temp_new_i64();
2662     TCGv_i64 tcg_rd = cpu_reg(s, rd);
2663     TCGv_i64 tcg_rn = read_cpu_reg(s, rn, sf);
2664
2665     tcg_gen_andi_i64(tcg_shift, cpu_reg(s, rm), sf ? 63 : 31);
2666     shift_reg(tcg_rd, tcg_rn, sf, shift_type, tcg_shift);
2667     tcg_temp_free_i64(tcg_shift);
2668 }
2669
2670 /* C3.5.8 Data-processing (2 source)
2671  *   31   30  29 28             21 20  16 15    10 9    5 4    0
2672  * +----+---+---+-----------------+------+--------+------+------+
2673  * | sf | 0 | S | 1 1 0 1 0 1 1 0 |  Rm  | opcode |  Rn  |  Rd  |
2674  * +----+---+---+-----------------+------+--------+------+------+
2675  */
2676 static void disas_data_proc_2src(DisasContext *s, uint32_t insn)
2677 {
2678     unsigned int sf, rm, opcode, rn, rd;
2679     sf = extract32(insn, 31, 1);
2680     rm = extract32(insn, 16, 5);
2681     opcode = extract32(insn, 10, 6);
2682     rn = extract32(insn, 5, 5);
2683     rd = extract32(insn, 0, 5);
2684
2685     if (extract32(insn, 29, 1)) {
2686         unallocated_encoding(s);
2687         return;
2688     }
2689
2690     switch (opcode) {
2691     case 2: /* UDIV */
2692         handle_div(s, false, sf, rm, rn, rd);
2693         break;
2694     case 3: /* SDIV */
2695         handle_div(s, true, sf, rm, rn, rd);
2696         break;
2697     case 8: /* LSLV */
2698         handle_shift_reg(s, A64_SHIFT_TYPE_LSL, sf, rm, rn, rd);
2699         break;
2700     case 9: /* LSRV */
2701         handle_shift_reg(s, A64_SHIFT_TYPE_LSR, sf, rm, rn, rd);
2702         break;
2703     case 10: /* ASRV */
2704         handle_shift_reg(s, A64_SHIFT_TYPE_ASR, sf, rm, rn, rd);
2705         break;
2706     case 11: /* RORV */
2707         handle_shift_reg(s, A64_SHIFT_TYPE_ROR, sf, rm, rn, rd);
2708         break;
2709     case 16:
2710     case 17:
2711     case 18:
2712     case 19:
2713     case 20:
2714     case 21:
2715     case 22:
2716     case 23: /* CRC32 */
2717         unsupported_encoding(s, insn);
2718         break;
2719     default:
2720         unallocated_encoding(s);
2721         break;
2722     }
2723 }
2724
2725 /* C3.5 Data processing - register */
2726 static void disas_data_proc_reg(DisasContext *s, uint32_t insn)
2727 {
2728     switch (extract32(insn, 24, 5)) {
2729     case 0x0a: /* Logical (shifted register) */
2730         disas_logic_reg(s, insn);
2731         break;
2732     case 0x0b: /* Add/subtract */
2733         if (insn & (1 << 21)) { /* (extended register) */
2734             disas_add_sub_ext_reg(s, insn);
2735         } else {
2736             disas_add_sub_reg(s, insn);
2737         }
2738         break;
2739     case 0x1b: /* Data-processing (3 source) */
2740         disas_data_proc_3src(s, insn);
2741         break;
2742     case 0x1a:
2743         switch (extract32(insn, 21, 3)) {
2744         case 0x0: /* Add/subtract (with carry) */
2745             disas_adc_sbc(s, insn);
2746             break;
2747         case 0x2: /* Conditional compare */
2748             if (insn & (1 << 11)) { /* (immediate) */
2749                 disas_cc_imm(s, insn);
2750             } else {            /* (register) */
2751                 disas_cc_reg(s, insn);
2752             }
2753             break;
2754         case 0x4: /* Conditional select */
2755             disas_cond_select(s, insn);
2756             break;
2757         case 0x6: /* Data-processing */
2758             if (insn & (1 << 30)) { /* (1 source) */
2759                 disas_data_proc_1src(s, insn);
2760             } else {            /* (2 source) */
2761                 disas_data_proc_2src(s, insn);
2762             }
2763             break;
2764         default:
2765             unallocated_encoding(s);
2766             break;
2767         }
2768         break;
2769     default:
2770         unallocated_encoding(s);
2771         break;
2772     }
2773 }
2774
2775 /* C3.6.22 Floating point compare
2776  *   31  30  29 28       24 23  22  21 20  16 15 14 13  10    9    5 4     0
2777  * +---+---+---+-----------+------+---+------+-----+---------+------+-------+
2778  * | M | 0 | S | 1 1 1 1 0 | type | 1 |  Rm  | op  | 1 0 0 0 |  Rn  |  op2  |
2779  * +---+---+---+-----------+------+---+------+-----+---------+------+-------+
2780  */
2781 static void disas_fp_compare(DisasContext *s, uint32_t insn)
2782 {
2783     unsupported_encoding(s, insn);
2784 }
2785
2786 /* C3.6.23 Floating point conditional compare
2787  *   31  30  29 28       24 23  22  21 20  16 15  12 11 10 9    5  4   3    0
2788  * +---+---+---+-----------+------+---+------+------+-----+------+----+------+
2789  * | M | 0 | S | 1 1 1 1 0 | type | 1 |  Rm  | cond | 0 1 |  Rn  | op | nzcv |
2790  * +---+---+---+-----------+------+---+------+------+-----+------+----+------+
2791  */
2792 static void disas_fp_ccomp(DisasContext *s, uint32_t insn)
2793 {
2794     unsupported_encoding(s, insn);
2795 }
2796
2797 /* C3.6.24 Floating point conditional select
2798  *   31  30  29 28       24 23  22  21 20  16 15  12 11 10 9    5 4    0
2799  * +---+---+---+-----------+------+---+------+------+-----+------+------+
2800  * | M | 0 | S | 1 1 1 1 0 | type | 1 |  Rm  | cond | 1 1 |  Rn  |  Rd  |
2801  * +---+---+---+-----------+------+---+------+------+-----+------+------+
2802  */
2803 static void disas_fp_csel(DisasContext *s, uint32_t insn)
2804 {
2805     unsupported_encoding(s, insn);
2806 }
2807
2808 /* C3.6.25 Floating point data-processing (1 source)
2809  *   31  30  29 28       24 23  22  21 20    15 14       10 9    5 4    0
2810  * +---+---+---+-----------+------+---+--------+-----------+------+------+
2811  * | M | 0 | S | 1 1 1 1 0 | type | 1 | opcode | 1 0 0 0 0 |  Rn  |  Rd  |
2812  * +---+---+---+-----------+------+---+--------+-----------+------+------+
2813  */
2814 static void disas_fp_1src(DisasContext *s, uint32_t insn)
2815 {
2816     unsupported_encoding(s, insn);
2817 }
2818
2819 /* C3.6.26 Floating point data-processing (2 source)
2820  *   31  30  29 28       24 23  22  21 20  16 15    12 11 10 9    5 4    0
2821  * +---+---+---+-----------+------+---+------+--------+-----+------+------+
2822  * | M | 0 | S | 1 1 1 1 0 | type | 1 |  Rm  | opcode | 1 0 |  Rn  |  Rd  |
2823  * +---+---+---+-----------+------+---+------+--------+-----+------+------+
2824  */
2825 static void disas_fp_2src(DisasContext *s, uint32_t insn)
2826 {
2827     unsupported_encoding(s, insn);
2828 }
2829
2830 /* C3.6.27 Floating point data-processing (3 source)
2831  *   31  30  29 28       24 23  22  21  20  16  15  14  10 9    5 4    0
2832  * +---+---+---+-----------+------+----+------+----+------+------+------+
2833  * | M | 0 | S | 1 1 1 1 1 | type | o1 |  Rm  | o0 |  Ra  |  Rn  |  Rd  |
2834  * +---+---+---+-----------+------+----+------+----+------+------+------+
2835  */
2836 static void disas_fp_3src(DisasContext *s, uint32_t insn)
2837 {
2838     unsupported_encoding(s, insn);
2839 }
2840
2841 /* C3.6.28 Floating point immediate
2842  *   31  30  29 28       24 23  22  21 20        13 12   10 9    5 4    0
2843  * +---+---+---+-----------+------+---+------------+-------+------+------+
2844  * | M | 0 | S | 1 1 1 1 0 | type | 1 |    imm8    | 1 0 0 | imm5 |  Rd  |
2845  * +---+---+---+-----------+------+---+------------+-------+------+------+
2846  */
2847 static void disas_fp_imm(DisasContext *s, uint32_t insn)
2848 {
2849     unsupported_encoding(s, insn);
2850 }
2851
2852 /* C3.6.29 Floating point <-> fixed point conversions
2853  *   31   30  29 28       24 23  22  21 20   19 18    16 15   10 9    5 4    0
2854  * +----+---+---+-----------+------+---+-------+--------+-------+------+------+
2855  * | sf | 0 | S | 1 1 1 1 0 | type | 0 | rmode | opcode | scale |  Rn  |  Rd  |
2856  * +----+---+---+-----------+------+---+-------+--------+-------+------+------+
2857  */
2858 static void disas_fp_fixed_conv(DisasContext *s, uint32_t insn)
2859 {
2860     unsupported_encoding(s, insn);
2861 }
2862
2863 static void handle_fmov(DisasContext *s, int rd, int rn, int type, bool itof)
2864 {
2865     /* FMOV: gpr to or from float, double, or top half of quad fp reg,
2866      * without conversion.
2867      */
2868
2869     if (itof) {
2870         int freg_offs = offsetof(CPUARMState, vfp.regs[rd * 2]);
2871         TCGv_i64 tcg_rn = cpu_reg(s, rn);
2872
2873         switch (type) {
2874         case 0:
2875         {
2876             /* 32 bit */
2877             TCGv_i64 tmp = tcg_temp_new_i64();
2878             tcg_gen_ext32u_i64(tmp, tcg_rn);
2879             tcg_gen_st_i64(tmp, cpu_env, freg_offs);
2880             tcg_gen_movi_i64(tmp, 0);
2881             tcg_gen_st_i64(tmp, cpu_env, freg_offs + sizeof(float64));
2882             tcg_temp_free_i64(tmp);
2883             break;
2884         }
2885         case 1:
2886         {
2887             /* 64 bit */
2888             TCGv_i64 tmp = tcg_const_i64(0);
2889             tcg_gen_st_i64(tcg_rn, cpu_env, freg_offs);
2890             tcg_gen_st_i64(tmp, cpu_env, freg_offs + sizeof(float64));
2891             tcg_temp_free_i64(tmp);
2892             break;
2893         }
2894         case 2:
2895             /* 64 bit to top half. */
2896             tcg_gen_st_i64(tcg_rn, cpu_env, freg_offs + sizeof(float64));
2897             break;
2898         }
2899     } else {
2900         int freg_offs = offsetof(CPUARMState, vfp.regs[rn * 2]);
2901         TCGv_i64 tcg_rd = cpu_reg(s, rd);
2902
2903         switch (type) {
2904         case 0:
2905             /* 32 bit */
2906             tcg_gen_ld32u_i64(tcg_rd, cpu_env, freg_offs);
2907             break;
2908         case 2:
2909             /* 64 bits from top half */
2910             freg_offs += sizeof(float64);
2911             /* fall through */
2912         case 1:
2913             /* 64 bit */
2914             tcg_gen_ld_i64(tcg_rd, cpu_env, freg_offs);
2915             break;
2916         }
2917     }
2918 }
2919
2920 /* C3.6.30 Floating point <-> integer conversions
2921  *   31   30  29 28       24 23  22  21 20   19 18 16 15         10 9  5 4  0
2922  * +----+---+---+-----------+------+---+-------+-----+-------------+----+----+
2923  * | sf | 0 | S | 1 1 1 1 0 | type | 0 | rmode | opc | 0 0 0 0 0 0 | Rn | Rd |
2924  * +----+---+---+-----------+------+---+-------+-----+-------------+----+----+
2925  */
2926 static void disas_fp_int_conv(DisasContext *s, uint32_t insn)
2927 {
2928     int rd = extract32(insn, 0, 5);
2929     int rn = extract32(insn, 5, 5);
2930     int opcode = extract32(insn, 16, 3);
2931     int rmode = extract32(insn, 19, 2);
2932     int type = extract32(insn, 22, 2);
2933     bool sbit = extract32(insn, 29, 1);
2934     bool sf = extract32(insn, 31, 1);
2935
2936     if (!sbit && (rmode < 2) && (opcode > 5)) {
2937         /* FMOV */
2938         bool itof = opcode & 1;
2939
2940         switch (sf << 3 | type << 1 | rmode) {
2941         case 0x0: /* 32 bit */
2942         case 0xa: /* 64 bit */
2943         case 0xd: /* 64 bit to top half of quad */
2944             break;
2945         default:
2946             /* all other sf/type/rmode combinations are invalid */
2947             unallocated_encoding(s);
2948             break;
2949         }
2950
2951         handle_fmov(s, rd, rn, type, itof);
2952     } else {
2953         /* actual FP conversions */
2954         unsupported_encoding(s, insn);
2955     }
2956 }
2957
2958 /* FP-specific subcases of table C3-6 (SIMD and FP data processing)
2959  *   31  30  29 28     25 24                          0
2960  * +---+---+---+---------+-----------------------------+
2961  * |   | 0 |   | 1 1 1 1 |                             |
2962  * +---+---+---+---------+-----------------------------+
2963  */
2964 static void disas_data_proc_fp(DisasContext *s, uint32_t insn)
2965 {
2966     if (extract32(insn, 24, 1)) {
2967         /* Floating point data-processing (3 source) */
2968         disas_fp_3src(s, insn);
2969     } else if (extract32(insn, 21, 1) == 0) {
2970         /* Floating point to fixed point conversions */
2971         disas_fp_fixed_conv(s, insn);
2972     } else {
2973         switch (extract32(insn, 10, 2)) {
2974         case 1:
2975             /* Floating point conditional compare */
2976             disas_fp_ccomp(s, insn);
2977             break;
2978         case 2:
2979             /* Floating point data-processing (2 source) */
2980             disas_fp_2src(s, insn);
2981             break;
2982         case 3:
2983             /* Floating point conditional select */
2984             disas_fp_csel(s, insn);
2985             break;
2986         case 0:
2987             switch (ctz32(extract32(insn, 12, 4))) {
2988             case 0: /* [15:12] == xxx1 */
2989                 /* Floating point immediate */
2990                 disas_fp_imm(s, insn);
2991                 break;
2992             case 1: /* [15:12] == xx10 */
2993                 /* Floating point compare */
2994                 disas_fp_compare(s, insn);
2995                 break;
2996             case 2: /* [15:12] == x100 */
2997                 /* Floating point data-processing (1 source) */
2998                 disas_fp_1src(s, insn);
2999                 break;
3000             case 3: /* [15:12] == 1000 */
3001                 unallocated_encoding(s);
3002                 break;
3003             default: /* [15:12] == 0000 */
3004                 /* Floating point <-> integer conversions */
3005                 disas_fp_int_conv(s, insn);
3006                 break;
3007             }
3008             break;
3009         }
3010     }
3011 }
3012
3013 static void disas_data_proc_simd(DisasContext *s, uint32_t insn)
3014 {
3015     /* Note that this is called with all non-FP cases from
3016      * table C3-6 so it must UNDEF for entries not specifically
3017      * allocated to instructions in that table.
3018      */
3019     unsupported_encoding(s, insn);
3020 }
3021
3022 /* C3.6 Data processing - SIMD and floating point */
3023 static void disas_data_proc_simd_fp(DisasContext *s, uint32_t insn)
3024 {
3025     if (extract32(insn, 28, 1) == 1 && extract32(insn, 30, 1) == 0) {
3026         disas_data_proc_fp(s, insn);
3027     } else {
3028         /* SIMD, including crypto */
3029         disas_data_proc_simd(s, insn);
3030     }
3031 }
3032
3033 /* C3.1 A64 instruction index by encoding */
3034 static void disas_a64_insn(CPUARMState *env, DisasContext *s)
3035 {
3036     uint32_t insn;
3037
3038     insn = arm_ldl_code(env, s->pc, s->bswap_code);
3039     s->insn = insn;
3040     s->pc += 4;
3041
3042     switch (extract32(insn, 25, 4)) {
3043     case 0x0: case 0x1: case 0x2: case 0x3: /* UNALLOCATED */
3044         unallocated_encoding(s);
3045         break;
3046     case 0x8: case 0x9: /* Data processing - immediate */
3047         disas_data_proc_imm(s, insn);
3048         break;
3049     case 0xa: case 0xb: /* Branch, exception generation and system insns */
3050         disas_b_exc_sys(s, insn);
3051         break;
3052     case 0x4:
3053     case 0x6:
3054     case 0xc:
3055     case 0xe:      /* Loads and stores */
3056         disas_ldst(s, insn);
3057         break;
3058     case 0x5:
3059     case 0xd:      /* Data processing - register */
3060         disas_data_proc_reg(s, insn);
3061         break;
3062     case 0x7:
3063     case 0xf:      /* Data processing - SIMD and floating point */
3064         disas_data_proc_simd_fp(s, insn);
3065         break;
3066     default:
3067         assert(FALSE); /* all 15 cases should be handled above */
3068         break;
3069     }
3070
3071     /* if we allocated any temporaries, free them here */
3072     free_tmp_a64(s);
3073 }
3074
3075 void gen_intermediate_code_internal_a64(ARMCPU *cpu,
3076                                         TranslationBlock *tb,
3077                                         bool search_pc)
3078 {
3079     CPUState *cs = CPU(cpu);
3080     CPUARMState *env = &cpu->env;
3081     DisasContext dc1, *dc = &dc1;
3082     CPUBreakpoint *bp;
3083     uint16_t *gen_opc_end;
3084     int j, lj;
3085     target_ulong pc_start;
3086     target_ulong next_page_start;
3087     int num_insns;
3088     int max_insns;
3089
3090     pc_start = tb->pc;
3091
3092     dc->tb = tb;
3093
3094     gen_opc_end = tcg_ctx.gen_opc_buf + OPC_MAX_SIZE;
3095
3096     dc->is_jmp = DISAS_NEXT;
3097     dc->pc = pc_start;
3098     dc->singlestep_enabled = cs->singlestep_enabled;
3099     dc->condjmp = 0;
3100
3101     dc->aarch64 = 1;
3102     dc->thumb = 0;
3103     dc->bswap_code = 0;
3104     dc->condexec_mask = 0;
3105     dc->condexec_cond = 0;
3106 #if !defined(CONFIG_USER_ONLY)
3107     dc->user = 0;
3108 #endif
3109     dc->vfp_enabled = 0;
3110     dc->vec_len = 0;
3111     dc->vec_stride = 0;
3112     dc->cp_regs = cpu->cp_regs;
3113     dc->current_pl = arm_current_pl(env);
3114
3115     init_tmp_a64_array(dc);
3116
3117     next_page_start = (pc_start & TARGET_PAGE_MASK) + TARGET_PAGE_SIZE;
3118     lj = -1;
3119     num_insns = 0;
3120     max_insns = tb->cflags & CF_COUNT_MASK;
3121     if (max_insns == 0) {
3122         max_insns = CF_COUNT_MASK;
3123     }
3124
3125     gen_tb_start();
3126
3127     tcg_clear_temp_count();
3128
3129     do {
3130         if (unlikely(!QTAILQ_EMPTY(&env->breakpoints))) {
3131             QTAILQ_FOREACH(bp, &env->breakpoints, entry) {
3132                 if (bp->pc == dc->pc) {
3133                     gen_exception_insn(dc, 0, EXCP_DEBUG);
3134                     /* Advance PC so that clearing the breakpoint will
3135                        invalidate this TB.  */
3136                     dc->pc += 2;
3137                     goto done_generating;
3138                 }
3139             }
3140         }
3141
3142         if (search_pc) {
3143             j = tcg_ctx.gen_opc_ptr - tcg_ctx.gen_opc_buf;
3144             if (lj < j) {
3145                 lj++;
3146                 while (lj < j) {
3147                     tcg_ctx.gen_opc_instr_start[lj++] = 0;
3148                 }
3149             }
3150             tcg_ctx.gen_opc_pc[lj] = dc->pc;
3151             tcg_ctx.gen_opc_instr_start[lj] = 1;
3152             tcg_ctx.gen_opc_icount[lj] = num_insns;
3153         }
3154
3155         if (num_insns + 1 == max_insns && (tb->cflags & CF_LAST_IO)) {
3156             gen_io_start();
3157         }
3158
3159         if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP | CPU_LOG_TB_OP_OPT))) {
3160             tcg_gen_debug_insn_start(dc->pc);
3161         }
3162
3163         disas_a64_insn(env, dc);
3164
3165         if (tcg_check_temp_count()) {
3166             fprintf(stderr, "TCG temporary leak before "TARGET_FMT_lx"\n",
3167                     dc->pc);
3168         }
3169
3170         /* Translation stops when a conditional branch is encountered.
3171          * Otherwise the subsequent code could get translated several times.
3172          * Also stop translation when a page boundary is reached.  This
3173          * ensures prefetch aborts occur at the right place.
3174          */
3175         num_insns++;
3176     } while (!dc->is_jmp && tcg_ctx.gen_opc_ptr < gen_opc_end &&
3177              !cs->singlestep_enabled &&
3178              !singlestep &&
3179              dc->pc < next_page_start &&
3180              num_insns < max_insns);
3181
3182     if (tb->cflags & CF_LAST_IO) {
3183         gen_io_end();
3184     }
3185
3186     if (unlikely(cs->singlestep_enabled) && dc->is_jmp != DISAS_EXC) {
3187         /* Note that this means single stepping WFI doesn't halt the CPU.
3188          * For conditional branch insns this is harmless unreachable code as
3189          * gen_goto_tb() has already handled emitting the debug exception
3190          * (and thus a tb-jump is not possible when singlestepping).
3191          */
3192         assert(dc->is_jmp != DISAS_TB_JUMP);
3193         if (dc->is_jmp != DISAS_JUMP) {
3194             gen_a64_set_pc_im(dc->pc);
3195         }
3196         gen_exception(EXCP_DEBUG);
3197     } else {
3198         switch (dc->is_jmp) {
3199         case DISAS_NEXT:
3200             gen_goto_tb(dc, 1, dc->pc);
3201             break;
3202         default:
3203         case DISAS_UPDATE:
3204             gen_a64_set_pc_im(dc->pc);
3205             /* fall through */
3206         case DISAS_JUMP:
3207             /* indicate that the hash table must be used to find the next TB */
3208             tcg_gen_exit_tb(0);
3209             break;
3210         case DISAS_TB_JUMP:
3211         case DISAS_EXC:
3212         case DISAS_SWI:
3213             break;
3214         case DISAS_WFI:
3215             /* This is a special case because we don't want to just halt the CPU
3216              * if trying to debug across a WFI.
3217              */
3218             gen_helper_wfi(cpu_env);
3219             break;
3220         }
3221     }
3222
3223 done_generating:
3224     gen_tb_end(tb, num_insns);
3225     *tcg_ctx.gen_opc_ptr = INDEX_op_end;
3226
3227 #ifdef DEBUG_DISAS
3228     if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
3229         qemu_log("----------------\n");
3230         qemu_log("IN: %s\n", lookup_symbol(pc_start));
3231         log_target_disas(env, pc_start, dc->pc - pc_start,
3232                          dc->thumb | (dc->bswap_code << 1));
3233         qemu_log("\n");
3234     }
3235 #endif
3236     if (search_pc) {
3237         j = tcg_ctx.gen_opc_ptr - tcg_ctx.gen_opc_buf;
3238         lj++;
3239         while (lj <= j) {
3240             tcg_ctx.gen_opc_instr_start[lj++] = 0;
3241         }
3242     } else {
3243         tb->size = dc->pc - pc_start;
3244         tb->icount = num_insns;
3245     }
3246 }
This page took 0.210818 seconds and 4 git commands to generate.