]> Git Repo - qemu.git/blob - target-arm/translate-a64.c
target-arm: A64: Add SIMD TBL/TBLX
[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 /* Load/store exclusive handling */
42 static TCGv_i64 cpu_exclusive_addr;
43 static TCGv_i64 cpu_exclusive_val;
44 static TCGv_i64 cpu_exclusive_high;
45 #ifdef CONFIG_USER_ONLY
46 static TCGv_i64 cpu_exclusive_test;
47 static TCGv_i32 cpu_exclusive_info;
48 #endif
49
50 static const char *regnames[] = {
51     "x0", "x1", "x2", "x3", "x4", "x5", "x6", "x7",
52     "x8", "x9", "x10", "x11", "x12", "x13", "x14", "x15",
53     "x16", "x17", "x18", "x19", "x20", "x21", "x22", "x23",
54     "x24", "x25", "x26", "x27", "x28", "x29", "lr", "sp"
55 };
56
57 enum a64_shift_type {
58     A64_SHIFT_TYPE_LSL = 0,
59     A64_SHIFT_TYPE_LSR = 1,
60     A64_SHIFT_TYPE_ASR = 2,
61     A64_SHIFT_TYPE_ROR = 3
62 };
63
64 /* Table based decoder typedefs - used when the relevant bits for decode
65  * are too awkwardly scattered across the instruction (eg SIMD).
66  */
67 typedef void AArch64DecodeFn(DisasContext *s, uint32_t insn);
68
69 typedef struct AArch64DecodeTable {
70     uint32_t pattern;
71     uint32_t mask;
72     AArch64DecodeFn *disas_fn;
73 } AArch64DecodeTable;
74
75 /* initialize TCG globals.  */
76 void a64_translate_init(void)
77 {
78     int i;
79
80     cpu_pc = tcg_global_mem_new_i64(TCG_AREG0,
81                                     offsetof(CPUARMState, pc),
82                                     "pc");
83     for (i = 0; i < 32; i++) {
84         cpu_X[i] = tcg_global_mem_new_i64(TCG_AREG0,
85                                           offsetof(CPUARMState, xregs[i]),
86                                           regnames[i]);
87     }
88
89     cpu_NF = tcg_global_mem_new_i32(TCG_AREG0, offsetof(CPUARMState, NF), "NF");
90     cpu_ZF = tcg_global_mem_new_i32(TCG_AREG0, offsetof(CPUARMState, ZF), "ZF");
91     cpu_CF = tcg_global_mem_new_i32(TCG_AREG0, offsetof(CPUARMState, CF), "CF");
92     cpu_VF = tcg_global_mem_new_i32(TCG_AREG0, offsetof(CPUARMState, VF), "VF");
93
94     cpu_exclusive_addr = tcg_global_mem_new_i64(TCG_AREG0,
95         offsetof(CPUARMState, exclusive_addr), "exclusive_addr");
96     cpu_exclusive_val = tcg_global_mem_new_i64(TCG_AREG0,
97         offsetof(CPUARMState, exclusive_val), "exclusive_val");
98     cpu_exclusive_high = tcg_global_mem_new_i64(TCG_AREG0,
99         offsetof(CPUARMState, exclusive_high), "exclusive_high");
100 #ifdef CONFIG_USER_ONLY
101     cpu_exclusive_test = tcg_global_mem_new_i64(TCG_AREG0,
102         offsetof(CPUARMState, exclusive_test), "exclusive_test");
103     cpu_exclusive_info = tcg_global_mem_new_i32(TCG_AREG0,
104         offsetof(CPUARMState, exclusive_info), "exclusive_info");
105 #endif
106 }
107
108 void aarch64_cpu_dump_state(CPUState *cs, FILE *f,
109                             fprintf_function cpu_fprintf, int flags)
110 {
111     ARMCPU *cpu = ARM_CPU(cs);
112     CPUARMState *env = &cpu->env;
113     uint32_t psr = pstate_read(env);
114     int i;
115
116     cpu_fprintf(f, "PC=%016"PRIx64"  SP=%016"PRIx64"\n",
117             env->pc, env->xregs[31]);
118     for (i = 0; i < 31; i++) {
119         cpu_fprintf(f, "X%02d=%016"PRIx64, i, env->xregs[i]);
120         if ((i % 4) == 3) {
121             cpu_fprintf(f, "\n");
122         } else {
123             cpu_fprintf(f, " ");
124         }
125     }
126     cpu_fprintf(f, "PSTATE=%08x (flags %c%c%c%c)\n",
127                 psr,
128                 psr & PSTATE_N ? 'N' : '-',
129                 psr & PSTATE_Z ? 'Z' : '-',
130                 psr & PSTATE_C ? 'C' : '-',
131                 psr & PSTATE_V ? 'V' : '-');
132     cpu_fprintf(f, "\n");
133
134     if (flags & CPU_DUMP_FPU) {
135         int numvfpregs = 32;
136         for (i = 0; i < numvfpregs; i += 2) {
137             uint64_t vlo = float64_val(env->vfp.regs[i * 2]);
138             uint64_t vhi = float64_val(env->vfp.regs[(i * 2) + 1]);
139             cpu_fprintf(f, "q%02d=%016" PRIx64 ":%016" PRIx64 " ",
140                         i, vhi, vlo);
141             vlo = float64_val(env->vfp.regs[(i + 1) * 2]);
142             vhi = float64_val(env->vfp.regs[((i + 1) * 2) + 1]);
143             cpu_fprintf(f, "q%02d=%016" PRIx64 ":%016" PRIx64 "\n",
144                         i + 1, vhi, vlo);
145         }
146         cpu_fprintf(f, "FPCR: %08x  FPSR: %08x\n",
147                     vfp_get_fpcr(env), vfp_get_fpsr(env));
148     }
149 }
150
151 static int get_mem_index(DisasContext *s)
152 {
153 #ifdef CONFIG_USER_ONLY
154     return 1;
155 #else
156     return s->user;
157 #endif
158 }
159
160 void gen_a64_set_pc_im(uint64_t val)
161 {
162     tcg_gen_movi_i64(cpu_pc, val);
163 }
164
165 static void gen_exception(int excp)
166 {
167     TCGv_i32 tmp = tcg_temp_new_i32();
168     tcg_gen_movi_i32(tmp, excp);
169     gen_helper_exception(cpu_env, tmp);
170     tcg_temp_free_i32(tmp);
171 }
172
173 static void gen_exception_insn(DisasContext *s, int offset, int excp)
174 {
175     gen_a64_set_pc_im(s->pc - offset);
176     gen_exception(excp);
177     s->is_jmp = DISAS_EXC;
178 }
179
180 static inline bool use_goto_tb(DisasContext *s, int n, uint64_t dest)
181 {
182     /* No direct tb linking with singlestep or deterministic io */
183     if (s->singlestep_enabled || (s->tb->cflags & CF_LAST_IO)) {
184         return false;
185     }
186
187     /* Only link tbs from inside the same guest page */
188     if ((s->tb->pc & TARGET_PAGE_MASK) != (dest & TARGET_PAGE_MASK)) {
189         return false;
190     }
191
192     return true;
193 }
194
195 static inline void gen_goto_tb(DisasContext *s, int n, uint64_t dest)
196 {
197     TranslationBlock *tb;
198
199     tb = s->tb;
200     if (use_goto_tb(s, n, dest)) {
201         tcg_gen_goto_tb(n);
202         gen_a64_set_pc_im(dest);
203         tcg_gen_exit_tb((tcg_target_long)tb + n);
204         s->is_jmp = DISAS_TB_JUMP;
205     } else {
206         gen_a64_set_pc_im(dest);
207         if (s->singlestep_enabled) {
208             gen_exception(EXCP_DEBUG);
209         }
210         tcg_gen_exit_tb(0);
211         s->is_jmp = DISAS_JUMP;
212     }
213 }
214
215 static void unallocated_encoding(DisasContext *s)
216 {
217     gen_exception_insn(s, 4, EXCP_UDEF);
218 }
219
220 #define unsupported_encoding(s, insn)                                    \
221     do {                                                                 \
222         qemu_log_mask(LOG_UNIMP,                                         \
223                       "%s:%d: unsupported instruction encoding 0x%08x "  \
224                       "at pc=%016" PRIx64 "\n",                          \
225                       __FILE__, __LINE__, insn, s->pc - 4);              \
226         unallocated_encoding(s);                                         \
227     } while (0);
228
229 static void init_tmp_a64_array(DisasContext *s)
230 {
231 #ifdef CONFIG_DEBUG_TCG
232     int i;
233     for (i = 0; i < ARRAY_SIZE(s->tmp_a64); i++) {
234         TCGV_UNUSED_I64(s->tmp_a64[i]);
235     }
236 #endif
237     s->tmp_a64_count = 0;
238 }
239
240 static void free_tmp_a64(DisasContext *s)
241 {
242     int i;
243     for (i = 0; i < s->tmp_a64_count; i++) {
244         tcg_temp_free_i64(s->tmp_a64[i]);
245     }
246     init_tmp_a64_array(s);
247 }
248
249 static TCGv_i64 new_tmp_a64(DisasContext *s)
250 {
251     assert(s->tmp_a64_count < TMP_A64_MAX);
252     return s->tmp_a64[s->tmp_a64_count++] = tcg_temp_new_i64();
253 }
254
255 static TCGv_i64 new_tmp_a64_zero(DisasContext *s)
256 {
257     TCGv_i64 t = new_tmp_a64(s);
258     tcg_gen_movi_i64(t, 0);
259     return t;
260 }
261
262 /*
263  * Register access functions
264  *
265  * These functions are used for directly accessing a register in where
266  * changes to the final register value are likely to be made. If you
267  * need to use a register for temporary calculation (e.g. index type
268  * operations) use the read_* form.
269  *
270  * B1.2.1 Register mappings
271  *
272  * In instruction register encoding 31 can refer to ZR (zero register) or
273  * the SP (stack pointer) depending on context. In QEMU's case we map SP
274  * to cpu_X[31] and ZR accesses to a temporary which can be discarded.
275  * This is the point of the _sp forms.
276  */
277 static TCGv_i64 cpu_reg(DisasContext *s, int reg)
278 {
279     if (reg == 31) {
280         return new_tmp_a64_zero(s);
281     } else {
282         return cpu_X[reg];
283     }
284 }
285
286 /* register access for when 31 == SP */
287 static TCGv_i64 cpu_reg_sp(DisasContext *s, int reg)
288 {
289     return cpu_X[reg];
290 }
291
292 /* read a cpu register in 32bit/64bit mode. Returns a TCGv_i64
293  * representing the register contents. This TCGv is an auto-freed
294  * temporary so it need not be explicitly freed, and may be modified.
295  */
296 static TCGv_i64 read_cpu_reg(DisasContext *s, int reg, int sf)
297 {
298     TCGv_i64 v = new_tmp_a64(s);
299     if (reg != 31) {
300         if (sf) {
301             tcg_gen_mov_i64(v, cpu_X[reg]);
302         } else {
303             tcg_gen_ext32u_i64(v, cpu_X[reg]);
304         }
305     } else {
306         tcg_gen_movi_i64(v, 0);
307     }
308     return v;
309 }
310
311 static TCGv_i64 read_cpu_reg_sp(DisasContext *s, int reg, int sf)
312 {
313     TCGv_i64 v = new_tmp_a64(s);
314     if (sf) {
315         tcg_gen_mov_i64(v, cpu_X[reg]);
316     } else {
317         tcg_gen_ext32u_i64(v, cpu_X[reg]);
318     }
319     return v;
320 }
321
322 /* Return the offset into CPUARMState of an element of specified
323  * size, 'element' places in from the least significant end of
324  * the FP/vector register Qn.
325  */
326 static inline int vec_reg_offset(int regno, int element, TCGMemOp size)
327 {
328     int offs = offsetof(CPUARMState, vfp.regs[regno * 2]);
329 #ifdef HOST_WORDS_BIGENDIAN
330     /* This is complicated slightly because vfp.regs[2n] is
331      * still the low half and  vfp.regs[2n+1] the high half
332      * of the 128 bit vector, even on big endian systems.
333      * Calculate the offset assuming a fully bigendian 128 bits,
334      * then XOR to account for the order of the two 64 bit halves.
335      */
336     offs += (16 - ((element + 1) * (1 << size)));
337     offs ^= 8;
338 #else
339     offs += element * (1 << size);
340 #endif
341     return offs;
342 }
343
344 /* Return the offset into CPUARMState of a slice (from
345  * the least significant end) of FP register Qn (ie
346  * Dn, Sn, Hn or Bn).
347  * (Note that this is not the same mapping as for A32; see cpu.h)
348  */
349 static inline int fp_reg_offset(int regno, TCGMemOp size)
350 {
351     int offs = offsetof(CPUARMState, vfp.regs[regno * 2]);
352 #ifdef HOST_WORDS_BIGENDIAN
353     offs += (8 - (1 << size));
354 #endif
355     return offs;
356 }
357
358 /* Offset of the high half of the 128 bit vector Qn */
359 static inline int fp_reg_hi_offset(int regno)
360 {
361     return offsetof(CPUARMState, vfp.regs[regno * 2 + 1]);
362 }
363
364 /* Convenience accessors for reading and writing single and double
365  * FP registers. Writing clears the upper parts of the associated
366  * 128 bit vector register, as required by the architecture.
367  * Note that unlike the GP register accessors, the values returned
368  * by the read functions must be manually freed.
369  */
370 static TCGv_i64 read_fp_dreg(DisasContext *s, int reg)
371 {
372     TCGv_i64 v = tcg_temp_new_i64();
373
374     tcg_gen_ld_i64(v, cpu_env, fp_reg_offset(reg, MO_64));
375     return v;
376 }
377
378 static TCGv_i32 read_fp_sreg(DisasContext *s, int reg)
379 {
380     TCGv_i32 v = tcg_temp_new_i32();
381
382     tcg_gen_ld_i32(v, cpu_env, fp_reg_offset(reg, MO_32));
383     return v;
384 }
385
386 static void write_fp_dreg(DisasContext *s, int reg, TCGv_i64 v)
387 {
388     TCGv_i64 tcg_zero = tcg_const_i64(0);
389
390     tcg_gen_st_i64(v, cpu_env, fp_reg_offset(reg, MO_64));
391     tcg_gen_st_i64(tcg_zero, cpu_env, fp_reg_hi_offset(reg));
392     tcg_temp_free_i64(tcg_zero);
393 }
394
395 static void write_fp_sreg(DisasContext *s, int reg, TCGv_i32 v)
396 {
397     TCGv_i64 tmp = tcg_temp_new_i64();
398
399     tcg_gen_extu_i32_i64(tmp, v);
400     write_fp_dreg(s, reg, tmp);
401     tcg_temp_free_i64(tmp);
402 }
403
404 static TCGv_ptr get_fpstatus_ptr(void)
405 {
406     TCGv_ptr statusptr = tcg_temp_new_ptr();
407     int offset;
408
409     /* In A64 all instructions (both FP and Neon) use the FPCR;
410      * there is no equivalent of the A32 Neon "standard FPSCR value"
411      * and all operations use vfp.fp_status.
412      */
413     offset = offsetof(CPUARMState, vfp.fp_status);
414     tcg_gen_addi_ptr(statusptr, cpu_env, offset);
415     return statusptr;
416 }
417
418 /* Set ZF and NF based on a 64 bit result. This is alas fiddlier
419  * than the 32 bit equivalent.
420  */
421 static inline void gen_set_NZ64(TCGv_i64 result)
422 {
423     TCGv_i64 flag = tcg_temp_new_i64();
424
425     tcg_gen_setcondi_i64(TCG_COND_NE, flag, result, 0);
426     tcg_gen_trunc_i64_i32(cpu_ZF, flag);
427     tcg_gen_shri_i64(flag, result, 32);
428     tcg_gen_trunc_i64_i32(cpu_NF, flag);
429     tcg_temp_free_i64(flag);
430 }
431
432 /* Set NZCV as for a logical operation: NZ as per result, CV cleared. */
433 static inline void gen_logic_CC(int sf, TCGv_i64 result)
434 {
435     if (sf) {
436         gen_set_NZ64(result);
437     } else {
438         tcg_gen_trunc_i64_i32(cpu_ZF, result);
439         tcg_gen_trunc_i64_i32(cpu_NF, result);
440     }
441     tcg_gen_movi_i32(cpu_CF, 0);
442     tcg_gen_movi_i32(cpu_VF, 0);
443 }
444
445 /* dest = T0 + T1; compute C, N, V and Z flags */
446 static void gen_add_CC(int sf, TCGv_i64 dest, TCGv_i64 t0, TCGv_i64 t1)
447 {
448     if (sf) {
449         TCGv_i64 result, flag, tmp;
450         result = tcg_temp_new_i64();
451         flag = tcg_temp_new_i64();
452         tmp = tcg_temp_new_i64();
453
454         tcg_gen_movi_i64(tmp, 0);
455         tcg_gen_add2_i64(result, flag, t0, tmp, t1, tmp);
456
457         tcg_gen_trunc_i64_i32(cpu_CF, flag);
458
459         gen_set_NZ64(result);
460
461         tcg_gen_xor_i64(flag, result, t0);
462         tcg_gen_xor_i64(tmp, t0, t1);
463         tcg_gen_andc_i64(flag, flag, tmp);
464         tcg_temp_free_i64(tmp);
465         tcg_gen_shri_i64(flag, flag, 32);
466         tcg_gen_trunc_i64_i32(cpu_VF, flag);
467
468         tcg_gen_mov_i64(dest, result);
469         tcg_temp_free_i64(result);
470         tcg_temp_free_i64(flag);
471     } else {
472         /* 32 bit arithmetic */
473         TCGv_i32 t0_32 = tcg_temp_new_i32();
474         TCGv_i32 t1_32 = tcg_temp_new_i32();
475         TCGv_i32 tmp = tcg_temp_new_i32();
476
477         tcg_gen_movi_i32(tmp, 0);
478         tcg_gen_trunc_i64_i32(t0_32, t0);
479         tcg_gen_trunc_i64_i32(t1_32, t1);
480         tcg_gen_add2_i32(cpu_NF, cpu_CF, t0_32, tmp, t1_32, tmp);
481         tcg_gen_mov_i32(cpu_ZF, cpu_NF);
482         tcg_gen_xor_i32(cpu_VF, cpu_NF, t0_32);
483         tcg_gen_xor_i32(tmp, t0_32, t1_32);
484         tcg_gen_andc_i32(cpu_VF, cpu_VF, tmp);
485         tcg_gen_extu_i32_i64(dest, cpu_NF);
486
487         tcg_temp_free_i32(tmp);
488         tcg_temp_free_i32(t0_32);
489         tcg_temp_free_i32(t1_32);
490     }
491 }
492
493 /* dest = T0 - T1; compute C, N, V and Z flags */
494 static void gen_sub_CC(int sf, TCGv_i64 dest, TCGv_i64 t0, TCGv_i64 t1)
495 {
496     if (sf) {
497         /* 64 bit arithmetic */
498         TCGv_i64 result, flag, tmp;
499
500         result = tcg_temp_new_i64();
501         flag = tcg_temp_new_i64();
502         tcg_gen_sub_i64(result, t0, t1);
503
504         gen_set_NZ64(result);
505
506         tcg_gen_setcond_i64(TCG_COND_GEU, flag, t0, t1);
507         tcg_gen_trunc_i64_i32(cpu_CF, flag);
508
509         tcg_gen_xor_i64(flag, result, t0);
510         tmp = tcg_temp_new_i64();
511         tcg_gen_xor_i64(tmp, t0, t1);
512         tcg_gen_and_i64(flag, flag, tmp);
513         tcg_temp_free_i64(tmp);
514         tcg_gen_shri_i64(flag, flag, 32);
515         tcg_gen_trunc_i64_i32(cpu_VF, flag);
516         tcg_gen_mov_i64(dest, result);
517         tcg_temp_free_i64(flag);
518         tcg_temp_free_i64(result);
519     } else {
520         /* 32 bit arithmetic */
521         TCGv_i32 t0_32 = tcg_temp_new_i32();
522         TCGv_i32 t1_32 = tcg_temp_new_i32();
523         TCGv_i32 tmp;
524
525         tcg_gen_trunc_i64_i32(t0_32, t0);
526         tcg_gen_trunc_i64_i32(t1_32, t1);
527         tcg_gen_sub_i32(cpu_NF, t0_32, t1_32);
528         tcg_gen_mov_i32(cpu_ZF, cpu_NF);
529         tcg_gen_setcond_i32(TCG_COND_GEU, cpu_CF, t0_32, t1_32);
530         tcg_gen_xor_i32(cpu_VF, cpu_NF, t0_32);
531         tmp = tcg_temp_new_i32();
532         tcg_gen_xor_i32(tmp, t0_32, t1_32);
533         tcg_temp_free_i32(t0_32);
534         tcg_temp_free_i32(t1_32);
535         tcg_gen_and_i32(cpu_VF, cpu_VF, tmp);
536         tcg_temp_free_i32(tmp);
537         tcg_gen_extu_i32_i64(dest, cpu_NF);
538     }
539 }
540
541 /* dest = T0 + T1 + CF; do not compute flags. */
542 static void gen_adc(int sf, TCGv_i64 dest, TCGv_i64 t0, TCGv_i64 t1)
543 {
544     TCGv_i64 flag = tcg_temp_new_i64();
545     tcg_gen_extu_i32_i64(flag, cpu_CF);
546     tcg_gen_add_i64(dest, t0, t1);
547     tcg_gen_add_i64(dest, dest, flag);
548     tcg_temp_free_i64(flag);
549
550     if (!sf) {
551         tcg_gen_ext32u_i64(dest, dest);
552     }
553 }
554
555 /* dest = T0 + T1 + CF; compute C, N, V and Z flags. */
556 static void gen_adc_CC(int sf, TCGv_i64 dest, TCGv_i64 t0, TCGv_i64 t1)
557 {
558     if (sf) {
559         TCGv_i64 result, cf_64, vf_64, tmp;
560         result = tcg_temp_new_i64();
561         cf_64 = tcg_temp_new_i64();
562         vf_64 = tcg_temp_new_i64();
563         tmp = tcg_const_i64(0);
564
565         tcg_gen_extu_i32_i64(cf_64, cpu_CF);
566         tcg_gen_add2_i64(result, cf_64, t0, tmp, cf_64, tmp);
567         tcg_gen_add2_i64(result, cf_64, result, cf_64, t1, tmp);
568         tcg_gen_trunc_i64_i32(cpu_CF, cf_64);
569         gen_set_NZ64(result);
570
571         tcg_gen_xor_i64(vf_64, result, t0);
572         tcg_gen_xor_i64(tmp, t0, t1);
573         tcg_gen_andc_i64(vf_64, vf_64, tmp);
574         tcg_gen_shri_i64(vf_64, vf_64, 32);
575         tcg_gen_trunc_i64_i32(cpu_VF, vf_64);
576
577         tcg_gen_mov_i64(dest, result);
578
579         tcg_temp_free_i64(tmp);
580         tcg_temp_free_i64(vf_64);
581         tcg_temp_free_i64(cf_64);
582         tcg_temp_free_i64(result);
583     } else {
584         TCGv_i32 t0_32, t1_32, tmp;
585         t0_32 = tcg_temp_new_i32();
586         t1_32 = tcg_temp_new_i32();
587         tmp = tcg_const_i32(0);
588
589         tcg_gen_trunc_i64_i32(t0_32, t0);
590         tcg_gen_trunc_i64_i32(t1_32, t1);
591         tcg_gen_add2_i32(cpu_NF, cpu_CF, t0_32, tmp, cpu_CF, tmp);
592         tcg_gen_add2_i32(cpu_NF, cpu_CF, cpu_NF, cpu_CF, t1_32, tmp);
593
594         tcg_gen_mov_i32(cpu_ZF, cpu_NF);
595         tcg_gen_xor_i32(cpu_VF, cpu_NF, t0_32);
596         tcg_gen_xor_i32(tmp, t0_32, t1_32);
597         tcg_gen_andc_i32(cpu_VF, cpu_VF, tmp);
598         tcg_gen_extu_i32_i64(dest, cpu_NF);
599
600         tcg_temp_free_i32(tmp);
601         tcg_temp_free_i32(t1_32);
602         tcg_temp_free_i32(t0_32);
603     }
604 }
605
606 /*
607  * Load/Store generators
608  */
609
610 /*
611  * Store from GPR register to memory
612  */
613 static void do_gpr_st(DisasContext *s, TCGv_i64 source,
614                       TCGv_i64 tcg_addr, int size)
615 {
616     g_assert(size <= 3);
617     tcg_gen_qemu_st_i64(source, tcg_addr, get_mem_index(s), MO_TE + size);
618 }
619
620 /*
621  * Load from memory to GPR register
622  */
623 static void do_gpr_ld(DisasContext *s, TCGv_i64 dest, TCGv_i64 tcg_addr,
624                       int size, bool is_signed, bool extend)
625 {
626     TCGMemOp memop = MO_TE + size;
627
628     g_assert(size <= 3);
629
630     if (is_signed) {
631         memop += MO_SIGN;
632     }
633
634     tcg_gen_qemu_ld_i64(dest, tcg_addr, get_mem_index(s), memop);
635
636     if (extend && is_signed) {
637         g_assert(size < 3);
638         tcg_gen_ext32u_i64(dest, dest);
639     }
640 }
641
642 /*
643  * Store from FP register to memory
644  */
645 static void do_fp_st(DisasContext *s, int srcidx, TCGv_i64 tcg_addr, int size)
646 {
647     /* This writes the bottom N bits of a 128 bit wide vector to memory */
648     TCGv_i64 tmp = tcg_temp_new_i64();
649     tcg_gen_ld_i64(tmp, cpu_env, fp_reg_offset(srcidx, MO_64));
650     if (size < 4) {
651         tcg_gen_qemu_st_i64(tmp, tcg_addr, get_mem_index(s), MO_TE + size);
652     } else {
653         TCGv_i64 tcg_hiaddr = tcg_temp_new_i64();
654         tcg_gen_qemu_st_i64(tmp, tcg_addr, get_mem_index(s), MO_TEQ);
655         tcg_gen_qemu_st64(tmp, tcg_addr, get_mem_index(s));
656         tcg_gen_ld_i64(tmp, cpu_env, fp_reg_hi_offset(srcidx));
657         tcg_gen_addi_i64(tcg_hiaddr, tcg_addr, 8);
658         tcg_gen_qemu_st_i64(tmp, tcg_hiaddr, get_mem_index(s), MO_TEQ);
659         tcg_temp_free_i64(tcg_hiaddr);
660     }
661
662     tcg_temp_free_i64(tmp);
663 }
664
665 /*
666  * Load from memory to FP register
667  */
668 static void do_fp_ld(DisasContext *s, int destidx, TCGv_i64 tcg_addr, int size)
669 {
670     /* This always zero-extends and writes to a full 128 bit wide vector */
671     TCGv_i64 tmplo = tcg_temp_new_i64();
672     TCGv_i64 tmphi;
673
674     if (size < 4) {
675         TCGMemOp memop = MO_TE + size;
676         tmphi = tcg_const_i64(0);
677         tcg_gen_qemu_ld_i64(tmplo, tcg_addr, get_mem_index(s), memop);
678     } else {
679         TCGv_i64 tcg_hiaddr;
680         tmphi = tcg_temp_new_i64();
681         tcg_hiaddr = tcg_temp_new_i64();
682
683         tcg_gen_qemu_ld_i64(tmplo, tcg_addr, get_mem_index(s), MO_TEQ);
684         tcg_gen_addi_i64(tcg_hiaddr, tcg_addr, 8);
685         tcg_gen_qemu_ld_i64(tmphi, tcg_hiaddr, get_mem_index(s), MO_TEQ);
686         tcg_temp_free_i64(tcg_hiaddr);
687     }
688
689     tcg_gen_st_i64(tmplo, cpu_env, fp_reg_offset(destidx, MO_64));
690     tcg_gen_st_i64(tmphi, cpu_env, fp_reg_hi_offset(destidx));
691
692     tcg_temp_free_i64(tmplo);
693     tcg_temp_free_i64(tmphi);
694 }
695
696 /*
697  * Vector load/store helpers.
698  *
699  * The principal difference between this and a FP load is that we don't
700  * zero extend as we are filling a partial chunk of the vector register.
701  * These functions don't support 128 bit loads/stores, which would be
702  * normal load/store operations.
703  */
704
705 /* Get value of an element within a vector register */
706 static void read_vec_element(DisasContext *s, TCGv_i64 tcg_dest, int srcidx,
707                              int element, TCGMemOp memop)
708 {
709     int vect_off = vec_reg_offset(srcidx, element, memop & MO_SIZE);
710     switch (memop) {
711     case MO_8:
712         tcg_gen_ld8u_i64(tcg_dest, cpu_env, vect_off);
713         break;
714     case MO_16:
715         tcg_gen_ld16u_i64(tcg_dest, cpu_env, vect_off);
716         break;
717     case MO_32:
718         tcg_gen_ld32u_i64(tcg_dest, cpu_env, vect_off);
719         break;
720     case MO_8|MO_SIGN:
721         tcg_gen_ld8s_i64(tcg_dest, cpu_env, vect_off);
722         break;
723     case MO_16|MO_SIGN:
724         tcg_gen_ld16s_i64(tcg_dest, cpu_env, vect_off);
725         break;
726     case MO_32|MO_SIGN:
727         tcg_gen_ld32s_i64(tcg_dest, cpu_env, vect_off);
728         break;
729     case MO_64:
730     case MO_64|MO_SIGN:
731         tcg_gen_ld_i64(tcg_dest, cpu_env, vect_off);
732         break;
733     default:
734         g_assert_not_reached();
735     }
736 }
737
738 /* Set value of an element within a vector register */
739 static void write_vec_element(DisasContext *s, TCGv_i64 tcg_src, int destidx,
740                               int element, TCGMemOp memop)
741 {
742     int vect_off = vec_reg_offset(destidx, element, memop & MO_SIZE);
743     switch (memop) {
744     case MO_8:
745         tcg_gen_st8_i64(tcg_src, cpu_env, vect_off);
746         break;
747     case MO_16:
748         tcg_gen_st16_i64(tcg_src, cpu_env, vect_off);
749         break;
750     case MO_32:
751         tcg_gen_st32_i64(tcg_src, cpu_env, vect_off);
752         break;
753     case MO_64:
754         tcg_gen_st_i64(tcg_src, cpu_env, vect_off);
755         break;
756     default:
757         g_assert_not_reached();
758     }
759 }
760
761 /* Clear the high 64 bits of a 128 bit vector (in general non-quad
762  * vector ops all need to do this).
763  */
764 static void clear_vec_high(DisasContext *s, int rd)
765 {
766     TCGv_i64 tcg_zero = tcg_const_i64(0);
767
768     write_vec_element(s, tcg_zero, rd, 1, MO_64);
769     tcg_temp_free_i64(tcg_zero);
770 }
771
772 /* Store from vector register to memory */
773 static void do_vec_st(DisasContext *s, int srcidx, int element,
774                       TCGv_i64 tcg_addr, int size)
775 {
776     TCGMemOp memop = MO_TE + size;
777     TCGv_i64 tcg_tmp = tcg_temp_new_i64();
778
779     read_vec_element(s, tcg_tmp, srcidx, element, size);
780     tcg_gen_qemu_st_i64(tcg_tmp, tcg_addr, get_mem_index(s), memop);
781
782     tcg_temp_free_i64(tcg_tmp);
783 }
784
785 /* Load from memory to vector register */
786 static void do_vec_ld(DisasContext *s, int destidx, int element,
787                       TCGv_i64 tcg_addr, int size)
788 {
789     TCGMemOp memop = MO_TE + size;
790     TCGv_i64 tcg_tmp = tcg_temp_new_i64();
791
792     tcg_gen_qemu_ld_i64(tcg_tmp, tcg_addr, get_mem_index(s), memop);
793     write_vec_element(s, tcg_tmp, destidx, element, size);
794
795     tcg_temp_free_i64(tcg_tmp);
796 }
797
798 /*
799  * This utility function is for doing register extension with an
800  * optional shift. You will likely want to pass a temporary for the
801  * destination register. See DecodeRegExtend() in the ARM ARM.
802  */
803 static void ext_and_shift_reg(TCGv_i64 tcg_out, TCGv_i64 tcg_in,
804                               int option, unsigned int shift)
805 {
806     int extsize = extract32(option, 0, 2);
807     bool is_signed = extract32(option, 2, 1);
808
809     if (is_signed) {
810         switch (extsize) {
811         case 0:
812             tcg_gen_ext8s_i64(tcg_out, tcg_in);
813             break;
814         case 1:
815             tcg_gen_ext16s_i64(tcg_out, tcg_in);
816             break;
817         case 2:
818             tcg_gen_ext32s_i64(tcg_out, tcg_in);
819             break;
820         case 3:
821             tcg_gen_mov_i64(tcg_out, tcg_in);
822             break;
823         }
824     } else {
825         switch (extsize) {
826         case 0:
827             tcg_gen_ext8u_i64(tcg_out, tcg_in);
828             break;
829         case 1:
830             tcg_gen_ext16u_i64(tcg_out, tcg_in);
831             break;
832         case 2:
833             tcg_gen_ext32u_i64(tcg_out, tcg_in);
834             break;
835         case 3:
836             tcg_gen_mov_i64(tcg_out, tcg_in);
837             break;
838         }
839     }
840
841     if (shift) {
842         tcg_gen_shli_i64(tcg_out, tcg_out, shift);
843     }
844 }
845
846 static inline void gen_check_sp_alignment(DisasContext *s)
847 {
848     /* The AArch64 architecture mandates that (if enabled via PSTATE
849      * or SCTLR bits) there is a check that SP is 16-aligned on every
850      * SP-relative load or store (with an exception generated if it is not).
851      * In line with general QEMU practice regarding misaligned accesses,
852      * we omit these checks for the sake of guest program performance.
853      * This function is provided as a hook so we can more easily add these
854      * checks in future (possibly as a "favour catching guest program bugs
855      * over speed" user selectable option).
856      */
857 }
858
859 /*
860  * This provides a simple table based table lookup decoder. It is
861  * intended to be used when the relevant bits for decode are too
862  * awkwardly placed and switch/if based logic would be confusing and
863  * deeply nested. Since it's a linear search through the table, tables
864  * should be kept small.
865  *
866  * It returns the first handler where insn & mask == pattern, or
867  * NULL if there is no match.
868  * The table is terminated by an empty mask (i.e. 0)
869  */
870 static inline AArch64DecodeFn *lookup_disas_fn(const AArch64DecodeTable *table,
871                                                uint32_t insn)
872 {
873     const AArch64DecodeTable *tptr = table;
874
875     while (tptr->mask) {
876         if ((insn & tptr->mask) == tptr->pattern) {
877             return tptr->disas_fn;
878         }
879         tptr++;
880     }
881     return NULL;
882 }
883
884 /*
885  * the instruction disassembly implemented here matches
886  * the instruction encoding classifications in chapter 3 (C3)
887  * of the ARM Architecture Reference Manual (DDI0487A_a)
888  */
889
890 /* C3.2.7 Unconditional branch (immediate)
891  *   31  30       26 25                                  0
892  * +----+-----------+-------------------------------------+
893  * | op | 0 0 1 0 1 |                 imm26               |
894  * +----+-----------+-------------------------------------+
895  */
896 static void disas_uncond_b_imm(DisasContext *s, uint32_t insn)
897 {
898     uint64_t addr = s->pc + sextract32(insn, 0, 26) * 4 - 4;
899
900     if (insn & (1 << 31)) {
901         /* C5.6.26 BL Branch with link */
902         tcg_gen_movi_i64(cpu_reg(s, 30), s->pc);
903     }
904
905     /* C5.6.20 B Branch / C5.6.26 BL Branch with link */
906     gen_goto_tb(s, 0, addr);
907 }
908
909 /* C3.2.1 Compare & branch (immediate)
910  *   31  30         25  24  23                  5 4      0
911  * +----+-------------+----+---------------------+--------+
912  * | sf | 0 1 1 0 1 0 | op |         imm19       |   Rt   |
913  * +----+-------------+----+---------------------+--------+
914  */
915 static void disas_comp_b_imm(DisasContext *s, uint32_t insn)
916 {
917     unsigned int sf, op, rt;
918     uint64_t addr;
919     int label_match;
920     TCGv_i64 tcg_cmp;
921
922     sf = extract32(insn, 31, 1);
923     op = extract32(insn, 24, 1); /* 0: CBZ; 1: CBNZ */
924     rt = extract32(insn, 0, 5);
925     addr = s->pc + sextract32(insn, 5, 19) * 4 - 4;
926
927     tcg_cmp = read_cpu_reg(s, rt, sf);
928     label_match = gen_new_label();
929
930     tcg_gen_brcondi_i64(op ? TCG_COND_NE : TCG_COND_EQ,
931                         tcg_cmp, 0, label_match);
932
933     gen_goto_tb(s, 0, s->pc);
934     gen_set_label(label_match);
935     gen_goto_tb(s, 1, addr);
936 }
937
938 /* C3.2.5 Test & branch (immediate)
939  *   31  30         25  24  23   19 18          5 4    0
940  * +----+-------------+----+-------+-------------+------+
941  * | b5 | 0 1 1 0 1 1 | op |  b40  |    imm14    |  Rt  |
942  * +----+-------------+----+-------+-------------+------+
943  */
944 static void disas_test_b_imm(DisasContext *s, uint32_t insn)
945 {
946     unsigned int bit_pos, op, rt;
947     uint64_t addr;
948     int label_match;
949     TCGv_i64 tcg_cmp;
950
951     bit_pos = (extract32(insn, 31, 1) << 5) | extract32(insn, 19, 5);
952     op = extract32(insn, 24, 1); /* 0: TBZ; 1: TBNZ */
953     addr = s->pc + sextract32(insn, 5, 14) * 4 - 4;
954     rt = extract32(insn, 0, 5);
955
956     tcg_cmp = tcg_temp_new_i64();
957     tcg_gen_andi_i64(tcg_cmp, cpu_reg(s, rt), (1ULL << bit_pos));
958     label_match = gen_new_label();
959     tcg_gen_brcondi_i64(op ? TCG_COND_NE : TCG_COND_EQ,
960                         tcg_cmp, 0, label_match);
961     tcg_temp_free_i64(tcg_cmp);
962     gen_goto_tb(s, 0, s->pc);
963     gen_set_label(label_match);
964     gen_goto_tb(s, 1, addr);
965 }
966
967 /* C3.2.2 / C5.6.19 Conditional branch (immediate)
968  *  31           25  24  23                  5   4  3    0
969  * +---------------+----+---------------------+----+------+
970  * | 0 1 0 1 0 1 0 | o1 |         imm19       | o0 | cond |
971  * +---------------+----+---------------------+----+------+
972  */
973 static void disas_cond_b_imm(DisasContext *s, uint32_t insn)
974 {
975     unsigned int cond;
976     uint64_t addr;
977
978     if ((insn & (1 << 4)) || (insn & (1 << 24))) {
979         unallocated_encoding(s);
980         return;
981     }
982     addr = s->pc + sextract32(insn, 5, 19) * 4 - 4;
983     cond = extract32(insn, 0, 4);
984
985     if (cond < 0x0e) {
986         /* genuinely conditional branches */
987         int label_match = gen_new_label();
988         arm_gen_test_cc(cond, label_match);
989         gen_goto_tb(s, 0, s->pc);
990         gen_set_label(label_match);
991         gen_goto_tb(s, 1, addr);
992     } else {
993         /* 0xe and 0xf are both "always" conditions */
994         gen_goto_tb(s, 0, addr);
995     }
996 }
997
998 /* C5.6.68 HINT */
999 static void handle_hint(DisasContext *s, uint32_t insn,
1000                         unsigned int op1, unsigned int op2, unsigned int crm)
1001 {
1002     unsigned int selector = crm << 3 | op2;
1003
1004     if (op1 != 3) {
1005         unallocated_encoding(s);
1006         return;
1007     }
1008
1009     switch (selector) {
1010     case 0: /* NOP */
1011         return;
1012     case 1: /* YIELD */
1013     case 2: /* WFE */
1014     case 3: /* WFI */
1015     case 4: /* SEV */
1016     case 5: /* SEVL */
1017         /* we treat all as NOP at least for now */
1018         return;
1019     default:
1020         /* default specified as NOP equivalent */
1021         return;
1022     }
1023 }
1024
1025 static void gen_clrex(DisasContext *s, uint32_t insn)
1026 {
1027     tcg_gen_movi_i64(cpu_exclusive_addr, -1);
1028 }
1029
1030 /* CLREX, DSB, DMB, ISB */
1031 static void handle_sync(DisasContext *s, uint32_t insn,
1032                         unsigned int op1, unsigned int op2, unsigned int crm)
1033 {
1034     if (op1 != 3) {
1035         unallocated_encoding(s);
1036         return;
1037     }
1038
1039     switch (op2) {
1040     case 2: /* CLREX */
1041         gen_clrex(s, insn);
1042         return;
1043     case 4: /* DSB */
1044     case 5: /* DMB */
1045     case 6: /* ISB */
1046         /* We don't emulate caches so barriers are no-ops */
1047         return;
1048     default:
1049         unallocated_encoding(s);
1050         return;
1051     }
1052 }
1053
1054 /* C5.6.130 MSR (immediate) - move immediate to processor state field */
1055 static void handle_msr_i(DisasContext *s, uint32_t insn,
1056                          unsigned int op1, unsigned int op2, unsigned int crm)
1057 {
1058     unsupported_encoding(s, insn);
1059 }
1060
1061 static void gen_get_nzcv(TCGv_i64 tcg_rt)
1062 {
1063     TCGv_i32 tmp = tcg_temp_new_i32();
1064     TCGv_i32 nzcv = tcg_temp_new_i32();
1065
1066     /* build bit 31, N */
1067     tcg_gen_andi_i32(nzcv, cpu_NF, (1 << 31));
1068     /* build bit 30, Z */
1069     tcg_gen_setcondi_i32(TCG_COND_EQ, tmp, cpu_ZF, 0);
1070     tcg_gen_deposit_i32(nzcv, nzcv, tmp, 30, 1);
1071     /* build bit 29, C */
1072     tcg_gen_deposit_i32(nzcv, nzcv, cpu_CF, 29, 1);
1073     /* build bit 28, V */
1074     tcg_gen_shri_i32(tmp, cpu_VF, 31);
1075     tcg_gen_deposit_i32(nzcv, nzcv, tmp, 28, 1);
1076     /* generate result */
1077     tcg_gen_extu_i32_i64(tcg_rt, nzcv);
1078
1079     tcg_temp_free_i32(nzcv);
1080     tcg_temp_free_i32(tmp);
1081 }
1082
1083 static void gen_set_nzcv(TCGv_i64 tcg_rt)
1084
1085 {
1086     TCGv_i32 nzcv = tcg_temp_new_i32();
1087
1088     /* take NZCV from R[t] */
1089     tcg_gen_trunc_i64_i32(nzcv, tcg_rt);
1090
1091     /* bit 31, N */
1092     tcg_gen_andi_i32(cpu_NF, nzcv, (1 << 31));
1093     /* bit 30, Z */
1094     tcg_gen_andi_i32(cpu_ZF, nzcv, (1 << 30));
1095     tcg_gen_setcondi_i32(TCG_COND_EQ, cpu_ZF, cpu_ZF, 0);
1096     /* bit 29, C */
1097     tcg_gen_andi_i32(cpu_CF, nzcv, (1 << 29));
1098     tcg_gen_shri_i32(cpu_CF, cpu_CF, 29);
1099     /* bit 28, V */
1100     tcg_gen_andi_i32(cpu_VF, nzcv, (1 << 28));
1101     tcg_gen_shli_i32(cpu_VF, cpu_VF, 3);
1102     tcg_temp_free_i32(nzcv);
1103 }
1104
1105 /* C5.6.129 MRS - move from system register
1106  * C5.6.131 MSR (register) - move to system register
1107  * C5.6.204 SYS
1108  * C5.6.205 SYSL
1109  * These are all essentially the same insn in 'read' and 'write'
1110  * versions, with varying op0 fields.
1111  */
1112 static void handle_sys(DisasContext *s, uint32_t insn, bool isread,
1113                        unsigned int op0, unsigned int op1, unsigned int op2,
1114                        unsigned int crn, unsigned int crm, unsigned int rt)
1115 {
1116     const ARMCPRegInfo *ri;
1117     TCGv_i64 tcg_rt;
1118
1119     ri = get_arm_cp_reginfo(s->cp_regs,
1120                             ENCODE_AA64_CP_REG(CP_REG_ARM64_SYSREG_CP,
1121                                                crn, crm, op0, op1, op2));
1122
1123     if (!ri) {
1124         /* Unknown register */
1125         unallocated_encoding(s);
1126         return;
1127     }
1128
1129     /* Check access permissions */
1130     if (!cp_access_ok(s->current_pl, ri, isread)) {
1131         unallocated_encoding(s);
1132         return;
1133     }
1134
1135     /* Handle special cases first */
1136     switch (ri->type & ~(ARM_CP_FLAG_MASK & ~ARM_CP_SPECIAL)) {
1137     case ARM_CP_NOP:
1138         return;
1139     case ARM_CP_NZCV:
1140         tcg_rt = cpu_reg(s, rt);
1141         if (isread) {
1142             gen_get_nzcv(tcg_rt);
1143         } else {
1144             gen_set_nzcv(tcg_rt);
1145         }
1146         return;
1147     default:
1148         break;
1149     }
1150
1151     if (use_icount && (ri->type & ARM_CP_IO)) {
1152         gen_io_start();
1153     }
1154
1155     tcg_rt = cpu_reg(s, rt);
1156
1157     if (isread) {
1158         if (ri->type & ARM_CP_CONST) {
1159             tcg_gen_movi_i64(tcg_rt, ri->resetvalue);
1160         } else if (ri->readfn) {
1161             TCGv_ptr tmpptr;
1162             gen_a64_set_pc_im(s->pc - 4);
1163             tmpptr = tcg_const_ptr(ri);
1164             gen_helper_get_cp_reg64(tcg_rt, cpu_env, tmpptr);
1165             tcg_temp_free_ptr(tmpptr);
1166         } else {
1167             tcg_gen_ld_i64(tcg_rt, cpu_env, ri->fieldoffset);
1168         }
1169     } else {
1170         if (ri->type & ARM_CP_CONST) {
1171             /* If not forbidden by access permissions, treat as WI */
1172             return;
1173         } else if (ri->writefn) {
1174             TCGv_ptr tmpptr;
1175             gen_a64_set_pc_im(s->pc - 4);
1176             tmpptr = tcg_const_ptr(ri);
1177             gen_helper_set_cp_reg64(cpu_env, tmpptr, tcg_rt);
1178             tcg_temp_free_ptr(tmpptr);
1179         } else {
1180             tcg_gen_st_i64(tcg_rt, cpu_env, ri->fieldoffset);
1181         }
1182     }
1183
1184     if (use_icount && (ri->type & ARM_CP_IO)) {
1185         /* I/O operations must end the TB here (whether read or write) */
1186         gen_io_end();
1187         s->is_jmp = DISAS_UPDATE;
1188     } else if (!isread && !(ri->type & ARM_CP_SUPPRESS_TB_END)) {
1189         /* We default to ending the TB on a coprocessor register write,
1190          * but allow this to be suppressed by the register definition
1191          * (usually only necessary to work around guest bugs).
1192          */
1193         s->is_jmp = DISAS_UPDATE;
1194     }
1195 }
1196
1197 /* C3.2.4 System
1198  *  31                 22 21  20 19 18 16 15   12 11    8 7   5 4    0
1199  * +---------------------+---+-----+-----+-------+-------+-----+------+
1200  * | 1 1 0 1 0 1 0 1 0 0 | L | op0 | op1 |  CRn  |  CRm  | op2 |  Rt  |
1201  * +---------------------+---+-----+-----+-------+-------+-----+------+
1202  */
1203 static void disas_system(DisasContext *s, uint32_t insn)
1204 {
1205     unsigned int l, op0, op1, crn, crm, op2, rt;
1206     l = extract32(insn, 21, 1);
1207     op0 = extract32(insn, 19, 2);
1208     op1 = extract32(insn, 16, 3);
1209     crn = extract32(insn, 12, 4);
1210     crm = extract32(insn, 8, 4);
1211     op2 = extract32(insn, 5, 3);
1212     rt = extract32(insn, 0, 5);
1213
1214     if (op0 == 0) {
1215         if (l || rt != 31) {
1216             unallocated_encoding(s);
1217             return;
1218         }
1219         switch (crn) {
1220         case 2: /* C5.6.68 HINT */
1221             handle_hint(s, insn, op1, op2, crm);
1222             break;
1223         case 3: /* CLREX, DSB, DMB, ISB */
1224             handle_sync(s, insn, op1, op2, crm);
1225             break;
1226         case 4: /* C5.6.130 MSR (immediate) */
1227             handle_msr_i(s, insn, op1, op2, crm);
1228             break;
1229         default:
1230             unallocated_encoding(s);
1231             break;
1232         }
1233         return;
1234     }
1235     handle_sys(s, insn, l, op0, op1, op2, crn, crm, rt);
1236 }
1237
1238 /* C3.2.3 Exception generation
1239  *
1240  *  31             24 23 21 20                     5 4   2 1  0
1241  * +-----------------+-----+------------------------+-----+----+
1242  * | 1 1 0 1 0 1 0 0 | opc |          imm16         | op2 | LL |
1243  * +-----------------------+------------------------+----------+
1244  */
1245 static void disas_exc(DisasContext *s, uint32_t insn)
1246 {
1247     int opc = extract32(insn, 21, 3);
1248     int op2_ll = extract32(insn, 0, 5);
1249
1250     switch (opc) {
1251     case 0:
1252         /* SVC, HVC, SMC; since we don't support the Virtualization
1253          * or TrustZone extensions these all UNDEF except SVC.
1254          */
1255         if (op2_ll != 1) {
1256             unallocated_encoding(s);
1257             break;
1258         }
1259         gen_exception_insn(s, 0, EXCP_SWI);
1260         break;
1261     case 1:
1262         if (op2_ll != 0) {
1263             unallocated_encoding(s);
1264             break;
1265         }
1266         /* BRK */
1267         gen_exception_insn(s, 0, EXCP_BKPT);
1268         break;
1269     case 2:
1270         if (op2_ll != 0) {
1271             unallocated_encoding(s);
1272             break;
1273         }
1274         /* HLT */
1275         unsupported_encoding(s, insn);
1276         break;
1277     case 5:
1278         if (op2_ll < 1 || op2_ll > 3) {
1279             unallocated_encoding(s);
1280             break;
1281         }
1282         /* DCPS1, DCPS2, DCPS3 */
1283         unsupported_encoding(s, insn);
1284         break;
1285     default:
1286         unallocated_encoding(s);
1287         break;
1288     }
1289 }
1290
1291 /* C3.2.7 Unconditional branch (register)
1292  *  31           25 24   21 20   16 15   10 9    5 4     0
1293  * +---------------+-------+-------+-------+------+-------+
1294  * | 1 1 0 1 0 1 1 |  opc  |  op2  |  op3  |  Rn  |  op4  |
1295  * +---------------+-------+-------+-------+------+-------+
1296  */
1297 static void disas_uncond_b_reg(DisasContext *s, uint32_t insn)
1298 {
1299     unsigned int opc, op2, op3, rn, op4;
1300
1301     opc = extract32(insn, 21, 4);
1302     op2 = extract32(insn, 16, 5);
1303     op3 = extract32(insn, 10, 6);
1304     rn = extract32(insn, 5, 5);
1305     op4 = extract32(insn, 0, 5);
1306
1307     if (op4 != 0x0 || op3 != 0x0 || op2 != 0x1f) {
1308         unallocated_encoding(s);
1309         return;
1310     }
1311
1312     switch (opc) {
1313     case 0: /* BR */
1314     case 2: /* RET */
1315         break;
1316     case 1: /* BLR */
1317         tcg_gen_movi_i64(cpu_reg(s, 30), s->pc);
1318         break;
1319     case 4: /* ERET */
1320     case 5: /* DRPS */
1321         if (rn != 0x1f) {
1322             unallocated_encoding(s);
1323         } else {
1324             unsupported_encoding(s, insn);
1325         }
1326         return;
1327     default:
1328         unallocated_encoding(s);
1329         return;
1330     }
1331
1332     tcg_gen_mov_i64(cpu_pc, cpu_reg(s, rn));
1333     s->is_jmp = DISAS_JUMP;
1334 }
1335
1336 /* C3.2 Branches, exception generating and system instructions */
1337 static void disas_b_exc_sys(DisasContext *s, uint32_t insn)
1338 {
1339     switch (extract32(insn, 25, 7)) {
1340     case 0x0a: case 0x0b:
1341     case 0x4a: case 0x4b: /* Unconditional branch (immediate) */
1342         disas_uncond_b_imm(s, insn);
1343         break;
1344     case 0x1a: case 0x5a: /* Compare & branch (immediate) */
1345         disas_comp_b_imm(s, insn);
1346         break;
1347     case 0x1b: case 0x5b: /* Test & branch (immediate) */
1348         disas_test_b_imm(s, insn);
1349         break;
1350     case 0x2a: /* Conditional branch (immediate) */
1351         disas_cond_b_imm(s, insn);
1352         break;
1353     case 0x6a: /* Exception generation / System */
1354         if (insn & (1 << 24)) {
1355             disas_system(s, insn);
1356         } else {
1357             disas_exc(s, insn);
1358         }
1359         break;
1360     case 0x6b: /* Unconditional branch (register) */
1361         disas_uncond_b_reg(s, insn);
1362         break;
1363     default:
1364         unallocated_encoding(s);
1365         break;
1366     }
1367 }
1368
1369 /*
1370  * Load/Store exclusive instructions are implemented by remembering
1371  * the value/address loaded, and seeing if these are the same
1372  * when the store is performed. This is not actually the architecturally
1373  * mandated semantics, but it works for typical guest code sequences
1374  * and avoids having to monitor regular stores.
1375  *
1376  * In system emulation mode only one CPU will be running at once, so
1377  * this sequence is effectively atomic.  In user emulation mode we
1378  * throw an exception and handle the atomic operation elsewhere.
1379  */
1380 static void gen_load_exclusive(DisasContext *s, int rt, int rt2,
1381                                TCGv_i64 addr, int size, bool is_pair)
1382 {
1383     TCGv_i64 tmp = tcg_temp_new_i64();
1384     TCGMemOp memop = MO_TE + size;
1385
1386     g_assert(size <= 3);
1387     tcg_gen_qemu_ld_i64(tmp, addr, get_mem_index(s), memop);
1388
1389     if (is_pair) {
1390         TCGv_i64 addr2 = tcg_temp_new_i64();
1391         TCGv_i64 hitmp = tcg_temp_new_i64();
1392
1393         g_assert(size >= 2);
1394         tcg_gen_addi_i64(addr2, addr, 1 << size);
1395         tcg_gen_qemu_ld_i64(hitmp, addr2, get_mem_index(s), memop);
1396         tcg_temp_free_i64(addr2);
1397         tcg_gen_mov_i64(cpu_exclusive_high, hitmp);
1398         tcg_gen_mov_i64(cpu_reg(s, rt2), hitmp);
1399         tcg_temp_free_i64(hitmp);
1400     }
1401
1402     tcg_gen_mov_i64(cpu_exclusive_val, tmp);
1403     tcg_gen_mov_i64(cpu_reg(s, rt), tmp);
1404
1405     tcg_temp_free_i64(tmp);
1406     tcg_gen_mov_i64(cpu_exclusive_addr, addr);
1407 }
1408
1409 #ifdef CONFIG_USER_ONLY
1410 static void gen_store_exclusive(DisasContext *s, int rd, int rt, int rt2,
1411                                 TCGv_i64 addr, int size, int is_pair)
1412 {
1413     tcg_gen_mov_i64(cpu_exclusive_test, addr);
1414     tcg_gen_movi_i32(cpu_exclusive_info,
1415                      size | is_pair << 2 | (rd << 4) | (rt << 9) | (rt2 << 14));
1416     gen_exception_insn(s, 4, EXCP_STREX);
1417 }
1418 #else
1419 static void gen_store_exclusive(DisasContext *s, int rd, int rt, int rt2,
1420                                 TCGv_i64 addr, int size, int is_pair)
1421 {
1422     qemu_log_mask(LOG_UNIMP,
1423                   "%s:%d: system mode store_exclusive unsupported "
1424                   "at pc=%016" PRIx64 "\n",
1425                   __FILE__, __LINE__, s->pc - 4);
1426 }
1427 #endif
1428
1429 /* C3.3.6 Load/store exclusive
1430  *
1431  *  31 30 29         24  23  22   21  20  16  15  14   10 9    5 4    0
1432  * +-----+-------------+----+---+----+------+----+-------+------+------+
1433  * | sz  | 0 0 1 0 0 0 | o2 | L | o1 |  Rs  | o0 |  Rt2  |  Rn  | Rt   |
1434  * +-----+-------------+----+---+----+------+----+-------+------+------+
1435  *
1436  *  sz: 00 -> 8 bit, 01 -> 16 bit, 10 -> 32 bit, 11 -> 64 bit
1437  *   L: 0 -> store, 1 -> load
1438  *  o2: 0 -> exclusive, 1 -> not
1439  *  o1: 0 -> single register, 1 -> register pair
1440  *  o0: 1 -> load-acquire/store-release, 0 -> not
1441  *
1442  *  o0 == 0 AND o2 == 1 is un-allocated
1443  *  o1 == 1 is un-allocated except for 32 and 64 bit sizes
1444  */
1445 static void disas_ldst_excl(DisasContext *s, uint32_t insn)
1446 {
1447     int rt = extract32(insn, 0, 5);
1448     int rn = extract32(insn, 5, 5);
1449     int rt2 = extract32(insn, 10, 5);
1450     int is_lasr = extract32(insn, 15, 1);
1451     int rs = extract32(insn, 16, 5);
1452     int is_pair = extract32(insn, 21, 1);
1453     int is_store = !extract32(insn, 22, 1);
1454     int is_excl = !extract32(insn, 23, 1);
1455     int size = extract32(insn, 30, 2);
1456     TCGv_i64 tcg_addr;
1457
1458     if ((!is_excl && !is_lasr) ||
1459         (is_pair && size < 2)) {
1460         unallocated_encoding(s);
1461         return;
1462     }
1463
1464     if (rn == 31) {
1465         gen_check_sp_alignment(s);
1466     }
1467     tcg_addr = read_cpu_reg_sp(s, rn, 1);
1468
1469     /* Note that since TCG is single threaded load-acquire/store-release
1470      * semantics require no extra if (is_lasr) { ... } handling.
1471      */
1472
1473     if (is_excl) {
1474         if (!is_store) {
1475             gen_load_exclusive(s, rt, rt2, tcg_addr, size, is_pair);
1476         } else {
1477             gen_store_exclusive(s, rs, rt, rt2, tcg_addr, size, is_pair);
1478         }
1479     } else {
1480         TCGv_i64 tcg_rt = cpu_reg(s, rt);
1481         if (is_store) {
1482             do_gpr_st(s, tcg_rt, tcg_addr, size);
1483         } else {
1484             do_gpr_ld(s, tcg_rt, tcg_addr, size, false, false);
1485         }
1486         if (is_pair) {
1487             TCGv_i64 tcg_rt2 = cpu_reg(s, rt);
1488             tcg_gen_addi_i64(tcg_addr, tcg_addr, 1 << size);
1489             if (is_store) {
1490                 do_gpr_st(s, tcg_rt2, tcg_addr, size);
1491             } else {
1492                 do_gpr_ld(s, tcg_rt2, tcg_addr, size, false, false);
1493             }
1494         }
1495     }
1496 }
1497
1498 /*
1499  * C3.3.5 Load register (literal)
1500  *
1501  *  31 30 29   27  26 25 24 23                5 4     0
1502  * +-----+-------+---+-----+-------------------+-------+
1503  * | opc | 0 1 1 | V | 0 0 |     imm19         |  Rt   |
1504  * +-----+-------+---+-----+-------------------+-------+
1505  *
1506  * V: 1 -> vector (simd/fp)
1507  * opc (non-vector): 00 -> 32 bit, 01 -> 64 bit,
1508  *                   10-> 32 bit signed, 11 -> prefetch
1509  * opc (vector): 00 -> 32 bit, 01 -> 64 bit, 10 -> 128 bit (11 unallocated)
1510  */
1511 static void disas_ld_lit(DisasContext *s, uint32_t insn)
1512 {
1513     int rt = extract32(insn, 0, 5);
1514     int64_t imm = sextract32(insn, 5, 19) << 2;
1515     bool is_vector = extract32(insn, 26, 1);
1516     int opc = extract32(insn, 30, 2);
1517     bool is_signed = false;
1518     int size = 2;
1519     TCGv_i64 tcg_rt, tcg_addr;
1520
1521     if (is_vector) {
1522         if (opc == 3) {
1523             unallocated_encoding(s);
1524             return;
1525         }
1526         size = 2 + opc;
1527     } else {
1528         if (opc == 3) {
1529             /* PRFM (literal) : prefetch */
1530             return;
1531         }
1532         size = 2 + extract32(opc, 0, 1);
1533         is_signed = extract32(opc, 1, 1);
1534     }
1535
1536     tcg_rt = cpu_reg(s, rt);
1537
1538     tcg_addr = tcg_const_i64((s->pc - 4) + imm);
1539     if (is_vector) {
1540         do_fp_ld(s, rt, tcg_addr, size);
1541     } else {
1542         do_gpr_ld(s, tcg_rt, tcg_addr, size, is_signed, false);
1543     }
1544     tcg_temp_free_i64(tcg_addr);
1545 }
1546
1547 /*
1548  * C5.6.80 LDNP (Load Pair - non-temporal hint)
1549  * C5.6.81 LDP (Load Pair - non vector)
1550  * C5.6.82 LDPSW (Load Pair Signed Word - non vector)
1551  * C5.6.176 STNP (Store Pair - non-temporal hint)
1552  * C5.6.177 STP (Store Pair - non vector)
1553  * C6.3.165 LDNP (Load Pair of SIMD&FP - non-temporal hint)
1554  * C6.3.165 LDP (Load Pair of SIMD&FP)
1555  * C6.3.284 STNP (Store Pair of SIMD&FP - non-temporal hint)
1556  * C6.3.284 STP (Store Pair of SIMD&FP)
1557  *
1558  *  31 30 29   27  26  25 24   23  22 21   15 14   10 9    5 4    0
1559  * +-----+-------+---+---+-------+---+-----------------------------+
1560  * | opc | 1 0 1 | V | 0 | index | L |  imm7 |  Rt2  |  Rn  | Rt   |
1561  * +-----+-------+---+---+-------+---+-------+-------+------+------+
1562  *
1563  * opc: LDP/STP/LDNP/STNP        00 -> 32 bit, 10 -> 64 bit
1564  *      LDPSW                    01
1565  *      LDP/STP/LDNP/STNP (SIMD) 00 -> 32 bit, 01 -> 64 bit, 10 -> 128 bit
1566  *   V: 0 -> GPR, 1 -> Vector
1567  * idx: 00 -> signed offset with non-temporal hint, 01 -> post-index,
1568  *      10 -> signed offset, 11 -> pre-index
1569  *   L: 0 -> Store 1 -> Load
1570  *
1571  * Rt, Rt2 = GPR or SIMD registers to be stored
1572  * Rn = general purpose register containing address
1573  * imm7 = signed offset (multiple of 4 or 8 depending on size)
1574  */
1575 static void disas_ldst_pair(DisasContext *s, uint32_t insn)
1576 {
1577     int rt = extract32(insn, 0, 5);
1578     int rn = extract32(insn, 5, 5);
1579     int rt2 = extract32(insn, 10, 5);
1580     int64_t offset = sextract32(insn, 15, 7);
1581     int index = extract32(insn, 23, 2);
1582     bool is_vector = extract32(insn, 26, 1);
1583     bool is_load = extract32(insn, 22, 1);
1584     int opc = extract32(insn, 30, 2);
1585
1586     bool is_signed = false;
1587     bool postindex = false;
1588     bool wback = false;
1589
1590     TCGv_i64 tcg_addr; /* calculated address */
1591     int size;
1592
1593     if (opc == 3) {
1594         unallocated_encoding(s);
1595         return;
1596     }
1597
1598     if (is_vector) {
1599         size = 2 + opc;
1600     } else {
1601         size = 2 + extract32(opc, 1, 1);
1602         is_signed = extract32(opc, 0, 1);
1603         if (!is_load && is_signed) {
1604             unallocated_encoding(s);
1605             return;
1606         }
1607     }
1608
1609     switch (index) {
1610     case 1: /* post-index */
1611         postindex = true;
1612         wback = true;
1613         break;
1614     case 0:
1615         /* signed offset with "non-temporal" hint. Since we don't emulate
1616          * caches we don't care about hints to the cache system about
1617          * data access patterns, and handle this identically to plain
1618          * signed offset.
1619          */
1620         if (is_signed) {
1621             /* There is no non-temporal-hint version of LDPSW */
1622             unallocated_encoding(s);
1623             return;
1624         }
1625         postindex = false;
1626         break;
1627     case 2: /* signed offset, rn not updated */
1628         postindex = false;
1629         break;
1630     case 3: /* pre-index */
1631         postindex = false;
1632         wback = true;
1633         break;
1634     }
1635
1636     offset <<= size;
1637
1638     if (rn == 31) {
1639         gen_check_sp_alignment(s);
1640     }
1641
1642     tcg_addr = read_cpu_reg_sp(s, rn, 1);
1643
1644     if (!postindex) {
1645         tcg_gen_addi_i64(tcg_addr, tcg_addr, offset);
1646     }
1647
1648     if (is_vector) {
1649         if (is_load) {
1650             do_fp_ld(s, rt, tcg_addr, size);
1651         } else {
1652             do_fp_st(s, rt, tcg_addr, size);
1653         }
1654     } else {
1655         TCGv_i64 tcg_rt = cpu_reg(s, rt);
1656         if (is_load) {
1657             do_gpr_ld(s, tcg_rt, tcg_addr, size, is_signed, false);
1658         } else {
1659             do_gpr_st(s, tcg_rt, tcg_addr, size);
1660         }
1661     }
1662     tcg_gen_addi_i64(tcg_addr, tcg_addr, 1 << size);
1663     if (is_vector) {
1664         if (is_load) {
1665             do_fp_ld(s, rt2, tcg_addr, size);
1666         } else {
1667             do_fp_st(s, rt2, tcg_addr, size);
1668         }
1669     } else {
1670         TCGv_i64 tcg_rt2 = cpu_reg(s, rt2);
1671         if (is_load) {
1672             do_gpr_ld(s, tcg_rt2, tcg_addr, size, is_signed, false);
1673         } else {
1674             do_gpr_st(s, tcg_rt2, tcg_addr, size);
1675         }
1676     }
1677
1678     if (wback) {
1679         if (postindex) {
1680             tcg_gen_addi_i64(tcg_addr, tcg_addr, offset - (1 << size));
1681         } else {
1682             tcg_gen_subi_i64(tcg_addr, tcg_addr, 1 << size);
1683         }
1684         tcg_gen_mov_i64(cpu_reg_sp(s, rn), tcg_addr);
1685     }
1686 }
1687
1688 /*
1689  * C3.3.8 Load/store (immediate post-indexed)
1690  * C3.3.9 Load/store (immediate pre-indexed)
1691  * C3.3.12 Load/store (unscaled immediate)
1692  *
1693  * 31 30 29   27  26 25 24 23 22 21  20    12 11 10 9    5 4    0
1694  * +----+-------+---+-----+-----+---+--------+-----+------+------+
1695  * |size| 1 1 1 | V | 0 0 | opc | 0 |  imm9  | idx |  Rn  |  Rt  |
1696  * +----+-------+---+-----+-----+---+--------+-----+------+------+
1697  *
1698  * idx = 01 -> post-indexed, 11 pre-indexed, 00 unscaled imm. (no writeback)
1699  * V = 0 -> non-vector
1700  * size: 00 -> 8 bit, 01 -> 16 bit, 10 -> 32 bit, 11 -> 64bit
1701  * opc: 00 -> store, 01 -> loadu, 10 -> loads 64, 11 -> loads 32
1702  */
1703 static void disas_ldst_reg_imm9(DisasContext *s, uint32_t insn)
1704 {
1705     int rt = extract32(insn, 0, 5);
1706     int rn = extract32(insn, 5, 5);
1707     int imm9 = sextract32(insn, 12, 9);
1708     int opc = extract32(insn, 22, 2);
1709     int size = extract32(insn, 30, 2);
1710     int idx = extract32(insn, 10, 2);
1711     bool is_signed = false;
1712     bool is_store = false;
1713     bool is_extended = false;
1714     bool is_vector = extract32(insn, 26, 1);
1715     bool post_index;
1716     bool writeback;
1717
1718     TCGv_i64 tcg_addr;
1719
1720     if (is_vector) {
1721         size |= (opc & 2) << 1;
1722         if (size > 4) {
1723             unallocated_encoding(s);
1724             return;
1725         }
1726         is_store = ((opc & 1) == 0);
1727     } else {
1728         if (size == 3 && opc == 2) {
1729             /* PRFM - prefetch */
1730             return;
1731         }
1732         if (opc == 3 && size > 1) {
1733             unallocated_encoding(s);
1734             return;
1735         }
1736         is_store = (opc == 0);
1737         is_signed = opc & (1<<1);
1738         is_extended = (size < 3) && (opc & 1);
1739     }
1740
1741     switch (idx) {
1742     case 0:
1743         post_index = false;
1744         writeback = false;
1745         break;
1746     case 1:
1747         post_index = true;
1748         writeback = true;
1749         break;
1750     case 3:
1751         post_index = false;
1752         writeback = true;
1753         break;
1754     case 2:
1755         g_assert(false);
1756         break;
1757     }
1758
1759     if (rn == 31) {
1760         gen_check_sp_alignment(s);
1761     }
1762     tcg_addr = read_cpu_reg_sp(s, rn, 1);
1763
1764     if (!post_index) {
1765         tcg_gen_addi_i64(tcg_addr, tcg_addr, imm9);
1766     }
1767
1768     if (is_vector) {
1769         if (is_store) {
1770             do_fp_st(s, rt, tcg_addr, size);
1771         } else {
1772             do_fp_ld(s, rt, tcg_addr, size);
1773         }
1774     } else {
1775         TCGv_i64 tcg_rt = cpu_reg(s, rt);
1776         if (is_store) {
1777             do_gpr_st(s, tcg_rt, tcg_addr, size);
1778         } else {
1779             do_gpr_ld(s, tcg_rt, tcg_addr, size, is_signed, is_extended);
1780         }
1781     }
1782
1783     if (writeback) {
1784         TCGv_i64 tcg_rn = cpu_reg_sp(s, rn);
1785         if (post_index) {
1786             tcg_gen_addi_i64(tcg_addr, tcg_addr, imm9);
1787         }
1788         tcg_gen_mov_i64(tcg_rn, tcg_addr);
1789     }
1790 }
1791
1792 /*
1793  * C3.3.10 Load/store (register offset)
1794  *
1795  * 31 30 29   27  26 25 24 23 22 21  20  16 15 13 12 11 10 9  5 4  0
1796  * +----+-------+---+-----+-----+---+------+-----+--+-----+----+----+
1797  * |size| 1 1 1 | V | 0 0 | opc | 1 |  Rm  | opt | S| 1 0 | Rn | Rt |
1798  * +----+-------+---+-----+-----+---+------+-----+--+-----+----+----+
1799  *
1800  * For non-vector:
1801  *   size: 00-> byte, 01 -> 16 bit, 10 -> 32bit, 11 -> 64bit
1802  *   opc: 00 -> store, 01 -> loadu, 10 -> loads 64, 11 -> loads 32
1803  * For vector:
1804  *   size is opc<1>:size<1:0> so 100 -> 128 bit; 110 and 111 unallocated
1805  *   opc<0>: 0 -> store, 1 -> load
1806  * V: 1 -> vector/simd
1807  * opt: extend encoding (see DecodeRegExtend)
1808  * S: if S=1 then scale (essentially index by sizeof(size))
1809  * Rt: register to transfer into/out of
1810  * Rn: address register or SP for base
1811  * Rm: offset register or ZR for offset
1812  */
1813 static void disas_ldst_reg_roffset(DisasContext *s, uint32_t insn)
1814 {
1815     int rt = extract32(insn, 0, 5);
1816     int rn = extract32(insn, 5, 5);
1817     int shift = extract32(insn, 12, 1);
1818     int rm = extract32(insn, 16, 5);
1819     int opc = extract32(insn, 22, 2);
1820     int opt = extract32(insn, 13, 3);
1821     int size = extract32(insn, 30, 2);
1822     bool is_signed = false;
1823     bool is_store = false;
1824     bool is_extended = false;
1825     bool is_vector = extract32(insn, 26, 1);
1826
1827     TCGv_i64 tcg_rm;
1828     TCGv_i64 tcg_addr;
1829
1830     if (extract32(opt, 1, 1) == 0) {
1831         unallocated_encoding(s);
1832         return;
1833     }
1834
1835     if (is_vector) {
1836         size |= (opc & 2) << 1;
1837         if (size > 4) {
1838             unallocated_encoding(s);
1839             return;
1840         }
1841         is_store = !extract32(opc, 0, 1);
1842     } else {
1843         if (size == 3 && opc == 2) {
1844             /* PRFM - prefetch */
1845             return;
1846         }
1847         if (opc == 3 && size > 1) {
1848             unallocated_encoding(s);
1849             return;
1850         }
1851         is_store = (opc == 0);
1852         is_signed = extract32(opc, 1, 1);
1853         is_extended = (size < 3) && extract32(opc, 0, 1);
1854     }
1855
1856     if (rn == 31) {
1857         gen_check_sp_alignment(s);
1858     }
1859     tcg_addr = read_cpu_reg_sp(s, rn, 1);
1860
1861     tcg_rm = read_cpu_reg(s, rm, 1);
1862     ext_and_shift_reg(tcg_rm, tcg_rm, opt, shift ? size : 0);
1863
1864     tcg_gen_add_i64(tcg_addr, tcg_addr, tcg_rm);
1865
1866     if (is_vector) {
1867         if (is_store) {
1868             do_fp_st(s, rt, tcg_addr, size);
1869         } else {
1870             do_fp_ld(s, rt, tcg_addr, size);
1871         }
1872     } else {
1873         TCGv_i64 tcg_rt = cpu_reg(s, rt);
1874         if (is_store) {
1875             do_gpr_st(s, tcg_rt, tcg_addr, size);
1876         } else {
1877             do_gpr_ld(s, tcg_rt, tcg_addr, size, is_signed, is_extended);
1878         }
1879     }
1880 }
1881
1882 /*
1883  * C3.3.13 Load/store (unsigned immediate)
1884  *
1885  * 31 30 29   27  26 25 24 23 22 21        10 9     5
1886  * +----+-------+---+-----+-----+------------+-------+------+
1887  * |size| 1 1 1 | V | 0 1 | opc |   imm12    |  Rn   |  Rt  |
1888  * +----+-------+---+-----+-----+------------+-------+------+
1889  *
1890  * For non-vector:
1891  *   size: 00-> byte, 01 -> 16 bit, 10 -> 32bit, 11 -> 64bit
1892  *   opc: 00 -> store, 01 -> loadu, 10 -> loads 64, 11 -> loads 32
1893  * For vector:
1894  *   size is opc<1>:size<1:0> so 100 -> 128 bit; 110 and 111 unallocated
1895  *   opc<0>: 0 -> store, 1 -> load
1896  * Rn: base address register (inc SP)
1897  * Rt: target register
1898  */
1899 static void disas_ldst_reg_unsigned_imm(DisasContext *s, uint32_t insn)
1900 {
1901     int rt = extract32(insn, 0, 5);
1902     int rn = extract32(insn, 5, 5);
1903     unsigned int imm12 = extract32(insn, 10, 12);
1904     bool is_vector = extract32(insn, 26, 1);
1905     int size = extract32(insn, 30, 2);
1906     int opc = extract32(insn, 22, 2);
1907     unsigned int offset;
1908
1909     TCGv_i64 tcg_addr;
1910
1911     bool is_store;
1912     bool is_signed = false;
1913     bool is_extended = false;
1914
1915     if (is_vector) {
1916         size |= (opc & 2) << 1;
1917         if (size > 4) {
1918             unallocated_encoding(s);
1919             return;
1920         }
1921         is_store = !extract32(opc, 0, 1);
1922     } else {
1923         if (size == 3 && opc == 2) {
1924             /* PRFM - prefetch */
1925             return;
1926         }
1927         if (opc == 3 && size > 1) {
1928             unallocated_encoding(s);
1929             return;
1930         }
1931         is_store = (opc == 0);
1932         is_signed = extract32(opc, 1, 1);
1933         is_extended = (size < 3) && extract32(opc, 0, 1);
1934     }
1935
1936     if (rn == 31) {
1937         gen_check_sp_alignment(s);
1938     }
1939     tcg_addr = read_cpu_reg_sp(s, rn, 1);
1940     offset = imm12 << size;
1941     tcg_gen_addi_i64(tcg_addr, tcg_addr, offset);
1942
1943     if (is_vector) {
1944         if (is_store) {
1945             do_fp_st(s, rt, tcg_addr, size);
1946         } else {
1947             do_fp_ld(s, rt, tcg_addr, size);
1948         }
1949     } else {
1950         TCGv_i64 tcg_rt = cpu_reg(s, rt);
1951         if (is_store) {
1952             do_gpr_st(s, tcg_rt, tcg_addr, size);
1953         } else {
1954             do_gpr_ld(s, tcg_rt, tcg_addr, size, is_signed, is_extended);
1955         }
1956     }
1957 }
1958
1959 /* Load/store register (immediate forms) */
1960 static void disas_ldst_reg_imm(DisasContext *s, uint32_t insn)
1961 {
1962     switch (extract32(insn, 10, 2)) {
1963     case 0: case 1: case 3:
1964         /* Load/store register (unscaled immediate) */
1965         /* Load/store immediate pre/post-indexed */
1966         disas_ldst_reg_imm9(s, insn);
1967         break;
1968     case 2:
1969         /* Load/store register unprivileged */
1970         unsupported_encoding(s, insn);
1971         break;
1972     default:
1973         unallocated_encoding(s);
1974         break;
1975     }
1976 }
1977
1978 /* Load/store register (all forms) */
1979 static void disas_ldst_reg(DisasContext *s, uint32_t insn)
1980 {
1981     switch (extract32(insn, 24, 2)) {
1982     case 0:
1983         if (extract32(insn, 21, 1) == 1 && extract32(insn, 10, 2) == 2) {
1984             disas_ldst_reg_roffset(s, insn);
1985         } else {
1986             disas_ldst_reg_imm(s, insn);
1987         }
1988         break;
1989     case 1:
1990         disas_ldst_reg_unsigned_imm(s, insn);
1991         break;
1992     default:
1993         unallocated_encoding(s);
1994         break;
1995     }
1996 }
1997
1998 /* C3.3.1 AdvSIMD load/store multiple structures
1999  *
2000  *  31  30  29           23 22  21         16 15    12 11  10 9    5 4    0
2001  * +---+---+---------------+---+-------------+--------+------+------+------+
2002  * | 0 | Q | 0 0 1 1 0 0 0 | L | 0 0 0 0 0 0 | opcode | size |  Rn  |  Rt  |
2003  * +---+---+---------------+---+-------------+--------+------+------+------+
2004  *
2005  * C3.3.2 AdvSIMD load/store multiple structures (post-indexed)
2006  *
2007  *  31  30  29           23 22  21  20     16 15    12 11  10 9    5 4    0
2008  * +---+---+---------------+---+---+---------+--------+------+------+------+
2009  * | 0 | Q | 0 0 1 1 0 0 1 | L | 0 |   Rm    | opcode | size |  Rn  |  Rt  |
2010  * +---+---+---------------+---+---+---------+--------+------+------+------+
2011  *
2012  * Rt: first (or only) SIMD&FP register to be transferred
2013  * Rn: base address or SP
2014  * Rm (post-index only): post-index register (when !31) or size dependent #imm
2015  */
2016 static void disas_ldst_multiple_struct(DisasContext *s, uint32_t insn)
2017 {
2018     int rt = extract32(insn, 0, 5);
2019     int rn = extract32(insn, 5, 5);
2020     int size = extract32(insn, 10, 2);
2021     int opcode = extract32(insn, 12, 4);
2022     bool is_store = !extract32(insn, 22, 1);
2023     bool is_postidx = extract32(insn, 23, 1);
2024     bool is_q = extract32(insn, 30, 1);
2025     TCGv_i64 tcg_addr, tcg_rn;
2026
2027     int ebytes = 1 << size;
2028     int elements = (is_q ? 128 : 64) / (8 << size);
2029     int rpt;    /* num iterations */
2030     int selem;  /* structure elements */
2031     int r;
2032
2033     if (extract32(insn, 31, 1) || extract32(insn, 21, 1)) {
2034         unallocated_encoding(s);
2035         return;
2036     }
2037
2038     /* From the shared decode logic */
2039     switch (opcode) {
2040     case 0x0:
2041         rpt = 1;
2042         selem = 4;
2043         break;
2044     case 0x2:
2045         rpt = 4;
2046         selem = 1;
2047         break;
2048     case 0x4:
2049         rpt = 1;
2050         selem = 3;
2051         break;
2052     case 0x6:
2053         rpt = 3;
2054         selem = 1;
2055         break;
2056     case 0x7:
2057         rpt = 1;
2058         selem = 1;
2059         break;
2060     case 0x8:
2061         rpt = 1;
2062         selem = 2;
2063         break;
2064     case 0xa:
2065         rpt = 2;
2066         selem = 1;
2067         break;
2068     default:
2069         unallocated_encoding(s);
2070         return;
2071     }
2072
2073     if (size == 3 && !is_q && selem != 1) {
2074         /* reserved */
2075         unallocated_encoding(s);
2076         return;
2077     }
2078
2079     if (rn == 31) {
2080         gen_check_sp_alignment(s);
2081     }
2082
2083     tcg_rn = cpu_reg_sp(s, rn);
2084     tcg_addr = tcg_temp_new_i64();
2085     tcg_gen_mov_i64(tcg_addr, tcg_rn);
2086
2087     for (r = 0; r < rpt; r++) {
2088         int e;
2089         for (e = 0; e < elements; e++) {
2090             int tt = (rt + r) % 32;
2091             int xs;
2092             for (xs = 0; xs < selem; xs++) {
2093                 if (is_store) {
2094                     do_vec_st(s, tt, e, tcg_addr, size);
2095                 } else {
2096                     do_vec_ld(s, tt, e, tcg_addr, size);
2097
2098                     /* For non-quad operations, setting a slice of the low
2099                      * 64 bits of the register clears the high 64 bits (in
2100                      * the ARM ARM pseudocode this is implicit in the fact
2101                      * that 'rval' is a 64 bit wide variable). We optimize
2102                      * by noticing that we only need to do this the first
2103                      * time we touch a register.
2104                      */
2105                     if (!is_q && e == 0 && (r == 0 || xs == selem - 1)) {
2106                         clear_vec_high(s, tt);
2107                     }
2108                 }
2109                 tcg_gen_addi_i64(tcg_addr, tcg_addr, ebytes);
2110                 tt = (tt + 1) % 32;
2111             }
2112         }
2113     }
2114
2115     if (is_postidx) {
2116         int rm = extract32(insn, 16, 5);
2117         if (rm == 31) {
2118             tcg_gen_mov_i64(tcg_rn, tcg_addr);
2119         } else {
2120             tcg_gen_add_i64(tcg_rn, tcg_rn, cpu_reg(s, rm));
2121         }
2122     }
2123     tcg_temp_free_i64(tcg_addr);
2124 }
2125
2126 /* C3.3.3 AdvSIMD load/store single structure
2127  *
2128  *  31  30  29           23 22 21 20       16 15 13 12  11  10 9    5 4    0
2129  * +---+---+---------------+-----+-----------+-----+---+------+------+------+
2130  * | 0 | Q | 0 0 1 1 0 1 0 | L R | 0 0 0 0 0 | opc | S | size |  Rn  |  Rt  |
2131  * +---+---+---------------+-----+-----------+-----+---+------+------+------+
2132  *
2133  * C3.3.4 AdvSIMD load/store single structure (post-indexed)
2134  *
2135  *  31  30  29           23 22 21 20       16 15 13 12  11  10 9    5 4    0
2136  * +---+---+---------------+-----+-----------+-----+---+------+------+------+
2137  * | 0 | Q | 0 0 1 1 0 1 1 | L R |     Rm    | opc | S | size |  Rn  |  Rt  |
2138  * +---+---+---------------+-----+-----------+-----+---+------+------+------+
2139  *
2140  * Rt: first (or only) SIMD&FP register to be transferred
2141  * Rn: base address or SP
2142  * Rm (post-index only): post-index register (when !31) or size dependent #imm
2143  * index = encoded in Q:S:size dependent on size
2144  *
2145  * lane_size = encoded in R, opc
2146  * transfer width = encoded in opc, S, size
2147  */
2148 static void disas_ldst_single_struct(DisasContext *s, uint32_t insn)
2149 {
2150     int rt = extract32(insn, 0, 5);
2151     int rn = extract32(insn, 5, 5);
2152     int size = extract32(insn, 10, 2);
2153     int S = extract32(insn, 12, 1);
2154     int opc = extract32(insn, 13, 3);
2155     int R = extract32(insn, 21, 1);
2156     int is_load = extract32(insn, 22, 1);
2157     int is_postidx = extract32(insn, 23, 1);
2158     int is_q = extract32(insn, 30, 1);
2159
2160     int scale = extract32(opc, 1, 2);
2161     int selem = (extract32(opc, 0, 1) << 1 | R) + 1;
2162     bool replicate = false;
2163     int index = is_q << 3 | S << 2 | size;
2164     int ebytes, xs;
2165     TCGv_i64 tcg_addr, tcg_rn;
2166
2167     switch (scale) {
2168     case 3:
2169         if (!is_load || S) {
2170             unallocated_encoding(s);
2171             return;
2172         }
2173         scale = size;
2174         replicate = true;
2175         break;
2176     case 0:
2177         break;
2178     case 1:
2179         if (extract32(size, 0, 1)) {
2180             unallocated_encoding(s);
2181             return;
2182         }
2183         index >>= 1;
2184         break;
2185     case 2:
2186         if (extract32(size, 1, 1)) {
2187             unallocated_encoding(s);
2188             return;
2189         }
2190         if (!extract32(size, 0, 1)) {
2191             index >>= 2;
2192         } else {
2193             if (S) {
2194                 unallocated_encoding(s);
2195                 return;
2196             }
2197             index >>= 3;
2198             scale = 3;
2199         }
2200         break;
2201     default:
2202         g_assert_not_reached();
2203     }
2204
2205     ebytes = 1 << scale;
2206
2207     if (rn == 31) {
2208         gen_check_sp_alignment(s);
2209     }
2210
2211     tcg_rn = cpu_reg_sp(s, rn);
2212     tcg_addr = tcg_temp_new_i64();
2213     tcg_gen_mov_i64(tcg_addr, tcg_rn);
2214
2215     for (xs = 0; xs < selem; xs++) {
2216         if (replicate) {
2217             /* Load and replicate to all elements */
2218             uint64_t mulconst;
2219             TCGv_i64 tcg_tmp = tcg_temp_new_i64();
2220
2221             tcg_gen_qemu_ld_i64(tcg_tmp, tcg_addr,
2222                                 get_mem_index(s), MO_TE + scale);
2223             switch (scale) {
2224             case 0:
2225                 mulconst = 0x0101010101010101ULL;
2226                 break;
2227             case 1:
2228                 mulconst = 0x0001000100010001ULL;
2229                 break;
2230             case 2:
2231                 mulconst = 0x0000000100000001ULL;
2232                 break;
2233             case 3:
2234                 mulconst = 0;
2235                 break;
2236             default:
2237                 g_assert_not_reached();
2238             }
2239             if (mulconst) {
2240                 tcg_gen_muli_i64(tcg_tmp, tcg_tmp, mulconst);
2241             }
2242             write_vec_element(s, tcg_tmp, rt, 0, MO_64);
2243             if (is_q) {
2244                 write_vec_element(s, tcg_tmp, rt, 1, MO_64);
2245             } else {
2246                 clear_vec_high(s, rt);
2247             }
2248             tcg_temp_free_i64(tcg_tmp);
2249         } else {
2250             /* Load/store one element per register */
2251             if (is_load) {
2252                 do_vec_ld(s, rt, index, tcg_addr, MO_TE + scale);
2253             } else {
2254                 do_vec_st(s, rt, index, tcg_addr, MO_TE + scale);
2255             }
2256         }
2257         tcg_gen_addi_i64(tcg_addr, tcg_addr, ebytes);
2258         rt = (rt + 1) % 32;
2259     }
2260
2261     if (is_postidx) {
2262         int rm = extract32(insn, 16, 5);
2263         if (rm == 31) {
2264             tcg_gen_mov_i64(tcg_rn, tcg_addr);
2265         } else {
2266             tcg_gen_add_i64(tcg_rn, tcg_rn, cpu_reg(s, rm));
2267         }
2268     }
2269     tcg_temp_free_i64(tcg_addr);
2270 }
2271
2272 /* C3.3 Loads and stores */
2273 static void disas_ldst(DisasContext *s, uint32_t insn)
2274 {
2275     switch (extract32(insn, 24, 6)) {
2276     case 0x08: /* Load/store exclusive */
2277         disas_ldst_excl(s, insn);
2278         break;
2279     case 0x18: case 0x1c: /* Load register (literal) */
2280         disas_ld_lit(s, insn);
2281         break;
2282     case 0x28: case 0x29:
2283     case 0x2c: case 0x2d: /* Load/store pair (all forms) */
2284         disas_ldst_pair(s, insn);
2285         break;
2286     case 0x38: case 0x39:
2287     case 0x3c: case 0x3d: /* Load/store register (all forms) */
2288         disas_ldst_reg(s, insn);
2289         break;
2290     case 0x0c: /* AdvSIMD load/store multiple structures */
2291         disas_ldst_multiple_struct(s, insn);
2292         break;
2293     case 0x0d: /* AdvSIMD load/store single structure */
2294         disas_ldst_single_struct(s, insn);
2295         break;
2296     default:
2297         unallocated_encoding(s);
2298         break;
2299     }
2300 }
2301
2302 /* C3.4.6 PC-rel. addressing
2303  *   31  30   29 28       24 23                5 4    0
2304  * +----+-------+-----------+-------------------+------+
2305  * | op | immlo | 1 0 0 0 0 |       immhi       |  Rd  |
2306  * +----+-------+-----------+-------------------+------+
2307  */
2308 static void disas_pc_rel_adr(DisasContext *s, uint32_t insn)
2309 {
2310     unsigned int page, rd;
2311     uint64_t base;
2312     int64_t offset;
2313
2314     page = extract32(insn, 31, 1);
2315     /* SignExtend(immhi:immlo) -> offset */
2316     offset = ((int64_t)sextract32(insn, 5, 19) << 2) | extract32(insn, 29, 2);
2317     rd = extract32(insn, 0, 5);
2318     base = s->pc - 4;
2319
2320     if (page) {
2321         /* ADRP (page based) */
2322         base &= ~0xfff;
2323         offset <<= 12;
2324     }
2325
2326     tcg_gen_movi_i64(cpu_reg(s, rd), base + offset);
2327 }
2328
2329 /*
2330  * C3.4.1 Add/subtract (immediate)
2331  *
2332  *  31 30 29 28       24 23 22 21         10 9   5 4   0
2333  * +--+--+--+-----------+-----+-------------+-----+-----+
2334  * |sf|op| S| 1 0 0 0 1 |shift|    imm12    |  Rn | Rd  |
2335  * +--+--+--+-----------+-----+-------------+-----+-----+
2336  *
2337  *    sf: 0 -> 32bit, 1 -> 64bit
2338  *    op: 0 -> add  , 1 -> sub
2339  *     S: 1 -> set flags
2340  * shift: 00 -> LSL imm by 0, 01 -> LSL imm by 12
2341  */
2342 static void disas_add_sub_imm(DisasContext *s, uint32_t insn)
2343 {
2344     int rd = extract32(insn, 0, 5);
2345     int rn = extract32(insn, 5, 5);
2346     uint64_t imm = extract32(insn, 10, 12);
2347     int shift = extract32(insn, 22, 2);
2348     bool setflags = extract32(insn, 29, 1);
2349     bool sub_op = extract32(insn, 30, 1);
2350     bool is_64bit = extract32(insn, 31, 1);
2351
2352     TCGv_i64 tcg_rn = cpu_reg_sp(s, rn);
2353     TCGv_i64 tcg_rd = setflags ? cpu_reg(s, rd) : cpu_reg_sp(s, rd);
2354     TCGv_i64 tcg_result;
2355
2356     switch (shift) {
2357     case 0x0:
2358         break;
2359     case 0x1:
2360         imm <<= 12;
2361         break;
2362     default:
2363         unallocated_encoding(s);
2364         return;
2365     }
2366
2367     tcg_result = tcg_temp_new_i64();
2368     if (!setflags) {
2369         if (sub_op) {
2370             tcg_gen_subi_i64(tcg_result, tcg_rn, imm);
2371         } else {
2372             tcg_gen_addi_i64(tcg_result, tcg_rn, imm);
2373         }
2374     } else {
2375         TCGv_i64 tcg_imm = tcg_const_i64(imm);
2376         if (sub_op) {
2377             gen_sub_CC(is_64bit, tcg_result, tcg_rn, tcg_imm);
2378         } else {
2379             gen_add_CC(is_64bit, tcg_result, tcg_rn, tcg_imm);
2380         }
2381         tcg_temp_free_i64(tcg_imm);
2382     }
2383
2384     if (is_64bit) {
2385         tcg_gen_mov_i64(tcg_rd, tcg_result);
2386     } else {
2387         tcg_gen_ext32u_i64(tcg_rd, tcg_result);
2388     }
2389
2390     tcg_temp_free_i64(tcg_result);
2391 }
2392
2393 /* The input should be a value in the bottom e bits (with higher
2394  * bits zero); returns that value replicated into every element
2395  * of size e in a 64 bit integer.
2396  */
2397 static uint64_t bitfield_replicate(uint64_t mask, unsigned int e)
2398 {
2399     assert(e != 0);
2400     while (e < 64) {
2401         mask |= mask << e;
2402         e *= 2;
2403     }
2404     return mask;
2405 }
2406
2407 /* Return a value with the bottom len bits set (where 0 < len <= 64) */
2408 static inline uint64_t bitmask64(unsigned int length)
2409 {
2410     assert(length > 0 && length <= 64);
2411     return ~0ULL >> (64 - length);
2412 }
2413
2414 /* Simplified variant of pseudocode DecodeBitMasks() for the case where we
2415  * only require the wmask. Returns false if the imms/immr/immn are a reserved
2416  * value (ie should cause a guest UNDEF exception), and true if they are
2417  * valid, in which case the decoded bit pattern is written to result.
2418  */
2419 static bool logic_imm_decode_wmask(uint64_t *result, unsigned int immn,
2420                                    unsigned int imms, unsigned int immr)
2421 {
2422     uint64_t mask;
2423     unsigned e, levels, s, r;
2424     int len;
2425
2426     assert(immn < 2 && imms < 64 && immr < 64);
2427
2428     /* The bit patterns we create here are 64 bit patterns which
2429      * are vectors of identical elements of size e = 2, 4, 8, 16, 32 or
2430      * 64 bits each. Each element contains the same value: a run
2431      * of between 1 and e-1 non-zero bits, rotated within the
2432      * element by between 0 and e-1 bits.
2433      *
2434      * The element size and run length are encoded into immn (1 bit)
2435      * and imms (6 bits) as follows:
2436      * 64 bit elements: immn = 1, imms = <length of run - 1>
2437      * 32 bit elements: immn = 0, imms = 0 : <length of run - 1>
2438      * 16 bit elements: immn = 0, imms = 10 : <length of run - 1>
2439      *  8 bit elements: immn = 0, imms = 110 : <length of run - 1>
2440      *  4 bit elements: immn = 0, imms = 1110 : <length of run - 1>
2441      *  2 bit elements: immn = 0, imms = 11110 : <length of run - 1>
2442      * Notice that immn = 0, imms = 11111x is the only combination
2443      * not covered by one of the above options; this is reserved.
2444      * Further, <length of run - 1> all-ones is a reserved pattern.
2445      *
2446      * In all cases the rotation is by immr % e (and immr is 6 bits).
2447      */
2448
2449     /* First determine the element size */
2450     len = 31 - clz32((immn << 6) | (~imms & 0x3f));
2451     if (len < 1) {
2452         /* This is the immn == 0, imms == 0x11111x case */
2453         return false;
2454     }
2455     e = 1 << len;
2456
2457     levels = e - 1;
2458     s = imms & levels;
2459     r = immr & levels;
2460
2461     if (s == levels) {
2462         /* <length of run - 1> mustn't be all-ones. */
2463         return false;
2464     }
2465
2466     /* Create the value of one element: s+1 set bits rotated
2467      * by r within the element (which is e bits wide)...
2468      */
2469     mask = bitmask64(s + 1);
2470     mask = (mask >> r) | (mask << (e - r));
2471     /* ...then replicate the element over the whole 64 bit value */
2472     mask = bitfield_replicate(mask, e);
2473     *result = mask;
2474     return true;
2475 }
2476
2477 /* C3.4.4 Logical (immediate)
2478  *   31  30 29 28         23 22  21  16 15  10 9    5 4    0
2479  * +----+-----+-------------+---+------+------+------+------+
2480  * | sf | opc | 1 0 0 1 0 0 | N | immr | imms |  Rn  |  Rd  |
2481  * +----+-----+-------------+---+------+------+------+------+
2482  */
2483 static void disas_logic_imm(DisasContext *s, uint32_t insn)
2484 {
2485     unsigned int sf, opc, is_n, immr, imms, rn, rd;
2486     TCGv_i64 tcg_rd, tcg_rn;
2487     uint64_t wmask;
2488     bool is_and = false;
2489
2490     sf = extract32(insn, 31, 1);
2491     opc = extract32(insn, 29, 2);
2492     is_n = extract32(insn, 22, 1);
2493     immr = extract32(insn, 16, 6);
2494     imms = extract32(insn, 10, 6);
2495     rn = extract32(insn, 5, 5);
2496     rd = extract32(insn, 0, 5);
2497
2498     if (!sf && is_n) {
2499         unallocated_encoding(s);
2500         return;
2501     }
2502
2503     if (opc == 0x3) { /* ANDS */
2504         tcg_rd = cpu_reg(s, rd);
2505     } else {
2506         tcg_rd = cpu_reg_sp(s, rd);
2507     }
2508     tcg_rn = cpu_reg(s, rn);
2509
2510     if (!logic_imm_decode_wmask(&wmask, is_n, imms, immr)) {
2511         /* some immediate field values are reserved */
2512         unallocated_encoding(s);
2513         return;
2514     }
2515
2516     if (!sf) {
2517         wmask &= 0xffffffff;
2518     }
2519
2520     switch (opc) {
2521     case 0x3: /* ANDS */
2522     case 0x0: /* AND */
2523         tcg_gen_andi_i64(tcg_rd, tcg_rn, wmask);
2524         is_and = true;
2525         break;
2526     case 0x1: /* ORR */
2527         tcg_gen_ori_i64(tcg_rd, tcg_rn, wmask);
2528         break;
2529     case 0x2: /* EOR */
2530         tcg_gen_xori_i64(tcg_rd, tcg_rn, wmask);
2531         break;
2532     default:
2533         assert(FALSE); /* must handle all above */
2534         break;
2535     }
2536
2537     if (!sf && !is_and) {
2538         /* zero extend final result; we know we can skip this for AND
2539          * since the immediate had the high 32 bits clear.
2540          */
2541         tcg_gen_ext32u_i64(tcg_rd, tcg_rd);
2542     }
2543
2544     if (opc == 3) { /* ANDS */
2545         gen_logic_CC(sf, tcg_rd);
2546     }
2547 }
2548
2549 /*
2550  * C3.4.5 Move wide (immediate)
2551  *
2552  *  31 30 29 28         23 22 21 20             5 4    0
2553  * +--+-----+-------------+-----+----------------+------+
2554  * |sf| opc | 1 0 0 1 0 1 |  hw |  imm16         |  Rd  |
2555  * +--+-----+-------------+-----+----------------+------+
2556  *
2557  * sf: 0 -> 32 bit, 1 -> 64 bit
2558  * opc: 00 -> N, 10 -> Z, 11 -> K
2559  * hw: shift/16 (0,16, and sf only 32, 48)
2560  */
2561 static void disas_movw_imm(DisasContext *s, uint32_t insn)
2562 {
2563     int rd = extract32(insn, 0, 5);
2564     uint64_t imm = extract32(insn, 5, 16);
2565     int sf = extract32(insn, 31, 1);
2566     int opc = extract32(insn, 29, 2);
2567     int pos = extract32(insn, 21, 2) << 4;
2568     TCGv_i64 tcg_rd = cpu_reg(s, rd);
2569     TCGv_i64 tcg_imm;
2570
2571     if (!sf && (pos >= 32)) {
2572         unallocated_encoding(s);
2573         return;
2574     }
2575
2576     switch (opc) {
2577     case 0: /* MOVN */
2578     case 2: /* MOVZ */
2579         imm <<= pos;
2580         if (opc == 0) {
2581             imm = ~imm;
2582         }
2583         if (!sf) {
2584             imm &= 0xffffffffu;
2585         }
2586         tcg_gen_movi_i64(tcg_rd, imm);
2587         break;
2588     case 3: /* MOVK */
2589         tcg_imm = tcg_const_i64(imm);
2590         tcg_gen_deposit_i64(tcg_rd, tcg_rd, tcg_imm, pos, 16);
2591         tcg_temp_free_i64(tcg_imm);
2592         if (!sf) {
2593             tcg_gen_ext32u_i64(tcg_rd, tcg_rd);
2594         }
2595         break;
2596     default:
2597         unallocated_encoding(s);
2598         break;
2599     }
2600 }
2601
2602 /* C3.4.2 Bitfield
2603  *   31  30 29 28         23 22  21  16 15  10 9    5 4    0
2604  * +----+-----+-------------+---+------+------+------+------+
2605  * | sf | opc | 1 0 0 1 1 0 | N | immr | imms |  Rn  |  Rd  |
2606  * +----+-----+-------------+---+------+------+------+------+
2607  */
2608 static void disas_bitfield(DisasContext *s, uint32_t insn)
2609 {
2610     unsigned int sf, n, opc, ri, si, rn, rd, bitsize, pos, len;
2611     TCGv_i64 tcg_rd, tcg_tmp;
2612
2613     sf = extract32(insn, 31, 1);
2614     opc = extract32(insn, 29, 2);
2615     n = extract32(insn, 22, 1);
2616     ri = extract32(insn, 16, 6);
2617     si = extract32(insn, 10, 6);
2618     rn = extract32(insn, 5, 5);
2619     rd = extract32(insn, 0, 5);
2620     bitsize = sf ? 64 : 32;
2621
2622     if (sf != n || ri >= bitsize || si >= bitsize || opc > 2) {
2623         unallocated_encoding(s);
2624         return;
2625     }
2626
2627     tcg_rd = cpu_reg(s, rd);
2628     tcg_tmp = read_cpu_reg(s, rn, sf);
2629
2630     /* OPTME: probably worth recognizing common cases of ext{8,16,32}{u,s} */
2631
2632     if (opc != 1) { /* SBFM or UBFM */
2633         tcg_gen_movi_i64(tcg_rd, 0);
2634     }
2635
2636     /* do the bit move operation */
2637     if (si >= ri) {
2638         /* Wd<s-r:0> = Wn<s:r> */
2639         tcg_gen_shri_i64(tcg_tmp, tcg_tmp, ri);
2640         pos = 0;
2641         len = (si - ri) + 1;
2642     } else {
2643         /* Wd<32+s-r,32-r> = Wn<s:0> */
2644         pos = bitsize - ri;
2645         len = si + 1;
2646     }
2647
2648     tcg_gen_deposit_i64(tcg_rd, tcg_rd, tcg_tmp, pos, len);
2649
2650     if (opc == 0) { /* SBFM - sign extend the destination field */
2651         tcg_gen_shli_i64(tcg_rd, tcg_rd, 64 - (pos + len));
2652         tcg_gen_sari_i64(tcg_rd, tcg_rd, 64 - (pos + len));
2653     }
2654
2655     if (!sf) { /* zero extend final result */
2656         tcg_gen_ext32u_i64(tcg_rd, tcg_rd);
2657     }
2658 }
2659
2660 /* C3.4.3 Extract
2661  *   31  30  29 28         23 22   21  20  16 15    10 9    5 4    0
2662  * +----+------+-------------+---+----+------+--------+------+------+
2663  * | sf | op21 | 1 0 0 1 1 1 | N | o0 |  Rm  |  imms  |  Rn  |  Rd  |
2664  * +----+------+-------------+---+----+------+--------+------+------+
2665  */
2666 static void disas_extract(DisasContext *s, uint32_t insn)
2667 {
2668     unsigned int sf, n, rm, imm, rn, rd, bitsize, op21, op0;
2669
2670     sf = extract32(insn, 31, 1);
2671     n = extract32(insn, 22, 1);
2672     rm = extract32(insn, 16, 5);
2673     imm = extract32(insn, 10, 6);
2674     rn = extract32(insn, 5, 5);
2675     rd = extract32(insn, 0, 5);
2676     op21 = extract32(insn, 29, 2);
2677     op0 = extract32(insn, 21, 1);
2678     bitsize = sf ? 64 : 32;
2679
2680     if (sf != n || op21 || op0 || imm >= bitsize) {
2681         unallocated_encoding(s);
2682     } else {
2683         TCGv_i64 tcg_rd, tcg_rm, tcg_rn;
2684
2685         tcg_rd = cpu_reg(s, rd);
2686
2687         if (imm) {
2688             /* OPTME: we can special case rm==rn as a rotate */
2689             tcg_rm = read_cpu_reg(s, rm, sf);
2690             tcg_rn = read_cpu_reg(s, rn, sf);
2691             tcg_gen_shri_i64(tcg_rm, tcg_rm, imm);
2692             tcg_gen_shli_i64(tcg_rn, tcg_rn, bitsize - imm);
2693             tcg_gen_or_i64(tcg_rd, tcg_rm, tcg_rn);
2694             if (!sf) {
2695                 tcg_gen_ext32u_i64(tcg_rd, tcg_rd);
2696             }
2697         } else {
2698             /* tcg shl_i32/shl_i64 is undefined for 32/64 bit shifts,
2699              * so an extract from bit 0 is a special case.
2700              */
2701             if (sf) {
2702                 tcg_gen_mov_i64(tcg_rd, cpu_reg(s, rm));
2703             } else {
2704                 tcg_gen_ext32u_i64(tcg_rd, cpu_reg(s, rm));
2705             }
2706         }
2707
2708     }
2709 }
2710
2711 /* C3.4 Data processing - immediate */
2712 static void disas_data_proc_imm(DisasContext *s, uint32_t insn)
2713 {
2714     switch (extract32(insn, 23, 6)) {
2715     case 0x20: case 0x21: /* PC-rel. addressing */
2716         disas_pc_rel_adr(s, insn);
2717         break;
2718     case 0x22: case 0x23: /* Add/subtract (immediate) */
2719         disas_add_sub_imm(s, insn);
2720         break;
2721     case 0x24: /* Logical (immediate) */
2722         disas_logic_imm(s, insn);
2723         break;
2724     case 0x25: /* Move wide (immediate) */
2725         disas_movw_imm(s, insn);
2726         break;
2727     case 0x26: /* Bitfield */
2728         disas_bitfield(s, insn);
2729         break;
2730     case 0x27: /* Extract */
2731         disas_extract(s, insn);
2732         break;
2733     default:
2734         unallocated_encoding(s);
2735         break;
2736     }
2737 }
2738
2739 /* Shift a TCGv src by TCGv shift_amount, put result in dst.
2740  * Note that it is the caller's responsibility to ensure that the
2741  * shift amount is in range (ie 0..31 or 0..63) and provide the ARM
2742  * mandated semantics for out of range shifts.
2743  */
2744 static void shift_reg(TCGv_i64 dst, TCGv_i64 src, int sf,
2745                       enum a64_shift_type shift_type, TCGv_i64 shift_amount)
2746 {
2747     switch (shift_type) {
2748     case A64_SHIFT_TYPE_LSL:
2749         tcg_gen_shl_i64(dst, src, shift_amount);
2750         break;
2751     case A64_SHIFT_TYPE_LSR:
2752         tcg_gen_shr_i64(dst, src, shift_amount);
2753         break;
2754     case A64_SHIFT_TYPE_ASR:
2755         if (!sf) {
2756             tcg_gen_ext32s_i64(dst, src);
2757         }
2758         tcg_gen_sar_i64(dst, sf ? src : dst, shift_amount);
2759         break;
2760     case A64_SHIFT_TYPE_ROR:
2761         if (sf) {
2762             tcg_gen_rotr_i64(dst, src, shift_amount);
2763         } else {
2764             TCGv_i32 t0, t1;
2765             t0 = tcg_temp_new_i32();
2766             t1 = tcg_temp_new_i32();
2767             tcg_gen_trunc_i64_i32(t0, src);
2768             tcg_gen_trunc_i64_i32(t1, shift_amount);
2769             tcg_gen_rotr_i32(t0, t0, t1);
2770             tcg_gen_extu_i32_i64(dst, t0);
2771             tcg_temp_free_i32(t0);
2772             tcg_temp_free_i32(t1);
2773         }
2774         break;
2775     default:
2776         assert(FALSE); /* all shift types should be handled */
2777         break;
2778     }
2779
2780     if (!sf) { /* zero extend final result */
2781         tcg_gen_ext32u_i64(dst, dst);
2782     }
2783 }
2784
2785 /* Shift a TCGv src by immediate, put result in dst.
2786  * The shift amount must be in range (this should always be true as the
2787  * relevant instructions will UNDEF on bad shift immediates).
2788  */
2789 static void shift_reg_imm(TCGv_i64 dst, TCGv_i64 src, int sf,
2790                           enum a64_shift_type shift_type, unsigned int shift_i)
2791 {
2792     assert(shift_i < (sf ? 64 : 32));
2793
2794     if (shift_i == 0) {
2795         tcg_gen_mov_i64(dst, src);
2796     } else {
2797         TCGv_i64 shift_const;
2798
2799         shift_const = tcg_const_i64(shift_i);
2800         shift_reg(dst, src, sf, shift_type, shift_const);
2801         tcg_temp_free_i64(shift_const);
2802     }
2803 }
2804
2805 /* C3.5.10 Logical (shifted register)
2806  *   31  30 29 28       24 23   22 21  20  16 15    10 9    5 4    0
2807  * +----+-----+-----------+-------+---+------+--------+------+------+
2808  * | sf | opc | 0 1 0 1 0 | shift | N |  Rm  |  imm6  |  Rn  |  Rd  |
2809  * +----+-----+-----------+-------+---+------+--------+------+------+
2810  */
2811 static void disas_logic_reg(DisasContext *s, uint32_t insn)
2812 {
2813     TCGv_i64 tcg_rd, tcg_rn, tcg_rm;
2814     unsigned int sf, opc, shift_type, invert, rm, shift_amount, rn, rd;
2815
2816     sf = extract32(insn, 31, 1);
2817     opc = extract32(insn, 29, 2);
2818     shift_type = extract32(insn, 22, 2);
2819     invert = extract32(insn, 21, 1);
2820     rm = extract32(insn, 16, 5);
2821     shift_amount = extract32(insn, 10, 6);
2822     rn = extract32(insn, 5, 5);
2823     rd = extract32(insn, 0, 5);
2824
2825     if (!sf && (shift_amount & (1 << 5))) {
2826         unallocated_encoding(s);
2827         return;
2828     }
2829
2830     tcg_rd = cpu_reg(s, rd);
2831
2832     if (opc == 1 && shift_amount == 0 && shift_type == 0 && rn == 31) {
2833         /* Unshifted ORR and ORN with WZR/XZR is the standard encoding for
2834          * register-register MOV and MVN, so it is worth special casing.
2835          */
2836         tcg_rm = cpu_reg(s, rm);
2837         if (invert) {
2838             tcg_gen_not_i64(tcg_rd, tcg_rm);
2839             if (!sf) {
2840                 tcg_gen_ext32u_i64(tcg_rd, tcg_rd);
2841             }
2842         } else {
2843             if (sf) {
2844                 tcg_gen_mov_i64(tcg_rd, tcg_rm);
2845             } else {
2846                 tcg_gen_ext32u_i64(tcg_rd, tcg_rm);
2847             }
2848         }
2849         return;
2850     }
2851
2852     tcg_rm = read_cpu_reg(s, rm, sf);
2853
2854     if (shift_amount) {
2855         shift_reg_imm(tcg_rm, tcg_rm, sf, shift_type, shift_amount);
2856     }
2857
2858     tcg_rn = cpu_reg(s, rn);
2859
2860     switch (opc | (invert << 2)) {
2861     case 0: /* AND */
2862     case 3: /* ANDS */
2863         tcg_gen_and_i64(tcg_rd, tcg_rn, tcg_rm);
2864         break;
2865     case 1: /* ORR */
2866         tcg_gen_or_i64(tcg_rd, tcg_rn, tcg_rm);
2867         break;
2868     case 2: /* EOR */
2869         tcg_gen_xor_i64(tcg_rd, tcg_rn, tcg_rm);
2870         break;
2871     case 4: /* BIC */
2872     case 7: /* BICS */
2873         tcg_gen_andc_i64(tcg_rd, tcg_rn, tcg_rm);
2874         break;
2875     case 5: /* ORN */
2876         tcg_gen_orc_i64(tcg_rd, tcg_rn, tcg_rm);
2877         break;
2878     case 6: /* EON */
2879         tcg_gen_eqv_i64(tcg_rd, tcg_rn, tcg_rm);
2880         break;
2881     default:
2882         assert(FALSE);
2883         break;
2884     }
2885
2886     if (!sf) {
2887         tcg_gen_ext32u_i64(tcg_rd, tcg_rd);
2888     }
2889
2890     if (opc == 3) {
2891         gen_logic_CC(sf, tcg_rd);
2892     }
2893 }
2894
2895 /*
2896  * C3.5.1 Add/subtract (extended register)
2897  *
2898  *  31|30|29|28       24|23 22|21|20   16|15  13|12  10|9  5|4  0|
2899  * +--+--+--+-----------+-----+--+-------+------+------+----+----+
2900  * |sf|op| S| 0 1 0 1 1 | opt | 1|  Rm   |option| imm3 | Rn | Rd |
2901  * +--+--+--+-----------+-----+--+-------+------+------+----+----+
2902  *
2903  *  sf: 0 -> 32bit, 1 -> 64bit
2904  *  op: 0 -> add  , 1 -> sub
2905  *   S: 1 -> set flags
2906  * opt: 00
2907  * option: extension type (see DecodeRegExtend)
2908  * imm3: optional shift to Rm
2909  *
2910  * Rd = Rn + LSL(extend(Rm), amount)
2911  */
2912 static void disas_add_sub_ext_reg(DisasContext *s, uint32_t insn)
2913 {
2914     int rd = extract32(insn, 0, 5);
2915     int rn = extract32(insn, 5, 5);
2916     int imm3 = extract32(insn, 10, 3);
2917     int option = extract32(insn, 13, 3);
2918     int rm = extract32(insn, 16, 5);
2919     bool setflags = extract32(insn, 29, 1);
2920     bool sub_op = extract32(insn, 30, 1);
2921     bool sf = extract32(insn, 31, 1);
2922
2923     TCGv_i64 tcg_rm, tcg_rn; /* temps */
2924     TCGv_i64 tcg_rd;
2925     TCGv_i64 tcg_result;
2926
2927     if (imm3 > 4) {
2928         unallocated_encoding(s);
2929         return;
2930     }
2931
2932     /* non-flag setting ops may use SP */
2933     if (!setflags) {
2934         tcg_rn = read_cpu_reg_sp(s, rn, sf);
2935         tcg_rd = cpu_reg_sp(s, rd);
2936     } else {
2937         tcg_rn = read_cpu_reg(s, rn, sf);
2938         tcg_rd = cpu_reg(s, rd);
2939     }
2940
2941     tcg_rm = read_cpu_reg(s, rm, sf);
2942     ext_and_shift_reg(tcg_rm, tcg_rm, option, imm3);
2943
2944     tcg_result = tcg_temp_new_i64();
2945
2946     if (!setflags) {
2947         if (sub_op) {
2948             tcg_gen_sub_i64(tcg_result, tcg_rn, tcg_rm);
2949         } else {
2950             tcg_gen_add_i64(tcg_result, tcg_rn, tcg_rm);
2951         }
2952     } else {
2953         if (sub_op) {
2954             gen_sub_CC(sf, tcg_result, tcg_rn, tcg_rm);
2955         } else {
2956             gen_add_CC(sf, tcg_result, tcg_rn, tcg_rm);
2957         }
2958     }
2959
2960     if (sf) {
2961         tcg_gen_mov_i64(tcg_rd, tcg_result);
2962     } else {
2963         tcg_gen_ext32u_i64(tcg_rd, tcg_result);
2964     }
2965
2966     tcg_temp_free_i64(tcg_result);
2967 }
2968
2969 /*
2970  * C3.5.2 Add/subtract (shifted register)
2971  *
2972  *  31 30 29 28       24 23 22 21 20   16 15     10 9    5 4    0
2973  * +--+--+--+-----------+-----+--+-------+---------+------+------+
2974  * |sf|op| S| 0 1 0 1 1 |shift| 0|  Rm   |  imm6   |  Rn  |  Rd  |
2975  * +--+--+--+-----------+-----+--+-------+---------+------+------+
2976  *
2977  *    sf: 0 -> 32bit, 1 -> 64bit
2978  *    op: 0 -> add  , 1 -> sub
2979  *     S: 1 -> set flags
2980  * shift: 00 -> LSL, 01 -> LSR, 10 -> ASR, 11 -> RESERVED
2981  *  imm6: Shift amount to apply to Rm before the add/sub
2982  */
2983 static void disas_add_sub_reg(DisasContext *s, uint32_t insn)
2984 {
2985     int rd = extract32(insn, 0, 5);
2986     int rn = extract32(insn, 5, 5);
2987     int imm6 = extract32(insn, 10, 6);
2988     int rm = extract32(insn, 16, 5);
2989     int shift_type = extract32(insn, 22, 2);
2990     bool setflags = extract32(insn, 29, 1);
2991     bool sub_op = extract32(insn, 30, 1);
2992     bool sf = extract32(insn, 31, 1);
2993
2994     TCGv_i64 tcg_rd = cpu_reg(s, rd);
2995     TCGv_i64 tcg_rn, tcg_rm;
2996     TCGv_i64 tcg_result;
2997
2998     if ((shift_type == 3) || (!sf && (imm6 > 31))) {
2999         unallocated_encoding(s);
3000         return;
3001     }
3002
3003     tcg_rn = read_cpu_reg(s, rn, sf);
3004     tcg_rm = read_cpu_reg(s, rm, sf);
3005
3006     shift_reg_imm(tcg_rm, tcg_rm, sf, shift_type, imm6);
3007
3008     tcg_result = tcg_temp_new_i64();
3009
3010     if (!setflags) {
3011         if (sub_op) {
3012             tcg_gen_sub_i64(tcg_result, tcg_rn, tcg_rm);
3013         } else {
3014             tcg_gen_add_i64(tcg_result, tcg_rn, tcg_rm);
3015         }
3016     } else {
3017         if (sub_op) {
3018             gen_sub_CC(sf, tcg_result, tcg_rn, tcg_rm);
3019         } else {
3020             gen_add_CC(sf, tcg_result, tcg_rn, tcg_rm);
3021         }
3022     }
3023
3024     if (sf) {
3025         tcg_gen_mov_i64(tcg_rd, tcg_result);
3026     } else {
3027         tcg_gen_ext32u_i64(tcg_rd, tcg_result);
3028     }
3029
3030     tcg_temp_free_i64(tcg_result);
3031 }
3032
3033 /* C3.5.9 Data-processing (3 source)
3034
3035    31 30  29 28       24 23 21  20  16  15  14  10 9    5 4    0
3036   +--+------+-----------+------+------+----+------+------+------+
3037   |sf| op54 | 1 1 0 1 1 | op31 |  Rm  | o0 |  Ra  |  Rn  |  Rd  |
3038   +--+------+-----------+------+------+----+------+------+------+
3039
3040  */
3041 static void disas_data_proc_3src(DisasContext *s, uint32_t insn)
3042 {
3043     int rd = extract32(insn, 0, 5);
3044     int rn = extract32(insn, 5, 5);
3045     int ra = extract32(insn, 10, 5);
3046     int rm = extract32(insn, 16, 5);
3047     int op_id = (extract32(insn, 29, 3) << 4) |
3048         (extract32(insn, 21, 3) << 1) |
3049         extract32(insn, 15, 1);
3050     bool sf = extract32(insn, 31, 1);
3051     bool is_sub = extract32(op_id, 0, 1);
3052     bool is_high = extract32(op_id, 2, 1);
3053     bool is_signed = false;
3054     TCGv_i64 tcg_op1;
3055     TCGv_i64 tcg_op2;
3056     TCGv_i64 tcg_tmp;
3057
3058     /* Note that op_id is sf:op54:op31:o0 so it includes the 32/64 size flag */
3059     switch (op_id) {
3060     case 0x42: /* SMADDL */
3061     case 0x43: /* SMSUBL */
3062     case 0x44: /* SMULH */
3063         is_signed = true;
3064         break;
3065     case 0x0: /* MADD (32bit) */
3066     case 0x1: /* MSUB (32bit) */
3067     case 0x40: /* MADD (64bit) */
3068     case 0x41: /* MSUB (64bit) */
3069     case 0x4a: /* UMADDL */
3070     case 0x4b: /* UMSUBL */
3071     case 0x4c: /* UMULH */
3072         break;
3073     default:
3074         unallocated_encoding(s);
3075         return;
3076     }
3077
3078     if (is_high) {
3079         TCGv_i64 low_bits = tcg_temp_new_i64(); /* low bits discarded */
3080         TCGv_i64 tcg_rd = cpu_reg(s, rd);
3081         TCGv_i64 tcg_rn = cpu_reg(s, rn);
3082         TCGv_i64 tcg_rm = cpu_reg(s, rm);
3083
3084         if (is_signed) {
3085             tcg_gen_muls2_i64(low_bits, tcg_rd, tcg_rn, tcg_rm);
3086         } else {
3087             tcg_gen_mulu2_i64(low_bits, tcg_rd, tcg_rn, tcg_rm);
3088         }
3089
3090         tcg_temp_free_i64(low_bits);
3091         return;
3092     }
3093
3094     tcg_op1 = tcg_temp_new_i64();
3095     tcg_op2 = tcg_temp_new_i64();
3096     tcg_tmp = tcg_temp_new_i64();
3097
3098     if (op_id < 0x42) {
3099         tcg_gen_mov_i64(tcg_op1, cpu_reg(s, rn));
3100         tcg_gen_mov_i64(tcg_op2, cpu_reg(s, rm));
3101     } else {
3102         if (is_signed) {
3103             tcg_gen_ext32s_i64(tcg_op1, cpu_reg(s, rn));
3104             tcg_gen_ext32s_i64(tcg_op2, cpu_reg(s, rm));
3105         } else {
3106             tcg_gen_ext32u_i64(tcg_op1, cpu_reg(s, rn));
3107             tcg_gen_ext32u_i64(tcg_op2, cpu_reg(s, rm));
3108         }
3109     }
3110
3111     if (ra == 31 && !is_sub) {
3112         /* Special-case MADD with rA == XZR; it is the standard MUL alias */
3113         tcg_gen_mul_i64(cpu_reg(s, rd), tcg_op1, tcg_op2);
3114     } else {
3115         tcg_gen_mul_i64(tcg_tmp, tcg_op1, tcg_op2);
3116         if (is_sub) {
3117             tcg_gen_sub_i64(cpu_reg(s, rd), cpu_reg(s, ra), tcg_tmp);
3118         } else {
3119             tcg_gen_add_i64(cpu_reg(s, rd), cpu_reg(s, ra), tcg_tmp);
3120         }
3121     }
3122
3123     if (!sf) {
3124         tcg_gen_ext32u_i64(cpu_reg(s, rd), cpu_reg(s, rd));
3125     }
3126
3127     tcg_temp_free_i64(tcg_op1);
3128     tcg_temp_free_i64(tcg_op2);
3129     tcg_temp_free_i64(tcg_tmp);
3130 }
3131
3132 /* C3.5.3 - Add/subtract (with carry)
3133  *  31 30 29 28 27 26 25 24 23 22 21  20  16  15   10  9    5 4   0
3134  * +--+--+--+------------------------+------+---------+------+-----+
3135  * |sf|op| S| 1  1  0  1  0  0  0  0 |  rm  | opcode2 |  Rn  |  Rd |
3136  * +--+--+--+------------------------+------+---------+------+-----+
3137  *                                            [000000]
3138  */
3139
3140 static void disas_adc_sbc(DisasContext *s, uint32_t insn)
3141 {
3142     unsigned int sf, op, setflags, rm, rn, rd;
3143     TCGv_i64 tcg_y, tcg_rn, tcg_rd;
3144
3145     if (extract32(insn, 10, 6) != 0) {
3146         unallocated_encoding(s);
3147         return;
3148     }
3149
3150     sf = extract32(insn, 31, 1);
3151     op = extract32(insn, 30, 1);
3152     setflags = extract32(insn, 29, 1);
3153     rm = extract32(insn, 16, 5);
3154     rn = extract32(insn, 5, 5);
3155     rd = extract32(insn, 0, 5);
3156
3157     tcg_rd = cpu_reg(s, rd);
3158     tcg_rn = cpu_reg(s, rn);
3159
3160     if (op) {
3161         tcg_y = new_tmp_a64(s);
3162         tcg_gen_not_i64(tcg_y, cpu_reg(s, rm));
3163     } else {
3164         tcg_y = cpu_reg(s, rm);
3165     }
3166
3167     if (setflags) {
3168         gen_adc_CC(sf, tcg_rd, tcg_rn, tcg_y);
3169     } else {
3170         gen_adc(sf, tcg_rd, tcg_rn, tcg_y);
3171     }
3172 }
3173
3174 /* C3.5.4 - C3.5.5 Conditional compare (immediate / register)
3175  *  31 30 29 28 27 26 25 24 23 22 21  20    16 15  12  11  10  9   5  4 3   0
3176  * +--+--+--+------------------------+--------+------+----+--+------+--+-----+
3177  * |sf|op| S| 1  1  0  1  0  0  1  0 |imm5/rm | cond |i/r |o2|  Rn  |o3|nzcv |
3178  * +--+--+--+------------------------+--------+------+----+--+------+--+-----+
3179  *        [1]                             y                [0]       [0]
3180  */
3181 static void disas_cc(DisasContext *s, uint32_t insn)
3182 {
3183     unsigned int sf, op, y, cond, rn, nzcv, is_imm;
3184     int label_continue = -1;
3185     TCGv_i64 tcg_tmp, tcg_y, tcg_rn;
3186
3187     if (!extract32(insn, 29, 1)) {
3188         unallocated_encoding(s);
3189         return;
3190     }
3191     if (insn & (1 << 10 | 1 << 4)) {
3192         unallocated_encoding(s);
3193         return;
3194     }
3195     sf = extract32(insn, 31, 1);
3196     op = extract32(insn, 30, 1);
3197     is_imm = extract32(insn, 11, 1);
3198     y = extract32(insn, 16, 5); /* y = rm (reg) or imm5 (imm) */
3199     cond = extract32(insn, 12, 4);
3200     rn = extract32(insn, 5, 5);
3201     nzcv = extract32(insn, 0, 4);
3202
3203     if (cond < 0x0e) { /* not always */
3204         int label_match = gen_new_label();
3205         label_continue = gen_new_label();
3206         arm_gen_test_cc(cond, label_match);
3207         /* nomatch: */
3208         tcg_tmp = tcg_temp_new_i64();
3209         tcg_gen_movi_i64(tcg_tmp, nzcv << 28);
3210         gen_set_nzcv(tcg_tmp);
3211         tcg_temp_free_i64(tcg_tmp);
3212         tcg_gen_br(label_continue);
3213         gen_set_label(label_match);
3214     }
3215     /* match, or condition is always */
3216     if (is_imm) {
3217         tcg_y = new_tmp_a64(s);
3218         tcg_gen_movi_i64(tcg_y, y);
3219     } else {
3220         tcg_y = cpu_reg(s, y);
3221     }
3222     tcg_rn = cpu_reg(s, rn);
3223
3224     tcg_tmp = tcg_temp_new_i64();
3225     if (op) {
3226         gen_sub_CC(sf, tcg_tmp, tcg_rn, tcg_y);
3227     } else {
3228         gen_add_CC(sf, tcg_tmp, tcg_rn, tcg_y);
3229     }
3230     tcg_temp_free_i64(tcg_tmp);
3231
3232     if (cond < 0x0e) { /* continue */
3233         gen_set_label(label_continue);
3234     }
3235 }
3236
3237 /* C3.5.6 Conditional select
3238  *   31   30  29  28             21 20  16 15  12 11 10 9    5 4    0
3239  * +----+----+---+-----------------+------+------+-----+------+------+
3240  * | sf | op | S | 1 1 0 1 0 1 0 0 |  Rm  | cond | op2 |  Rn  |  Rd  |
3241  * +----+----+---+-----------------+------+------+-----+------+------+
3242  */
3243 static void disas_cond_select(DisasContext *s, uint32_t insn)
3244 {
3245     unsigned int sf, else_inv, rm, cond, else_inc, rn, rd;
3246     TCGv_i64 tcg_rd, tcg_src;
3247
3248     if (extract32(insn, 29, 1) || extract32(insn, 11, 1)) {
3249         /* S == 1 or op2<1> == 1 */
3250         unallocated_encoding(s);
3251         return;
3252     }
3253     sf = extract32(insn, 31, 1);
3254     else_inv = extract32(insn, 30, 1);
3255     rm = extract32(insn, 16, 5);
3256     cond = extract32(insn, 12, 4);
3257     else_inc = extract32(insn, 10, 1);
3258     rn = extract32(insn, 5, 5);
3259     rd = extract32(insn, 0, 5);
3260
3261     if (rd == 31) {
3262         /* silly no-op write; until we use movcond we must special-case
3263          * this to avoid a dead temporary across basic blocks.
3264          */
3265         return;
3266     }
3267
3268     tcg_rd = cpu_reg(s, rd);
3269
3270     if (cond >= 0x0e) { /* condition "always" */
3271         tcg_src = read_cpu_reg(s, rn, sf);
3272         tcg_gen_mov_i64(tcg_rd, tcg_src);
3273     } else {
3274         /* OPTME: we could use movcond here, at the cost of duplicating
3275          * a lot of the arm_gen_test_cc() logic.
3276          */
3277         int label_match = gen_new_label();
3278         int label_continue = gen_new_label();
3279
3280         arm_gen_test_cc(cond, label_match);
3281         /* nomatch: */
3282         tcg_src = cpu_reg(s, rm);
3283
3284         if (else_inv && else_inc) {
3285             tcg_gen_neg_i64(tcg_rd, tcg_src);
3286         } else if (else_inv) {
3287             tcg_gen_not_i64(tcg_rd, tcg_src);
3288         } else if (else_inc) {
3289             tcg_gen_addi_i64(tcg_rd, tcg_src, 1);
3290         } else {
3291             tcg_gen_mov_i64(tcg_rd, tcg_src);
3292         }
3293         if (!sf) {
3294             tcg_gen_ext32u_i64(tcg_rd, tcg_rd);
3295         }
3296         tcg_gen_br(label_continue);
3297         /* match: */
3298         gen_set_label(label_match);
3299         tcg_src = read_cpu_reg(s, rn, sf);
3300         tcg_gen_mov_i64(tcg_rd, tcg_src);
3301         /* continue: */
3302         gen_set_label(label_continue);
3303     }
3304 }
3305
3306 static void handle_clz(DisasContext *s, unsigned int sf,
3307                        unsigned int rn, unsigned int rd)
3308 {
3309     TCGv_i64 tcg_rd, tcg_rn;
3310     tcg_rd = cpu_reg(s, rd);
3311     tcg_rn = cpu_reg(s, rn);
3312
3313     if (sf) {
3314         gen_helper_clz64(tcg_rd, tcg_rn);
3315     } else {
3316         TCGv_i32 tcg_tmp32 = tcg_temp_new_i32();
3317         tcg_gen_trunc_i64_i32(tcg_tmp32, tcg_rn);
3318         gen_helper_clz(tcg_tmp32, tcg_tmp32);
3319         tcg_gen_extu_i32_i64(tcg_rd, tcg_tmp32);
3320         tcg_temp_free_i32(tcg_tmp32);
3321     }
3322 }
3323
3324 static void handle_cls(DisasContext *s, unsigned int sf,
3325                        unsigned int rn, unsigned int rd)
3326 {
3327     TCGv_i64 tcg_rd, tcg_rn;
3328     tcg_rd = cpu_reg(s, rd);
3329     tcg_rn = cpu_reg(s, rn);
3330
3331     if (sf) {
3332         gen_helper_cls64(tcg_rd, tcg_rn);
3333     } else {
3334         TCGv_i32 tcg_tmp32 = tcg_temp_new_i32();
3335         tcg_gen_trunc_i64_i32(tcg_tmp32, tcg_rn);
3336         gen_helper_cls32(tcg_tmp32, tcg_tmp32);
3337         tcg_gen_extu_i32_i64(tcg_rd, tcg_tmp32);
3338         tcg_temp_free_i32(tcg_tmp32);
3339     }
3340 }
3341
3342 static void handle_rbit(DisasContext *s, unsigned int sf,
3343                         unsigned int rn, unsigned int rd)
3344 {
3345     TCGv_i64 tcg_rd, tcg_rn;
3346     tcg_rd = cpu_reg(s, rd);
3347     tcg_rn = cpu_reg(s, rn);
3348
3349     if (sf) {
3350         gen_helper_rbit64(tcg_rd, tcg_rn);
3351     } else {
3352         TCGv_i32 tcg_tmp32 = tcg_temp_new_i32();
3353         tcg_gen_trunc_i64_i32(tcg_tmp32, tcg_rn);
3354         gen_helper_rbit(tcg_tmp32, tcg_tmp32);
3355         tcg_gen_extu_i32_i64(tcg_rd, tcg_tmp32);
3356         tcg_temp_free_i32(tcg_tmp32);
3357     }
3358 }
3359
3360 /* C5.6.149 REV with sf==1, opcode==3 ("REV64") */
3361 static void handle_rev64(DisasContext *s, unsigned int sf,
3362                          unsigned int rn, unsigned int rd)
3363 {
3364     if (!sf) {
3365         unallocated_encoding(s);
3366         return;
3367     }
3368     tcg_gen_bswap64_i64(cpu_reg(s, rd), cpu_reg(s, rn));
3369 }
3370
3371 /* C5.6.149 REV with sf==0, opcode==2
3372  * C5.6.151 REV32 (sf==1, opcode==2)
3373  */
3374 static void handle_rev32(DisasContext *s, unsigned int sf,
3375                          unsigned int rn, unsigned int rd)
3376 {
3377     TCGv_i64 tcg_rd = cpu_reg(s, rd);
3378
3379     if (sf) {
3380         TCGv_i64 tcg_tmp = tcg_temp_new_i64();
3381         TCGv_i64 tcg_rn = read_cpu_reg(s, rn, sf);
3382
3383         /* bswap32_i64 requires zero high word */
3384         tcg_gen_ext32u_i64(tcg_tmp, tcg_rn);
3385         tcg_gen_bswap32_i64(tcg_rd, tcg_tmp);
3386         tcg_gen_shri_i64(tcg_tmp, tcg_rn, 32);
3387         tcg_gen_bswap32_i64(tcg_tmp, tcg_tmp);
3388         tcg_gen_concat32_i64(tcg_rd, tcg_rd, tcg_tmp);
3389
3390         tcg_temp_free_i64(tcg_tmp);
3391     } else {
3392         tcg_gen_ext32u_i64(tcg_rd, cpu_reg(s, rn));
3393         tcg_gen_bswap32_i64(tcg_rd, tcg_rd);
3394     }
3395 }
3396
3397 /* C5.6.150 REV16 (opcode==1) */
3398 static void handle_rev16(DisasContext *s, unsigned int sf,
3399                          unsigned int rn, unsigned int rd)
3400 {
3401     TCGv_i64 tcg_rd = cpu_reg(s, rd);
3402     TCGv_i64 tcg_tmp = tcg_temp_new_i64();
3403     TCGv_i64 tcg_rn = read_cpu_reg(s, rn, sf);
3404
3405     tcg_gen_andi_i64(tcg_tmp, tcg_rn, 0xffff);
3406     tcg_gen_bswap16_i64(tcg_rd, tcg_tmp);
3407
3408     tcg_gen_shri_i64(tcg_tmp, tcg_rn, 16);
3409     tcg_gen_andi_i64(tcg_tmp, tcg_tmp, 0xffff);
3410     tcg_gen_bswap16_i64(tcg_tmp, tcg_tmp);
3411     tcg_gen_deposit_i64(tcg_rd, tcg_rd, tcg_tmp, 16, 16);
3412
3413     if (sf) {
3414         tcg_gen_shri_i64(tcg_tmp, tcg_rn, 32);
3415         tcg_gen_andi_i64(tcg_tmp, tcg_tmp, 0xffff);
3416         tcg_gen_bswap16_i64(tcg_tmp, tcg_tmp);
3417         tcg_gen_deposit_i64(tcg_rd, tcg_rd, tcg_tmp, 32, 16);
3418
3419         tcg_gen_shri_i64(tcg_tmp, tcg_rn, 48);
3420         tcg_gen_bswap16_i64(tcg_tmp, tcg_tmp);
3421         tcg_gen_deposit_i64(tcg_rd, tcg_rd, tcg_tmp, 48, 16);
3422     }
3423
3424     tcg_temp_free_i64(tcg_tmp);
3425 }
3426
3427 /* C3.5.7 Data-processing (1 source)
3428  *   31  30  29  28             21 20     16 15    10 9    5 4    0
3429  * +----+---+---+-----------------+---------+--------+------+------+
3430  * | sf | 1 | S | 1 1 0 1 0 1 1 0 | opcode2 | opcode |  Rn  |  Rd  |
3431  * +----+---+---+-----------------+---------+--------+------+------+
3432  */
3433 static void disas_data_proc_1src(DisasContext *s, uint32_t insn)
3434 {
3435     unsigned int sf, opcode, rn, rd;
3436
3437     if (extract32(insn, 29, 1) || extract32(insn, 16, 5)) {
3438         unallocated_encoding(s);
3439         return;
3440     }
3441
3442     sf = extract32(insn, 31, 1);
3443     opcode = extract32(insn, 10, 6);
3444     rn = extract32(insn, 5, 5);
3445     rd = extract32(insn, 0, 5);
3446
3447     switch (opcode) {
3448     case 0: /* RBIT */
3449         handle_rbit(s, sf, rn, rd);
3450         break;
3451     case 1: /* REV16 */
3452         handle_rev16(s, sf, rn, rd);
3453         break;
3454     case 2: /* REV32 */
3455         handle_rev32(s, sf, rn, rd);
3456         break;
3457     case 3: /* REV64 */
3458         handle_rev64(s, sf, rn, rd);
3459         break;
3460     case 4: /* CLZ */
3461         handle_clz(s, sf, rn, rd);
3462         break;
3463     case 5: /* CLS */
3464         handle_cls(s, sf, rn, rd);
3465         break;
3466     }
3467 }
3468
3469 static void handle_div(DisasContext *s, bool is_signed, unsigned int sf,
3470                        unsigned int rm, unsigned int rn, unsigned int rd)
3471 {
3472     TCGv_i64 tcg_n, tcg_m, tcg_rd;
3473     tcg_rd = cpu_reg(s, rd);
3474
3475     if (!sf && is_signed) {
3476         tcg_n = new_tmp_a64(s);
3477         tcg_m = new_tmp_a64(s);
3478         tcg_gen_ext32s_i64(tcg_n, cpu_reg(s, rn));
3479         tcg_gen_ext32s_i64(tcg_m, cpu_reg(s, rm));
3480     } else {
3481         tcg_n = read_cpu_reg(s, rn, sf);
3482         tcg_m = read_cpu_reg(s, rm, sf);
3483     }
3484
3485     if (is_signed) {
3486         gen_helper_sdiv64(tcg_rd, tcg_n, tcg_m);
3487     } else {
3488         gen_helper_udiv64(tcg_rd, tcg_n, tcg_m);
3489     }
3490
3491     if (!sf) { /* zero extend final result */
3492         tcg_gen_ext32u_i64(tcg_rd, tcg_rd);
3493     }
3494 }
3495
3496 /* C5.6.115 LSLV, C5.6.118 LSRV, C5.6.17 ASRV, C5.6.154 RORV */
3497 static void handle_shift_reg(DisasContext *s,
3498                              enum a64_shift_type shift_type, unsigned int sf,
3499                              unsigned int rm, unsigned int rn, unsigned int rd)
3500 {
3501     TCGv_i64 tcg_shift = tcg_temp_new_i64();
3502     TCGv_i64 tcg_rd = cpu_reg(s, rd);
3503     TCGv_i64 tcg_rn = read_cpu_reg(s, rn, sf);
3504
3505     tcg_gen_andi_i64(tcg_shift, cpu_reg(s, rm), sf ? 63 : 31);
3506     shift_reg(tcg_rd, tcg_rn, sf, shift_type, tcg_shift);
3507     tcg_temp_free_i64(tcg_shift);
3508 }
3509
3510 /* C3.5.8 Data-processing (2 source)
3511  *   31   30  29 28             21 20  16 15    10 9    5 4    0
3512  * +----+---+---+-----------------+------+--------+------+------+
3513  * | sf | 0 | S | 1 1 0 1 0 1 1 0 |  Rm  | opcode |  Rn  |  Rd  |
3514  * +----+---+---+-----------------+------+--------+------+------+
3515  */
3516 static void disas_data_proc_2src(DisasContext *s, uint32_t insn)
3517 {
3518     unsigned int sf, rm, opcode, rn, rd;
3519     sf = extract32(insn, 31, 1);
3520     rm = extract32(insn, 16, 5);
3521     opcode = extract32(insn, 10, 6);
3522     rn = extract32(insn, 5, 5);
3523     rd = extract32(insn, 0, 5);
3524
3525     if (extract32(insn, 29, 1)) {
3526         unallocated_encoding(s);
3527         return;
3528     }
3529
3530     switch (opcode) {
3531     case 2: /* UDIV */
3532         handle_div(s, false, sf, rm, rn, rd);
3533         break;
3534     case 3: /* SDIV */
3535         handle_div(s, true, sf, rm, rn, rd);
3536         break;
3537     case 8: /* LSLV */
3538         handle_shift_reg(s, A64_SHIFT_TYPE_LSL, sf, rm, rn, rd);
3539         break;
3540     case 9: /* LSRV */
3541         handle_shift_reg(s, A64_SHIFT_TYPE_LSR, sf, rm, rn, rd);
3542         break;
3543     case 10: /* ASRV */
3544         handle_shift_reg(s, A64_SHIFT_TYPE_ASR, sf, rm, rn, rd);
3545         break;
3546     case 11: /* RORV */
3547         handle_shift_reg(s, A64_SHIFT_TYPE_ROR, sf, rm, rn, rd);
3548         break;
3549     case 16:
3550     case 17:
3551     case 18:
3552     case 19:
3553     case 20:
3554     case 21:
3555     case 22:
3556     case 23: /* CRC32 */
3557         unsupported_encoding(s, insn);
3558         break;
3559     default:
3560         unallocated_encoding(s);
3561         break;
3562     }
3563 }
3564
3565 /* C3.5 Data processing - register */
3566 static void disas_data_proc_reg(DisasContext *s, uint32_t insn)
3567 {
3568     switch (extract32(insn, 24, 5)) {
3569     case 0x0a: /* Logical (shifted register) */
3570         disas_logic_reg(s, insn);
3571         break;
3572     case 0x0b: /* Add/subtract */
3573         if (insn & (1 << 21)) { /* (extended register) */
3574             disas_add_sub_ext_reg(s, insn);
3575         } else {
3576             disas_add_sub_reg(s, insn);
3577         }
3578         break;
3579     case 0x1b: /* Data-processing (3 source) */
3580         disas_data_proc_3src(s, insn);
3581         break;
3582     case 0x1a:
3583         switch (extract32(insn, 21, 3)) {
3584         case 0x0: /* Add/subtract (with carry) */
3585             disas_adc_sbc(s, insn);
3586             break;
3587         case 0x2: /* Conditional compare */
3588             disas_cc(s, insn); /* both imm and reg forms */
3589             break;
3590         case 0x4: /* Conditional select */
3591             disas_cond_select(s, insn);
3592             break;
3593         case 0x6: /* Data-processing */
3594             if (insn & (1 << 30)) { /* (1 source) */
3595                 disas_data_proc_1src(s, insn);
3596             } else {            /* (2 source) */
3597                 disas_data_proc_2src(s, insn);
3598             }
3599             break;
3600         default:
3601             unallocated_encoding(s);
3602             break;
3603         }
3604         break;
3605     default:
3606         unallocated_encoding(s);
3607         break;
3608     }
3609 }
3610
3611 /* Convert ARM rounding mode to softfloat */
3612 static inline int arm_rmode_to_sf(int rmode)
3613 {
3614     switch (rmode) {
3615     case FPROUNDING_TIEAWAY:
3616         rmode = float_round_ties_away;
3617         break;
3618     case FPROUNDING_ODD:
3619         /* FIXME: add support for TIEAWAY and ODD */
3620         qemu_log_mask(LOG_UNIMP, "arm: unimplemented rounding mode: %d\n",
3621                       rmode);
3622     case FPROUNDING_TIEEVEN:
3623     default:
3624         rmode = float_round_nearest_even;
3625         break;
3626     case FPROUNDING_POSINF:
3627         rmode = float_round_up;
3628         break;
3629     case FPROUNDING_NEGINF:
3630         rmode = float_round_down;
3631         break;
3632     case FPROUNDING_ZERO:
3633         rmode = float_round_to_zero;
3634         break;
3635     }
3636     return rmode;
3637 }
3638
3639 static void handle_fp_compare(DisasContext *s, bool is_double,
3640                               unsigned int rn, unsigned int rm,
3641                               bool cmp_with_zero, bool signal_all_nans)
3642 {
3643     TCGv_i64 tcg_flags = tcg_temp_new_i64();
3644     TCGv_ptr fpst = get_fpstatus_ptr();
3645
3646     if (is_double) {
3647         TCGv_i64 tcg_vn, tcg_vm;
3648
3649         tcg_vn = read_fp_dreg(s, rn);
3650         if (cmp_with_zero) {
3651             tcg_vm = tcg_const_i64(0);
3652         } else {
3653             tcg_vm = read_fp_dreg(s, rm);
3654         }
3655         if (signal_all_nans) {
3656             gen_helper_vfp_cmped_a64(tcg_flags, tcg_vn, tcg_vm, fpst);
3657         } else {
3658             gen_helper_vfp_cmpd_a64(tcg_flags, tcg_vn, tcg_vm, fpst);
3659         }
3660         tcg_temp_free_i64(tcg_vn);
3661         tcg_temp_free_i64(tcg_vm);
3662     } else {
3663         TCGv_i32 tcg_vn, tcg_vm;
3664
3665         tcg_vn = read_fp_sreg(s, rn);
3666         if (cmp_with_zero) {
3667             tcg_vm = tcg_const_i32(0);
3668         } else {
3669             tcg_vm = read_fp_sreg(s, rm);
3670         }
3671         if (signal_all_nans) {
3672             gen_helper_vfp_cmpes_a64(tcg_flags, tcg_vn, tcg_vm, fpst);
3673         } else {
3674             gen_helper_vfp_cmps_a64(tcg_flags, tcg_vn, tcg_vm, fpst);
3675         }
3676         tcg_temp_free_i32(tcg_vn);
3677         tcg_temp_free_i32(tcg_vm);
3678     }
3679
3680     tcg_temp_free_ptr(fpst);
3681
3682     gen_set_nzcv(tcg_flags);
3683
3684     tcg_temp_free_i64(tcg_flags);
3685 }
3686
3687 /* C3.6.22 Floating point compare
3688  *   31  30  29 28       24 23  22  21 20  16 15 14 13  10    9    5 4     0
3689  * +---+---+---+-----------+------+---+------+-----+---------+------+-------+
3690  * | M | 0 | S | 1 1 1 1 0 | type | 1 |  Rm  | op  | 1 0 0 0 |  Rn  |  op2  |
3691  * +---+---+---+-----------+------+---+------+-----+---------+------+-------+
3692  */
3693 static void disas_fp_compare(DisasContext *s, uint32_t insn)
3694 {
3695     unsigned int mos, type, rm, op, rn, opc, op2r;
3696
3697     mos = extract32(insn, 29, 3);
3698     type = extract32(insn, 22, 2); /* 0 = single, 1 = double */
3699     rm = extract32(insn, 16, 5);
3700     op = extract32(insn, 14, 2);
3701     rn = extract32(insn, 5, 5);
3702     opc = extract32(insn, 3, 2);
3703     op2r = extract32(insn, 0, 3);
3704
3705     if (mos || op || op2r || type > 1) {
3706         unallocated_encoding(s);
3707         return;
3708     }
3709
3710     handle_fp_compare(s, type, rn, rm, opc & 1, opc & 2);
3711 }
3712
3713 /* C3.6.23 Floating point conditional compare
3714  *   31  30  29 28       24 23  22  21 20  16 15  12 11 10 9    5  4   3    0
3715  * +---+---+---+-----------+------+---+------+------+-----+------+----+------+
3716  * | M | 0 | S | 1 1 1 1 0 | type | 1 |  Rm  | cond | 0 1 |  Rn  | op | nzcv |
3717  * +---+---+---+-----------+------+---+------+------+-----+------+----+------+
3718  */
3719 static void disas_fp_ccomp(DisasContext *s, uint32_t insn)
3720 {
3721     unsigned int mos, type, rm, cond, rn, op, nzcv;
3722     TCGv_i64 tcg_flags;
3723     int label_continue = -1;
3724
3725     mos = extract32(insn, 29, 3);
3726     type = extract32(insn, 22, 2); /* 0 = single, 1 = double */
3727     rm = extract32(insn, 16, 5);
3728     cond = extract32(insn, 12, 4);
3729     rn = extract32(insn, 5, 5);
3730     op = extract32(insn, 4, 1);
3731     nzcv = extract32(insn, 0, 4);
3732
3733     if (mos || type > 1) {
3734         unallocated_encoding(s);
3735         return;
3736     }
3737
3738     if (cond < 0x0e) { /* not always */
3739         int label_match = gen_new_label();
3740         label_continue = gen_new_label();
3741         arm_gen_test_cc(cond, label_match);
3742         /* nomatch: */
3743         tcg_flags = tcg_const_i64(nzcv << 28);
3744         gen_set_nzcv(tcg_flags);
3745         tcg_temp_free_i64(tcg_flags);
3746         tcg_gen_br(label_continue);
3747         gen_set_label(label_match);
3748     }
3749
3750     handle_fp_compare(s, type, rn, rm, false, op);
3751
3752     if (cond < 0x0e) {
3753         gen_set_label(label_continue);
3754     }
3755 }
3756
3757 /* copy src FP register to dst FP register; type specifies single or double */
3758 static void gen_mov_fp2fp(DisasContext *s, int type, int dst, int src)
3759 {
3760     if (type) {
3761         TCGv_i64 v = read_fp_dreg(s, src);
3762         write_fp_dreg(s, dst, v);
3763         tcg_temp_free_i64(v);
3764     } else {
3765         TCGv_i32 v = read_fp_sreg(s, src);
3766         write_fp_sreg(s, dst, v);
3767         tcg_temp_free_i32(v);
3768     }
3769 }
3770
3771 /* C3.6.24 Floating point conditional select
3772  *   31  30  29 28       24 23  22  21 20  16 15  12 11 10 9    5 4    0
3773  * +---+---+---+-----------+------+---+------+------+-----+------+------+
3774  * | M | 0 | S | 1 1 1 1 0 | type | 1 |  Rm  | cond | 1 1 |  Rn  |  Rd  |
3775  * +---+---+---+-----------+------+---+------+------+-----+------+------+
3776  */
3777 static void disas_fp_csel(DisasContext *s, uint32_t insn)
3778 {
3779     unsigned int mos, type, rm, cond, rn, rd;
3780     int label_continue = -1;
3781
3782     mos = extract32(insn, 29, 3);
3783     type = extract32(insn, 22, 2); /* 0 = single, 1 = double */
3784     rm = extract32(insn, 16, 5);
3785     cond = extract32(insn, 12, 4);
3786     rn = extract32(insn, 5, 5);
3787     rd = extract32(insn, 0, 5);
3788
3789     if (mos || type > 1) {
3790         unallocated_encoding(s);
3791         return;
3792     }
3793
3794     if (cond < 0x0e) { /* not always */
3795         int label_match = gen_new_label();
3796         label_continue = gen_new_label();
3797         arm_gen_test_cc(cond, label_match);
3798         /* nomatch: */
3799         gen_mov_fp2fp(s, type, rd, rm);
3800         tcg_gen_br(label_continue);
3801         gen_set_label(label_match);
3802     }
3803
3804     gen_mov_fp2fp(s, type, rd, rn);
3805
3806     if (cond < 0x0e) { /* continue */
3807         gen_set_label(label_continue);
3808     }
3809 }
3810
3811 /* C3.6.25 Floating-point data-processing (1 source) - single precision */
3812 static void handle_fp_1src_single(DisasContext *s, int opcode, int rd, int rn)
3813 {
3814     TCGv_ptr fpst;
3815     TCGv_i32 tcg_op;
3816     TCGv_i32 tcg_res;
3817
3818     fpst = get_fpstatus_ptr();
3819     tcg_op = read_fp_sreg(s, rn);
3820     tcg_res = tcg_temp_new_i32();
3821
3822     switch (opcode) {
3823     case 0x0: /* FMOV */
3824         tcg_gen_mov_i32(tcg_res, tcg_op);
3825         break;
3826     case 0x1: /* FABS */
3827         gen_helper_vfp_abss(tcg_res, tcg_op);
3828         break;
3829     case 0x2: /* FNEG */
3830         gen_helper_vfp_negs(tcg_res, tcg_op);
3831         break;
3832     case 0x3: /* FSQRT */
3833         gen_helper_vfp_sqrts(tcg_res, tcg_op, cpu_env);
3834         break;
3835     case 0x8: /* FRINTN */
3836     case 0x9: /* FRINTP */
3837     case 0xa: /* FRINTM */
3838     case 0xb: /* FRINTZ */
3839     case 0xc: /* FRINTA */
3840     {
3841         TCGv_i32 tcg_rmode = tcg_const_i32(arm_rmode_to_sf(opcode & 7));
3842
3843         gen_helper_set_rmode(tcg_rmode, tcg_rmode, cpu_env);
3844         gen_helper_rints(tcg_res, tcg_op, fpst);
3845
3846         gen_helper_set_rmode(tcg_rmode, tcg_rmode, cpu_env);
3847         tcg_temp_free_i32(tcg_rmode);
3848         break;
3849     }
3850     case 0xe: /* FRINTX */
3851         gen_helper_rints_exact(tcg_res, tcg_op, fpst);
3852         break;
3853     case 0xf: /* FRINTI */
3854         gen_helper_rints(tcg_res, tcg_op, fpst);
3855         break;
3856     default:
3857         abort();
3858     }
3859
3860     write_fp_sreg(s, rd, tcg_res);
3861
3862     tcg_temp_free_ptr(fpst);
3863     tcg_temp_free_i32(tcg_op);
3864     tcg_temp_free_i32(tcg_res);
3865 }
3866
3867 /* C3.6.25 Floating-point data-processing (1 source) - double precision */
3868 static void handle_fp_1src_double(DisasContext *s, int opcode, int rd, int rn)
3869 {
3870     TCGv_ptr fpst;
3871     TCGv_i64 tcg_op;
3872     TCGv_i64 tcg_res;
3873
3874     fpst = get_fpstatus_ptr();
3875     tcg_op = read_fp_dreg(s, rn);
3876     tcg_res = tcg_temp_new_i64();
3877
3878     switch (opcode) {
3879     case 0x0: /* FMOV */
3880         tcg_gen_mov_i64(tcg_res, tcg_op);
3881         break;
3882     case 0x1: /* FABS */
3883         gen_helper_vfp_absd(tcg_res, tcg_op);
3884         break;
3885     case 0x2: /* FNEG */
3886         gen_helper_vfp_negd(tcg_res, tcg_op);
3887         break;
3888     case 0x3: /* FSQRT */
3889         gen_helper_vfp_sqrtd(tcg_res, tcg_op, cpu_env);
3890         break;
3891     case 0x8: /* FRINTN */
3892     case 0x9: /* FRINTP */
3893     case 0xa: /* FRINTM */
3894     case 0xb: /* FRINTZ */
3895     case 0xc: /* FRINTA */
3896     {
3897         TCGv_i32 tcg_rmode = tcg_const_i32(arm_rmode_to_sf(opcode & 7));
3898
3899         gen_helper_set_rmode(tcg_rmode, tcg_rmode, cpu_env);
3900         gen_helper_rintd(tcg_res, tcg_op, fpst);
3901
3902         gen_helper_set_rmode(tcg_rmode, tcg_rmode, cpu_env);
3903         tcg_temp_free_i32(tcg_rmode);
3904         break;
3905     }
3906     case 0xe: /* FRINTX */
3907         gen_helper_rintd_exact(tcg_res, tcg_op, fpst);
3908         break;
3909     case 0xf: /* FRINTI */
3910         gen_helper_rintd(tcg_res, tcg_op, fpst);
3911         break;
3912     default:
3913         abort();
3914     }
3915
3916     write_fp_dreg(s, rd, tcg_res);
3917
3918     tcg_temp_free_ptr(fpst);
3919     tcg_temp_free_i64(tcg_op);
3920     tcg_temp_free_i64(tcg_res);
3921 }
3922
3923 static void handle_fp_fcvt(DisasContext *s, int opcode,
3924                            int rd, int rn, int dtype, int ntype)
3925 {
3926     switch (ntype) {
3927     case 0x0:
3928     {
3929         TCGv_i32 tcg_rn = read_fp_sreg(s, rn);
3930         if (dtype == 1) {
3931             /* Single to double */
3932             TCGv_i64 tcg_rd = tcg_temp_new_i64();
3933             gen_helper_vfp_fcvtds(tcg_rd, tcg_rn, cpu_env);
3934             write_fp_dreg(s, rd, tcg_rd);
3935             tcg_temp_free_i64(tcg_rd);
3936         } else {
3937             /* Single to half */
3938             TCGv_i32 tcg_rd = tcg_temp_new_i32();
3939             gen_helper_vfp_fcvt_f32_to_f16(tcg_rd, tcg_rn, cpu_env);
3940             /* write_fp_sreg is OK here because top half of tcg_rd is zero */
3941             write_fp_sreg(s, rd, tcg_rd);
3942             tcg_temp_free_i32(tcg_rd);
3943         }
3944         tcg_temp_free_i32(tcg_rn);
3945         break;
3946     }
3947     case 0x1:
3948     {
3949         TCGv_i64 tcg_rn = read_fp_dreg(s, rn);
3950         TCGv_i32 tcg_rd = tcg_temp_new_i32();
3951         if (dtype == 0) {
3952             /* Double to single */
3953             gen_helper_vfp_fcvtsd(tcg_rd, tcg_rn, cpu_env);
3954         } else {
3955             /* Double to half */
3956             gen_helper_vfp_fcvt_f64_to_f16(tcg_rd, tcg_rn, cpu_env);
3957             /* write_fp_sreg is OK here because top half of tcg_rd is zero */
3958         }
3959         write_fp_sreg(s, rd, tcg_rd);
3960         tcg_temp_free_i32(tcg_rd);
3961         tcg_temp_free_i64(tcg_rn);
3962         break;
3963     }
3964     case 0x3:
3965     {
3966         TCGv_i32 tcg_rn = read_fp_sreg(s, rn);
3967         tcg_gen_ext16u_i32(tcg_rn, tcg_rn);
3968         if (dtype == 0) {
3969             /* Half to single */
3970             TCGv_i32 tcg_rd = tcg_temp_new_i32();
3971             gen_helper_vfp_fcvt_f16_to_f32(tcg_rd, tcg_rn, cpu_env);
3972             write_fp_sreg(s, rd, tcg_rd);
3973             tcg_temp_free_i32(tcg_rd);
3974         } else {
3975             /* Half to double */
3976             TCGv_i64 tcg_rd = tcg_temp_new_i64();
3977             gen_helper_vfp_fcvt_f16_to_f64(tcg_rd, tcg_rn, cpu_env);
3978             write_fp_dreg(s, rd, tcg_rd);
3979             tcg_temp_free_i64(tcg_rd);
3980         }
3981         tcg_temp_free_i32(tcg_rn);
3982         break;
3983     }
3984     default:
3985         abort();
3986     }
3987 }
3988
3989 /* C3.6.25 Floating point data-processing (1 source)
3990  *   31  30  29 28       24 23  22  21 20    15 14       10 9    5 4    0
3991  * +---+---+---+-----------+------+---+--------+-----------+------+------+
3992  * | M | 0 | S | 1 1 1 1 0 | type | 1 | opcode | 1 0 0 0 0 |  Rn  |  Rd  |
3993  * +---+---+---+-----------+------+---+--------+-----------+------+------+
3994  */
3995 static void disas_fp_1src(DisasContext *s, uint32_t insn)
3996 {
3997     int type = extract32(insn, 22, 2);
3998     int opcode = extract32(insn, 15, 6);
3999     int rn = extract32(insn, 5, 5);
4000     int rd = extract32(insn, 0, 5);
4001
4002     switch (opcode) {
4003     case 0x4: case 0x5: case 0x7:
4004     {
4005         /* FCVT between half, single and double precision */
4006         int dtype = extract32(opcode, 0, 2);
4007         if (type == 2 || dtype == type) {
4008             unallocated_encoding(s);
4009             return;
4010         }
4011         handle_fp_fcvt(s, opcode, rd, rn, dtype, type);
4012         break;
4013     }
4014     case 0x0 ... 0x3:
4015     case 0x8 ... 0xc:
4016     case 0xe ... 0xf:
4017         /* 32-to-32 and 64-to-64 ops */
4018         switch (type) {
4019         case 0:
4020             handle_fp_1src_single(s, opcode, rd, rn);
4021             break;
4022         case 1:
4023             handle_fp_1src_double(s, opcode, rd, rn);
4024             break;
4025         default:
4026             unallocated_encoding(s);
4027         }
4028         break;
4029     default:
4030         unallocated_encoding(s);
4031         break;
4032     }
4033 }
4034
4035 /* C3.6.26 Floating-point data-processing (2 source) - single precision */
4036 static void handle_fp_2src_single(DisasContext *s, int opcode,
4037                                   int rd, int rn, int rm)
4038 {
4039     TCGv_i32 tcg_op1;
4040     TCGv_i32 tcg_op2;
4041     TCGv_i32 tcg_res;
4042     TCGv_ptr fpst;
4043
4044     tcg_res = tcg_temp_new_i32();
4045     fpst = get_fpstatus_ptr();
4046     tcg_op1 = read_fp_sreg(s, rn);
4047     tcg_op2 = read_fp_sreg(s, rm);
4048
4049     switch (opcode) {
4050     case 0x0: /* FMUL */
4051         gen_helper_vfp_muls(tcg_res, tcg_op1, tcg_op2, fpst);
4052         break;
4053     case 0x1: /* FDIV */
4054         gen_helper_vfp_divs(tcg_res, tcg_op1, tcg_op2, fpst);
4055         break;
4056     case 0x2: /* FADD */
4057         gen_helper_vfp_adds(tcg_res, tcg_op1, tcg_op2, fpst);
4058         break;
4059     case 0x3: /* FSUB */
4060         gen_helper_vfp_subs(tcg_res, tcg_op1, tcg_op2, fpst);
4061         break;
4062     case 0x4: /* FMAX */
4063         gen_helper_vfp_maxs(tcg_res, tcg_op1, tcg_op2, fpst);
4064         break;
4065     case 0x5: /* FMIN */
4066         gen_helper_vfp_mins(tcg_res, tcg_op1, tcg_op2, fpst);
4067         break;
4068     case 0x6: /* FMAXNM */
4069         gen_helper_vfp_maxnums(tcg_res, tcg_op1, tcg_op2, fpst);
4070         break;
4071     case 0x7: /* FMINNM */
4072         gen_helper_vfp_minnums(tcg_res, tcg_op1, tcg_op2, fpst);
4073         break;
4074     case 0x8: /* FNMUL */
4075         gen_helper_vfp_muls(tcg_res, tcg_op1, tcg_op2, fpst);
4076         gen_helper_vfp_negs(tcg_res, tcg_res);
4077         break;
4078     }
4079
4080     write_fp_sreg(s, rd, tcg_res);
4081
4082     tcg_temp_free_ptr(fpst);
4083     tcg_temp_free_i32(tcg_op1);
4084     tcg_temp_free_i32(tcg_op2);
4085     tcg_temp_free_i32(tcg_res);
4086 }
4087
4088 /* C3.6.26 Floating-point data-processing (2 source) - double precision */
4089 static void handle_fp_2src_double(DisasContext *s, int opcode,
4090                                   int rd, int rn, int rm)
4091 {
4092     TCGv_i64 tcg_op1;
4093     TCGv_i64 tcg_op2;
4094     TCGv_i64 tcg_res;
4095     TCGv_ptr fpst;
4096
4097     tcg_res = tcg_temp_new_i64();
4098     fpst = get_fpstatus_ptr();
4099     tcg_op1 = read_fp_dreg(s, rn);
4100     tcg_op2 = read_fp_dreg(s, rm);
4101
4102     switch (opcode) {
4103     case 0x0: /* FMUL */
4104         gen_helper_vfp_muld(tcg_res, tcg_op1, tcg_op2, fpst);
4105         break;
4106     case 0x1: /* FDIV */
4107         gen_helper_vfp_divd(tcg_res, tcg_op1, tcg_op2, fpst);
4108         break;
4109     case 0x2: /* FADD */
4110         gen_helper_vfp_addd(tcg_res, tcg_op1, tcg_op2, fpst);
4111         break;
4112     case 0x3: /* FSUB */
4113         gen_helper_vfp_subd(tcg_res, tcg_op1, tcg_op2, fpst);
4114         break;
4115     case 0x4: /* FMAX */
4116         gen_helper_vfp_maxd(tcg_res, tcg_op1, tcg_op2, fpst);
4117         break;
4118     case 0x5: /* FMIN */
4119         gen_helper_vfp_mind(tcg_res, tcg_op1, tcg_op2, fpst);
4120         break;
4121     case 0x6: /* FMAXNM */
4122         gen_helper_vfp_maxnumd(tcg_res, tcg_op1, tcg_op2, fpst);
4123         break;
4124     case 0x7: /* FMINNM */
4125         gen_helper_vfp_minnumd(tcg_res, tcg_op1, tcg_op2, fpst);
4126         break;
4127     case 0x8: /* FNMUL */
4128         gen_helper_vfp_muld(tcg_res, tcg_op1, tcg_op2, fpst);
4129         gen_helper_vfp_negd(tcg_res, tcg_res);
4130         break;
4131     }
4132
4133     write_fp_dreg(s, rd, tcg_res);
4134
4135     tcg_temp_free_ptr(fpst);
4136     tcg_temp_free_i64(tcg_op1);
4137     tcg_temp_free_i64(tcg_op2);
4138     tcg_temp_free_i64(tcg_res);
4139 }
4140
4141 /* C3.6.26 Floating point data-processing (2 source)
4142  *   31  30  29 28       24 23  22  21 20  16 15    12 11 10 9    5 4    0
4143  * +---+---+---+-----------+------+---+------+--------+-----+------+------+
4144  * | M | 0 | S | 1 1 1 1 0 | type | 1 |  Rm  | opcode | 1 0 |  Rn  |  Rd  |
4145  * +---+---+---+-----------+------+---+------+--------+-----+------+------+
4146  */
4147 static void disas_fp_2src(DisasContext *s, uint32_t insn)
4148 {
4149     int type = extract32(insn, 22, 2);
4150     int rd = extract32(insn, 0, 5);
4151     int rn = extract32(insn, 5, 5);
4152     int rm = extract32(insn, 16, 5);
4153     int opcode = extract32(insn, 12, 4);
4154
4155     if (opcode > 8) {
4156         unallocated_encoding(s);
4157         return;
4158     }
4159
4160     switch (type) {
4161     case 0:
4162         handle_fp_2src_single(s, opcode, rd, rn, rm);
4163         break;
4164     case 1:
4165         handle_fp_2src_double(s, opcode, rd, rn, rm);
4166         break;
4167     default:
4168         unallocated_encoding(s);
4169     }
4170 }
4171
4172 /* C3.6.27 Floating-point data-processing (3 source) - single precision */
4173 static void handle_fp_3src_single(DisasContext *s, bool o0, bool o1,
4174                                   int rd, int rn, int rm, int ra)
4175 {
4176     TCGv_i32 tcg_op1, tcg_op2, tcg_op3;
4177     TCGv_i32 tcg_res = tcg_temp_new_i32();
4178     TCGv_ptr fpst = get_fpstatus_ptr();
4179
4180     tcg_op1 = read_fp_sreg(s, rn);
4181     tcg_op2 = read_fp_sreg(s, rm);
4182     tcg_op3 = read_fp_sreg(s, ra);
4183
4184     /* These are fused multiply-add, and must be done as one
4185      * floating point operation with no rounding between the
4186      * multiplication and addition steps.
4187      * NB that doing the negations here as separate steps is
4188      * correct : an input NaN should come out with its sign bit
4189      * flipped if it is a negated-input.
4190      */
4191     if (o1 == true) {
4192         gen_helper_vfp_negs(tcg_op3, tcg_op3);
4193     }
4194
4195     if (o0 != o1) {
4196         gen_helper_vfp_negs(tcg_op1, tcg_op1);
4197     }
4198
4199     gen_helper_vfp_muladds(tcg_res, tcg_op1, tcg_op2, tcg_op3, fpst);
4200
4201     write_fp_sreg(s, rd, tcg_res);
4202
4203     tcg_temp_free_ptr(fpst);
4204     tcg_temp_free_i32(tcg_op1);
4205     tcg_temp_free_i32(tcg_op2);
4206     tcg_temp_free_i32(tcg_op3);
4207     tcg_temp_free_i32(tcg_res);
4208 }
4209
4210 /* C3.6.27 Floating-point data-processing (3 source) - double precision */
4211 static void handle_fp_3src_double(DisasContext *s, bool o0, bool o1,
4212                                   int rd, int rn, int rm, int ra)
4213 {
4214     TCGv_i64 tcg_op1, tcg_op2, tcg_op3;
4215     TCGv_i64 tcg_res = tcg_temp_new_i64();
4216     TCGv_ptr fpst = get_fpstatus_ptr();
4217
4218     tcg_op1 = read_fp_dreg(s, rn);
4219     tcg_op2 = read_fp_dreg(s, rm);
4220     tcg_op3 = read_fp_dreg(s, ra);
4221
4222     /* These are fused multiply-add, and must be done as one
4223      * floating point operation with no rounding between the
4224      * multiplication and addition steps.
4225      * NB that doing the negations here as separate steps is
4226      * correct : an input NaN should come out with its sign bit
4227      * flipped if it is a negated-input.
4228      */
4229     if (o1 == true) {
4230         gen_helper_vfp_negd(tcg_op3, tcg_op3);
4231     }
4232
4233     if (o0 != o1) {
4234         gen_helper_vfp_negd(tcg_op1, tcg_op1);
4235     }
4236
4237     gen_helper_vfp_muladdd(tcg_res, tcg_op1, tcg_op2, tcg_op3, fpst);
4238
4239     write_fp_dreg(s, rd, tcg_res);
4240
4241     tcg_temp_free_ptr(fpst);
4242     tcg_temp_free_i64(tcg_op1);
4243     tcg_temp_free_i64(tcg_op2);
4244     tcg_temp_free_i64(tcg_op3);
4245     tcg_temp_free_i64(tcg_res);
4246 }
4247
4248 /* C3.6.27 Floating point data-processing (3 source)
4249  *   31  30  29 28       24 23  22  21  20  16  15  14  10 9    5 4    0
4250  * +---+---+---+-----------+------+----+------+----+------+------+------+
4251  * | M | 0 | S | 1 1 1 1 1 | type | o1 |  Rm  | o0 |  Ra  |  Rn  |  Rd  |
4252  * +---+---+---+-----------+------+----+------+----+------+------+------+
4253  */
4254 static void disas_fp_3src(DisasContext *s, uint32_t insn)
4255 {
4256     int type = extract32(insn, 22, 2);
4257     int rd = extract32(insn, 0, 5);
4258     int rn = extract32(insn, 5, 5);
4259     int ra = extract32(insn, 10, 5);
4260     int rm = extract32(insn, 16, 5);
4261     bool o0 = extract32(insn, 15, 1);
4262     bool o1 = extract32(insn, 21, 1);
4263
4264     switch (type) {
4265     case 0:
4266         handle_fp_3src_single(s, o0, o1, rd, rn, rm, ra);
4267         break;
4268     case 1:
4269         handle_fp_3src_double(s, o0, o1, rd, rn, rm, ra);
4270         break;
4271     default:
4272         unallocated_encoding(s);
4273     }
4274 }
4275
4276 /* C3.6.28 Floating point immediate
4277  *   31  30  29 28       24 23  22  21 20        13 12   10 9    5 4    0
4278  * +---+---+---+-----------+------+---+------------+-------+------+------+
4279  * | M | 0 | S | 1 1 1 1 0 | type | 1 |    imm8    | 1 0 0 | imm5 |  Rd  |
4280  * +---+---+---+-----------+------+---+------------+-------+------+------+
4281  */
4282 static void disas_fp_imm(DisasContext *s, uint32_t insn)
4283 {
4284     int rd = extract32(insn, 0, 5);
4285     int imm8 = extract32(insn, 13, 8);
4286     int is_double = extract32(insn, 22, 2);
4287     uint64_t imm;
4288     TCGv_i64 tcg_res;
4289
4290     if (is_double > 1) {
4291         unallocated_encoding(s);
4292         return;
4293     }
4294
4295     /* The imm8 encodes the sign bit, enough bits to represent
4296      * an exponent in the range 01....1xx to 10....0xx,
4297      * and the most significant 4 bits of the mantissa; see
4298      * VFPExpandImm() in the v8 ARM ARM.
4299      */
4300     if (is_double) {
4301         imm = (extract32(imm8, 7, 1) ? 0x8000 : 0) |
4302             (extract32(imm8, 6, 1) ? 0x3fc0 : 0x4000) |
4303             extract32(imm8, 0, 6);
4304         imm <<= 48;
4305     } else {
4306         imm = (extract32(imm8, 7, 1) ? 0x8000 : 0) |
4307             (extract32(imm8, 6, 1) ? 0x3e00 : 0x4000) |
4308             (extract32(imm8, 0, 6) << 3);
4309         imm <<= 16;
4310     }
4311
4312     tcg_res = tcg_const_i64(imm);
4313     write_fp_dreg(s, rd, tcg_res);
4314     tcg_temp_free_i64(tcg_res);
4315 }
4316
4317 /* Handle floating point <=> fixed point conversions. Note that we can
4318  * also deal with fp <=> integer conversions as a special case (scale == 64)
4319  * OPTME: consider handling that special case specially or at least skipping
4320  * the call to scalbn in the helpers for zero shifts.
4321  */
4322 static void handle_fpfpcvt(DisasContext *s, int rd, int rn, int opcode,
4323                            bool itof, int rmode, int scale, int sf, int type)
4324 {
4325     bool is_signed = !(opcode & 1);
4326     bool is_double = type;
4327     TCGv_ptr tcg_fpstatus;
4328     TCGv_i32 tcg_shift;
4329
4330     tcg_fpstatus = get_fpstatus_ptr();
4331
4332     tcg_shift = tcg_const_i32(64 - scale);
4333
4334     if (itof) {
4335         TCGv_i64 tcg_int = cpu_reg(s, rn);
4336         if (!sf) {
4337             TCGv_i64 tcg_extend = new_tmp_a64(s);
4338
4339             if (is_signed) {
4340                 tcg_gen_ext32s_i64(tcg_extend, tcg_int);
4341             } else {
4342                 tcg_gen_ext32u_i64(tcg_extend, tcg_int);
4343             }
4344
4345             tcg_int = tcg_extend;
4346         }
4347
4348         if (is_double) {
4349             TCGv_i64 tcg_double = tcg_temp_new_i64();
4350             if (is_signed) {
4351                 gen_helper_vfp_sqtod(tcg_double, tcg_int,
4352                                      tcg_shift, tcg_fpstatus);
4353             } else {
4354                 gen_helper_vfp_uqtod(tcg_double, tcg_int,
4355                                      tcg_shift, tcg_fpstatus);
4356             }
4357             write_fp_dreg(s, rd, tcg_double);
4358             tcg_temp_free_i64(tcg_double);
4359         } else {
4360             TCGv_i32 tcg_single = tcg_temp_new_i32();
4361             if (is_signed) {
4362                 gen_helper_vfp_sqtos(tcg_single, tcg_int,
4363                                      tcg_shift, tcg_fpstatus);
4364             } else {
4365                 gen_helper_vfp_uqtos(tcg_single, tcg_int,
4366                                      tcg_shift, tcg_fpstatus);
4367             }
4368             write_fp_sreg(s, rd, tcg_single);
4369             tcg_temp_free_i32(tcg_single);
4370         }
4371     } else {
4372         TCGv_i64 tcg_int = cpu_reg(s, rd);
4373         TCGv_i32 tcg_rmode;
4374
4375         if (extract32(opcode, 2, 1)) {
4376             /* There are too many rounding modes to all fit into rmode,
4377              * so FCVTA[US] is a special case.
4378              */
4379             rmode = FPROUNDING_TIEAWAY;
4380         }
4381
4382         tcg_rmode = tcg_const_i32(arm_rmode_to_sf(rmode));
4383
4384         gen_helper_set_rmode(tcg_rmode, tcg_rmode, cpu_env);
4385
4386         if (is_double) {
4387             TCGv_i64 tcg_double = read_fp_dreg(s, rn);
4388             if (is_signed) {
4389                 if (!sf) {
4390                     gen_helper_vfp_tosld(tcg_int, tcg_double,
4391                                          tcg_shift, tcg_fpstatus);
4392                 } else {
4393                     gen_helper_vfp_tosqd(tcg_int, tcg_double,
4394                                          tcg_shift, tcg_fpstatus);
4395                 }
4396             } else {
4397                 if (!sf) {
4398                     gen_helper_vfp_tould(tcg_int, tcg_double,
4399                                          tcg_shift, tcg_fpstatus);
4400                 } else {
4401                     gen_helper_vfp_touqd(tcg_int, tcg_double,
4402                                          tcg_shift, tcg_fpstatus);
4403                 }
4404             }
4405             tcg_temp_free_i64(tcg_double);
4406         } else {
4407             TCGv_i32 tcg_single = read_fp_sreg(s, rn);
4408             if (sf) {
4409                 if (is_signed) {
4410                     gen_helper_vfp_tosqs(tcg_int, tcg_single,
4411                                          tcg_shift, tcg_fpstatus);
4412                 } else {
4413                     gen_helper_vfp_touqs(tcg_int, tcg_single,
4414                                          tcg_shift, tcg_fpstatus);
4415                 }
4416             } else {
4417                 TCGv_i32 tcg_dest = tcg_temp_new_i32();
4418                 if (is_signed) {
4419                     gen_helper_vfp_tosls(tcg_dest, tcg_single,
4420                                          tcg_shift, tcg_fpstatus);
4421                 } else {
4422                     gen_helper_vfp_touls(tcg_dest, tcg_single,
4423                                          tcg_shift, tcg_fpstatus);
4424                 }
4425                 tcg_gen_extu_i32_i64(tcg_int, tcg_dest);
4426                 tcg_temp_free_i32(tcg_dest);
4427             }
4428             tcg_temp_free_i32(tcg_single);
4429         }
4430
4431         gen_helper_set_rmode(tcg_rmode, tcg_rmode, cpu_env);
4432         tcg_temp_free_i32(tcg_rmode);
4433
4434         if (!sf) {
4435             tcg_gen_ext32u_i64(tcg_int, tcg_int);
4436         }
4437     }
4438
4439     tcg_temp_free_ptr(tcg_fpstatus);
4440     tcg_temp_free_i32(tcg_shift);
4441 }
4442
4443 /* C3.6.29 Floating point <-> fixed point conversions
4444  *   31   30  29 28       24 23  22  21 20   19 18    16 15   10 9    5 4    0
4445  * +----+---+---+-----------+------+---+-------+--------+-------+------+------+
4446  * | sf | 0 | S | 1 1 1 1 0 | type | 0 | rmode | opcode | scale |  Rn  |  Rd  |
4447  * +----+---+---+-----------+------+---+-------+--------+-------+------+------+
4448  */
4449 static void disas_fp_fixed_conv(DisasContext *s, uint32_t insn)
4450 {
4451     int rd = extract32(insn, 0, 5);
4452     int rn = extract32(insn, 5, 5);
4453     int scale = extract32(insn, 10, 6);
4454     int opcode = extract32(insn, 16, 3);
4455     int rmode = extract32(insn, 19, 2);
4456     int type = extract32(insn, 22, 2);
4457     bool sbit = extract32(insn, 29, 1);
4458     bool sf = extract32(insn, 31, 1);
4459     bool itof;
4460
4461     if (sbit || (type > 1)
4462         || (!sf && scale < 32)) {
4463         unallocated_encoding(s);
4464         return;
4465     }
4466
4467     switch ((rmode << 3) | opcode) {
4468     case 0x2: /* SCVTF */
4469     case 0x3: /* UCVTF */
4470         itof = true;
4471         break;
4472     case 0x18: /* FCVTZS */
4473     case 0x19: /* FCVTZU */
4474         itof = false;
4475         break;
4476     default:
4477         unallocated_encoding(s);
4478         return;
4479     }
4480
4481     handle_fpfpcvt(s, rd, rn, opcode, itof, FPROUNDING_ZERO, scale, sf, type);
4482 }
4483
4484 static void handle_fmov(DisasContext *s, int rd, int rn, int type, bool itof)
4485 {
4486     /* FMOV: gpr to or from float, double, or top half of quad fp reg,
4487      * without conversion.
4488      */
4489
4490     if (itof) {
4491         TCGv_i64 tcg_rn = cpu_reg(s, rn);
4492
4493         switch (type) {
4494         case 0:
4495         {
4496             /* 32 bit */
4497             TCGv_i64 tmp = tcg_temp_new_i64();
4498             tcg_gen_ext32u_i64(tmp, tcg_rn);
4499             tcg_gen_st_i64(tmp, cpu_env, fp_reg_offset(rd, MO_64));
4500             tcg_gen_movi_i64(tmp, 0);
4501             tcg_gen_st_i64(tmp, cpu_env, fp_reg_hi_offset(rd));
4502             tcg_temp_free_i64(tmp);
4503             break;
4504         }
4505         case 1:
4506         {
4507             /* 64 bit */
4508             TCGv_i64 tmp = tcg_const_i64(0);
4509             tcg_gen_st_i64(tcg_rn, cpu_env, fp_reg_offset(rd, MO_64));
4510             tcg_gen_st_i64(tmp, cpu_env, fp_reg_hi_offset(rd));
4511             tcg_temp_free_i64(tmp);
4512             break;
4513         }
4514         case 2:
4515             /* 64 bit to top half. */
4516             tcg_gen_st_i64(tcg_rn, cpu_env, fp_reg_hi_offset(rd));
4517             break;
4518         }
4519     } else {
4520         TCGv_i64 tcg_rd = cpu_reg(s, rd);
4521
4522         switch (type) {
4523         case 0:
4524             /* 32 bit */
4525             tcg_gen_ld32u_i64(tcg_rd, cpu_env, fp_reg_offset(rn, MO_32));
4526             break;
4527         case 1:
4528             /* 64 bit */
4529             tcg_gen_ld_i64(tcg_rd, cpu_env, fp_reg_offset(rn, MO_64));
4530             break;
4531         case 2:
4532             /* 64 bits from top half */
4533             tcg_gen_ld_i64(tcg_rd, cpu_env, fp_reg_hi_offset(rn));
4534             break;
4535         }
4536     }
4537 }
4538
4539 /* C3.6.30 Floating point <-> integer conversions
4540  *   31   30  29 28       24 23  22  21 20   19 18 16 15         10 9  5 4  0
4541  * +----+---+---+-----------+------+---+-------+-----+-------------+----+----+
4542  * | sf | 0 | S | 1 1 1 1 0 | type | 1 | rmode | opc | 0 0 0 0 0 0 | Rn | Rd |
4543  * +----+---+---+-----------+------+---+-------+-----+-------------+----+----+
4544  */
4545 static void disas_fp_int_conv(DisasContext *s, uint32_t insn)
4546 {
4547     int rd = extract32(insn, 0, 5);
4548     int rn = extract32(insn, 5, 5);
4549     int opcode = extract32(insn, 16, 3);
4550     int rmode = extract32(insn, 19, 2);
4551     int type = extract32(insn, 22, 2);
4552     bool sbit = extract32(insn, 29, 1);
4553     bool sf = extract32(insn, 31, 1);
4554
4555     if (sbit) {
4556         unallocated_encoding(s);
4557         return;
4558     }
4559
4560     if (opcode > 5) {
4561         /* FMOV */
4562         bool itof = opcode & 1;
4563
4564         if (rmode >= 2) {
4565             unallocated_encoding(s);
4566             return;
4567         }
4568
4569         switch (sf << 3 | type << 1 | rmode) {
4570         case 0x0: /* 32 bit */
4571         case 0xa: /* 64 bit */
4572         case 0xd: /* 64 bit to top half of quad */
4573             break;
4574         default:
4575             /* all other sf/type/rmode combinations are invalid */
4576             unallocated_encoding(s);
4577             break;
4578         }
4579
4580         handle_fmov(s, rd, rn, type, itof);
4581     } else {
4582         /* actual FP conversions */
4583         bool itof = extract32(opcode, 1, 1);
4584
4585         if (type > 1 || (rmode != 0 && opcode > 1)) {
4586             unallocated_encoding(s);
4587             return;
4588         }
4589
4590         handle_fpfpcvt(s, rd, rn, opcode, itof, rmode, 64, sf, type);
4591     }
4592 }
4593
4594 /* FP-specific subcases of table C3-6 (SIMD and FP data processing)
4595  *   31  30  29 28     25 24                          0
4596  * +---+---+---+---------+-----------------------------+
4597  * |   | 0 |   | 1 1 1 1 |                             |
4598  * +---+---+---+---------+-----------------------------+
4599  */
4600 static void disas_data_proc_fp(DisasContext *s, uint32_t insn)
4601 {
4602     if (extract32(insn, 24, 1)) {
4603         /* Floating point data-processing (3 source) */
4604         disas_fp_3src(s, insn);
4605     } else if (extract32(insn, 21, 1) == 0) {
4606         /* Floating point to fixed point conversions */
4607         disas_fp_fixed_conv(s, insn);
4608     } else {
4609         switch (extract32(insn, 10, 2)) {
4610         case 1:
4611             /* Floating point conditional compare */
4612             disas_fp_ccomp(s, insn);
4613             break;
4614         case 2:
4615             /* Floating point data-processing (2 source) */
4616             disas_fp_2src(s, insn);
4617             break;
4618         case 3:
4619             /* Floating point conditional select */
4620             disas_fp_csel(s, insn);
4621             break;
4622         case 0:
4623             switch (ctz32(extract32(insn, 12, 4))) {
4624             case 0: /* [15:12] == xxx1 */
4625                 /* Floating point immediate */
4626                 disas_fp_imm(s, insn);
4627                 break;
4628             case 1: /* [15:12] == xx10 */
4629                 /* Floating point compare */
4630                 disas_fp_compare(s, insn);
4631                 break;
4632             case 2: /* [15:12] == x100 */
4633                 /* Floating point data-processing (1 source) */
4634                 disas_fp_1src(s, insn);
4635                 break;
4636             case 3: /* [15:12] == 1000 */
4637                 unallocated_encoding(s);
4638                 break;
4639             default: /* [15:12] == 0000 */
4640                 /* Floating point <-> integer conversions */
4641                 disas_fp_int_conv(s, insn);
4642                 break;
4643             }
4644             break;
4645         }
4646     }
4647 }
4648
4649 static void do_ext64(DisasContext *s, TCGv_i64 tcg_left, TCGv_i64 tcg_right,
4650                      int pos)
4651 {
4652     /* Extract 64 bits from the middle of two concatenated 64 bit
4653      * vector register slices left:right. The extracted bits start
4654      * at 'pos' bits into the right (least significant) side.
4655      * We return the result in tcg_right, and guarantee not to
4656      * trash tcg_left.
4657      */
4658     TCGv_i64 tcg_tmp = tcg_temp_new_i64();
4659     assert(pos > 0 && pos < 64);
4660
4661     tcg_gen_shri_i64(tcg_right, tcg_right, pos);
4662     tcg_gen_shli_i64(tcg_tmp, tcg_left, 64 - pos);
4663     tcg_gen_or_i64(tcg_right, tcg_right, tcg_tmp);
4664
4665     tcg_temp_free_i64(tcg_tmp);
4666 }
4667
4668 /* C3.6.1 EXT
4669  *   31  30 29         24 23 22  21 20  16 15  14  11 10  9    5 4    0
4670  * +---+---+-------------+-----+---+------+---+------+---+------+------+
4671  * | 0 | Q | 1 0 1 1 1 0 | op2 | 0 |  Rm  | 0 | imm4 | 0 |  Rn  |  Rd  |
4672  * +---+---+-------------+-----+---+------+---+------+---+------+------+
4673  */
4674 static void disas_simd_ext(DisasContext *s, uint32_t insn)
4675 {
4676     int is_q = extract32(insn, 30, 1);
4677     int op2 = extract32(insn, 22, 2);
4678     int imm4 = extract32(insn, 11, 4);
4679     int rm = extract32(insn, 16, 5);
4680     int rn = extract32(insn, 5, 5);
4681     int rd = extract32(insn, 0, 5);
4682     int pos = imm4 << 3;
4683     TCGv_i64 tcg_resl, tcg_resh;
4684
4685     if (op2 != 0 || (!is_q && extract32(imm4, 3, 1))) {
4686         unallocated_encoding(s);
4687         return;
4688     }
4689
4690     tcg_resh = tcg_temp_new_i64();
4691     tcg_resl = tcg_temp_new_i64();
4692
4693     /* Vd gets bits starting at pos bits into Vm:Vn. This is
4694      * either extracting 128 bits from a 128:128 concatenation, or
4695      * extracting 64 bits from a 64:64 concatenation.
4696      */
4697     if (!is_q) {
4698         read_vec_element(s, tcg_resl, rn, 0, MO_64);
4699         if (pos != 0) {
4700             read_vec_element(s, tcg_resh, rm, 0, MO_64);
4701             do_ext64(s, tcg_resh, tcg_resl, pos);
4702         }
4703         tcg_gen_movi_i64(tcg_resh, 0);
4704     } else {
4705         TCGv_i64 tcg_hh;
4706         typedef struct {
4707             int reg;
4708             int elt;
4709         } EltPosns;
4710         EltPosns eltposns[] = { {rn, 0}, {rn, 1}, {rm, 0}, {rm, 1} };
4711         EltPosns *elt = eltposns;
4712
4713         if (pos >= 64) {
4714             elt++;
4715             pos -= 64;
4716         }
4717
4718         read_vec_element(s, tcg_resl, elt->reg, elt->elt, MO_64);
4719         elt++;
4720         read_vec_element(s, tcg_resh, elt->reg, elt->elt, MO_64);
4721         elt++;
4722         if (pos != 0) {
4723             do_ext64(s, tcg_resh, tcg_resl, pos);
4724             tcg_hh = tcg_temp_new_i64();
4725             read_vec_element(s, tcg_hh, elt->reg, elt->elt, MO_64);
4726             do_ext64(s, tcg_hh, tcg_resh, pos);
4727             tcg_temp_free_i64(tcg_hh);
4728         }
4729     }
4730
4731     write_vec_element(s, tcg_resl, rd, 0, MO_64);
4732     tcg_temp_free_i64(tcg_resl);
4733     write_vec_element(s, tcg_resh, rd, 1, MO_64);
4734     tcg_temp_free_i64(tcg_resh);
4735 }
4736
4737 /* C3.6.2 TBL/TBX
4738  *   31  30 29         24 23 22  21 20  16 15  14 13  12  11 10 9    5 4    0
4739  * +---+---+-------------+-----+---+------+---+-----+----+-----+------+------+
4740  * | 0 | Q | 0 0 1 1 1 0 | op2 | 0 |  Rm  | 0 | len | op | 0 0 |  Rn  |  Rd  |
4741  * +---+---+-------------+-----+---+------+---+-----+----+-----+------+------+
4742  */
4743 static void disas_simd_tb(DisasContext *s, uint32_t insn)
4744 {
4745     int op2 = extract32(insn, 22, 2);
4746     int is_q = extract32(insn, 30, 1);
4747     int rm = extract32(insn, 16, 5);
4748     int rn = extract32(insn, 5, 5);
4749     int rd = extract32(insn, 0, 5);
4750     int is_tblx = extract32(insn, 12, 1);
4751     int len = extract32(insn, 13, 2);
4752     TCGv_i64 tcg_resl, tcg_resh, tcg_idx;
4753     TCGv_i32 tcg_regno, tcg_numregs;
4754
4755     if (op2 != 0) {
4756         unallocated_encoding(s);
4757         return;
4758     }
4759
4760     /* This does a table lookup: for every byte element in the input
4761      * we index into a table formed from up to four vector registers,
4762      * and then the output is the result of the lookups. Our helper
4763      * function does the lookup operation for a single 64 bit part of
4764      * the input.
4765      */
4766     tcg_resl = tcg_temp_new_i64();
4767     tcg_resh = tcg_temp_new_i64();
4768
4769     if (is_tblx) {
4770         read_vec_element(s, tcg_resl, rd, 0, MO_64);
4771     } else {
4772         tcg_gen_movi_i64(tcg_resl, 0);
4773     }
4774     if (is_tblx && is_q) {
4775         read_vec_element(s, tcg_resh, rd, 1, MO_64);
4776     } else {
4777         tcg_gen_movi_i64(tcg_resh, 0);
4778     }
4779
4780     tcg_idx = tcg_temp_new_i64();
4781     tcg_regno = tcg_const_i32(rn);
4782     tcg_numregs = tcg_const_i32(len + 1);
4783     read_vec_element(s, tcg_idx, rm, 0, MO_64);
4784     gen_helper_simd_tbl(tcg_resl, cpu_env, tcg_resl, tcg_idx,
4785                         tcg_regno, tcg_numregs);
4786     if (is_q) {
4787         read_vec_element(s, tcg_idx, rm, 1, MO_64);
4788         gen_helper_simd_tbl(tcg_resh, cpu_env, tcg_resh, tcg_idx,
4789                             tcg_regno, tcg_numregs);
4790     }
4791     tcg_temp_free_i64(tcg_idx);
4792     tcg_temp_free_i32(tcg_regno);
4793     tcg_temp_free_i32(tcg_numregs);
4794
4795     write_vec_element(s, tcg_resl, rd, 0, MO_64);
4796     tcg_temp_free_i64(tcg_resl);
4797     write_vec_element(s, tcg_resh, rd, 1, MO_64);
4798     tcg_temp_free_i64(tcg_resh);
4799 }
4800
4801 /* C3.6.3 ZIP/UZP/TRN
4802  *   31  30 29         24 23  22  21 20   16 15 14 12 11 10 9    5 4    0
4803  * +---+---+-------------+------+---+------+---+------------------+------+
4804  * | 0 | Q | 0 0 1 1 1 0 | size | 0 |  Rm  | 0 | opc | 1 0 |  Rn  |  Rd  |
4805  * +---+---+-------------+------+---+------+---+------------------+------+
4806  */
4807 static void disas_simd_zip_trn(DisasContext *s, uint32_t insn)
4808 {
4809     unsupported_encoding(s, insn);
4810 }
4811
4812 /* C3.6.4 AdvSIMD across lanes
4813  *   31  30  29 28       24 23  22 21       17 16    12 11 10 9    5 4    0
4814  * +---+---+---+-----------+------+-----------+--------+-----+------+------+
4815  * | 0 | Q | U | 0 1 1 1 0 | size | 1 1 0 0 0 | opcode | 1 0 |  Rn  |  Rd  |
4816  * +---+---+---+-----------+------+-----------+--------+-----+------+------+
4817  */
4818 static void disas_simd_across_lanes(DisasContext *s, uint32_t insn)
4819 {
4820     unsupported_encoding(s, insn);
4821 }
4822
4823 /* C3.6.5 AdvSIMD copy
4824  *   31  30  29  28             21 20  16 15  14  11 10  9    5 4    0
4825  * +---+---+----+-----------------+------+---+------+---+------+------+
4826  * | 0 | Q | op | 0 1 1 1 0 0 0 0 | imm5 | 0 | imm4 | 1 |  Rn  |  Rd  |
4827  * +---+---+----+-----------------+------+---+------+---+------+------+
4828  */
4829 static void disas_simd_copy(DisasContext *s, uint32_t insn)
4830 {
4831     unsupported_encoding(s, insn);
4832 }
4833
4834 /* C3.6.6 AdvSIMD modified immediate
4835  *  31  30   29  28                 19 18 16 15   12  11  10  9     5 4    0
4836  * +---+---+----+---------------------+-----+-------+----+---+-------+------+
4837  * | 0 | Q | op | 0 1 1 1 1 0 0 0 0 0 | abc | cmode | o2 | 1 | defgh |  Rd  |
4838  * +---+---+----+---------------------+-----+-------+----+---+-------+------+
4839  */
4840 static void disas_simd_mod_imm(DisasContext *s, uint32_t insn)
4841 {
4842     unsupported_encoding(s, insn);
4843 }
4844
4845 /* C3.6.7 AdvSIMD scalar copy
4846  *  31 30  29  28             21 20  16 15  14  11 10  9    5 4    0
4847  * +-----+----+-----------------+------+---+------+---+------+------+
4848  * | 0 1 | op | 1 1 1 1 0 0 0 0 | imm5 | 0 | imm4 | 1 |  Rn  |  Rd  |
4849  * +-----+----+-----------------+------+---+------+---+------+------+
4850  */
4851 static void disas_simd_scalar_copy(DisasContext *s, uint32_t insn)
4852 {
4853     unsupported_encoding(s, insn);
4854 }
4855
4856 /* C3.6.8 AdvSIMD scalar pairwise
4857  *  31 30  29 28       24 23  22 21       17 16    12 11 10 9    5 4    0
4858  * +-----+---+-----------+------+-----------+--------+-----+------+------+
4859  * | 0 1 | U | 1 1 1 1 0 | size | 1 1 0 0 0 | opcode | 1 0 |  Rn  |  Rd  |
4860  * +-----+---+-----------+------+-----------+--------+-----+------+------+
4861  */
4862 static void disas_simd_scalar_pairwise(DisasContext *s, uint32_t insn)
4863 {
4864     unsupported_encoding(s, insn);
4865 }
4866
4867 /* C3.6.9 AdvSIMD scalar shift by immediate
4868  *  31 30  29 28         23 22  19 18  16 15    11  10 9    5 4    0
4869  * +-----+---+-------------+------+------+--------+---+------+------+
4870  * | 0 1 | U | 1 1 1 1 1 0 | immh | immb | opcode | 1 |  Rn  |  Rd  |
4871  * +-----+---+-------------+------+------+--------+---+------+------+
4872  */
4873 static void disas_simd_scalar_shift_imm(DisasContext *s, uint32_t insn)
4874 {
4875     unsupported_encoding(s, insn);
4876 }
4877
4878 /* C3.6.10 AdvSIMD scalar three different
4879  *  31 30  29 28       24 23  22  21 20  16 15    12 11 10 9    5 4    0
4880  * +-----+---+-----------+------+---+------+--------+-----+------+------+
4881  * | 0 1 | U | 1 1 1 1 0 | size | 1 |  Rm  | opcode | 0 0 |  Rn  |  Rd  |
4882  * +-----+---+-----------+------+---+------+--------+-----+------+------+
4883  */
4884 static void disas_simd_scalar_three_reg_diff(DisasContext *s, uint32_t insn)
4885 {
4886     unsupported_encoding(s, insn);
4887 }
4888
4889 /* C3.6.11 AdvSIMD scalar three same
4890  *  31 30  29 28       24 23  22  21 20  16 15    11  10 9    5 4    0
4891  * +-----+---+-----------+------+---+------+--------+---+------+------+
4892  * | 0 1 | U | 1 1 1 1 0 | size | 1 |  Rm  | opcode | 1 |  Rn  |  Rd  |
4893  * +-----+---+-----------+------+---+------+--------+---+------+------+
4894  */
4895 static void disas_simd_scalar_three_reg_same(DisasContext *s, uint32_t insn)
4896 {
4897     unsupported_encoding(s, insn);
4898 }
4899
4900 /* C3.6.12 AdvSIMD scalar two reg misc
4901  *  31 30  29 28       24 23  22 21       17 16    12 11 10 9    5 4    0
4902  * +-----+---+-----------+------+-----------+--------+-----+------+------+
4903  * | 0 1 | U | 1 1 1 1 0 | size | 1 0 0 0 0 | opcode | 1 0 |  Rn  |  Rd  |
4904  * +-----+---+-----------+------+-----------+--------+-----+------+------+
4905  */
4906 static void disas_simd_scalar_two_reg_misc(DisasContext *s, uint32_t insn)
4907 {
4908     unsupported_encoding(s, insn);
4909 }
4910
4911 /* C3.6.13 AdvSIMD scalar x indexed element
4912  *  31 30  29 28       24 23  22 21  20  19  16 15 12  11  10 9    5 4    0
4913  * +-----+---+-----------+------+---+---+------+-----+---+---+------+------+
4914  * | 0 1 | U | 1 1 1 1 1 | size | L | M |  Rm  | opc | H | 0 |  Rn  |  Rd  |
4915  * +-----+---+-----------+------+---+---+------+-----+---+---+------+------+
4916  */
4917 static void disas_simd_scalar_indexed(DisasContext *s, uint32_t insn)
4918 {
4919     unsupported_encoding(s, insn);
4920 }
4921
4922 /* C3.6.14 AdvSIMD shift by immediate
4923  *  31  30   29 28         23 22  19 18  16 15    11  10 9    5 4    0
4924  * +---+---+---+-------------+------+------+--------+---+------+------+
4925  * | 0 | Q | U | 0 1 1 1 1 0 | immh | immb | opcode | 1 |  Rn  |  Rd  |
4926  * +---+---+---+-------------+------+------+--------+---+------+------+
4927  */
4928 static void disas_simd_shift_imm(DisasContext *s, uint32_t insn)
4929 {
4930     unsupported_encoding(s, insn);
4931 }
4932
4933 /* C3.6.15 AdvSIMD three different
4934  *   31  30  29 28       24 23  22  21 20  16 15    12 11 10 9    5 4    0
4935  * +---+---+---+-----------+------+---+------+--------+-----+------+------+
4936  * | 0 | Q | U | 0 1 1 1 0 | size | 1 |  Rm  | opcode | 0 0 |  Rn  |  Rd  |
4937  * +---+---+---+-----------+------+---+------+--------+-----+------+------+
4938  */
4939 static void disas_simd_three_reg_diff(DisasContext *s, uint32_t insn)
4940 {
4941     unsupported_encoding(s, insn);
4942 }
4943
4944 /* C3.6.16 AdvSIMD three same
4945  *  31  30  29  28       24 23  22  21 20  16 15    11  10 9    5 4    0
4946  * +---+---+---+-----------+------+---+------+--------+---+------+------+
4947  * | 0 | Q | U | 0 1 1 1 0 | size | 1 |  Rm  | opcode | 1 |  Rn  |  Rd  |
4948  * +---+---+---+-----------+------+---+------+--------+---+------+------+
4949  */
4950 static void disas_simd_three_reg_same(DisasContext *s, uint32_t insn)
4951 {
4952     unsupported_encoding(s, insn);
4953 }
4954
4955 /* C3.6.17 AdvSIMD two reg misc
4956  *   31  30  29 28       24 23  22 21       17 16    12 11 10 9    5 4    0
4957  * +---+---+---+-----------+------+-----------+--------+-----+------+------+
4958  * | 0 | Q | U | 0 1 1 1 0 | size | 1 0 0 0 0 | opcode | 1 0 |  Rn  |  Rd  |
4959  * +---+---+---+-----------+------+-----------+--------+-----+------+------+
4960  */
4961 static void disas_simd_two_reg_misc(DisasContext *s, uint32_t insn)
4962 {
4963     unsupported_encoding(s, insn);
4964 }
4965
4966 /* C3.6.18 AdvSIMD vector x indexed element
4967  *   31  30  29 28       24 23  22 21  20  19  16 15 12  11  10 9    5 4    0
4968  * +---+---+---+-----------+------+---+---+------+-----+---+---+------+------+
4969  * | 0 | Q | U | 0 1 1 1 1 | size | L | M |  Rm  | opc | H | 0 |  Rn  |  Rd  |
4970  * +---+---+---+-----------+------+---+---+------+-----+---+---+------+------+
4971  */
4972 static void disas_simd_indexed_vector(DisasContext *s, uint32_t insn)
4973 {
4974     unsupported_encoding(s, insn);
4975 }
4976
4977 /* C3.6.19 Crypto AES
4978  *  31             24 23  22 21       17 16    12 11 10 9    5 4    0
4979  * +-----------------+------+-----------+--------+-----+------+------+
4980  * | 0 1 0 0 1 1 1 0 | size | 1 0 1 0 0 | opcode | 1 0 |  Rn  |  Rd  |
4981  * +-----------------+------+-----------+--------+-----+------+------+
4982  */
4983 static void disas_crypto_aes(DisasContext *s, uint32_t insn)
4984 {
4985     unsupported_encoding(s, insn);
4986 }
4987
4988 /* C3.6.20 Crypto three-reg SHA
4989  *  31             24 23  22  21 20  16  15 14    12 11 10 9    5 4    0
4990  * +-----------------+------+---+------+---+--------+-----+------+------+
4991  * | 0 1 0 1 1 1 1 0 | size | 0 |  Rm  | 0 | opcode | 0 0 |  Rn  |  Rd  |
4992  * +-----------------+------+---+------+---+--------+-----+------+------+
4993  */
4994 static void disas_crypto_three_reg_sha(DisasContext *s, uint32_t insn)
4995 {
4996     unsupported_encoding(s, insn);
4997 }
4998
4999 /* C3.6.21 Crypto two-reg SHA
5000  *  31             24 23  22 21       17 16    12 11 10 9    5 4    0
5001  * +-----------------+------+-----------+--------+-----+------+------+
5002  * | 0 1 0 1 1 1 1 0 | size | 1 0 1 0 0 | opcode | 1 0 |  Rn  |  Rd  |
5003  * +-----------------+------+-----------+--------+-----+------+------+
5004  */
5005 static void disas_crypto_two_reg_sha(DisasContext *s, uint32_t insn)
5006 {
5007     unsupported_encoding(s, insn);
5008 }
5009
5010 /* C3.6 Data processing - SIMD, inc Crypto
5011  *
5012  * As the decode gets a little complex we are using a table based
5013  * approach for this part of the decode.
5014  */
5015 static const AArch64DecodeTable data_proc_simd[] = {
5016     /* pattern  ,  mask     ,  fn                        */
5017     { 0x0e200400, 0x9f200400, disas_simd_three_reg_same },
5018     { 0x0e200000, 0x9f200c00, disas_simd_three_reg_diff },
5019     { 0x0e200800, 0x9f3e0c00, disas_simd_two_reg_misc },
5020     { 0x0e300800, 0x9f3e0c00, disas_simd_across_lanes },
5021     { 0x0e000400, 0x9fe08400, disas_simd_copy },
5022     { 0x0f000000, 0x9f000400, disas_simd_indexed_vector },
5023     /* simd_mod_imm decode is a subset of simd_shift_imm, so must precede it */
5024     { 0x0f000400, 0x9ff80400, disas_simd_mod_imm },
5025     { 0x0f000400, 0x9f800400, disas_simd_shift_imm },
5026     { 0x0e000000, 0xbf208c00, disas_simd_tb },
5027     { 0x0e000800, 0xbf208c00, disas_simd_zip_trn },
5028     { 0x2e000000, 0xbf208400, disas_simd_ext },
5029     { 0x5e200400, 0xdf200400, disas_simd_scalar_three_reg_same },
5030     { 0x5e200000, 0xdf200c00, disas_simd_scalar_three_reg_diff },
5031     { 0x5e200800, 0xdf3e0c00, disas_simd_scalar_two_reg_misc },
5032     { 0x5e300800, 0xdf3e0c00, disas_simd_scalar_pairwise },
5033     { 0x5e000400, 0xdfe08400, disas_simd_scalar_copy },
5034     { 0x5f000000, 0xdf000400, disas_simd_scalar_indexed },
5035     { 0x5f000400, 0xdf800400, disas_simd_scalar_shift_imm },
5036     { 0x4e280800, 0xff3e0c00, disas_crypto_aes },
5037     { 0x5e000000, 0xff208c00, disas_crypto_three_reg_sha },
5038     { 0x5e280800, 0xff3e0c00, disas_crypto_two_reg_sha },
5039     { 0x00000000, 0x00000000, NULL }
5040 };
5041
5042 static void disas_data_proc_simd(DisasContext *s, uint32_t insn)
5043 {
5044     /* Note that this is called with all non-FP cases from
5045      * table C3-6 so it must UNDEF for entries not specifically
5046      * allocated to instructions in that table.
5047      */
5048     AArch64DecodeFn *fn = lookup_disas_fn(&data_proc_simd[0], insn);
5049     if (fn) {
5050         fn(s, insn);
5051     } else {
5052         unallocated_encoding(s);
5053     }
5054 }
5055
5056 /* C3.6 Data processing - SIMD and floating point */
5057 static void disas_data_proc_simd_fp(DisasContext *s, uint32_t insn)
5058 {
5059     if (extract32(insn, 28, 1) == 1 && extract32(insn, 30, 1) == 0) {
5060         disas_data_proc_fp(s, insn);
5061     } else {
5062         /* SIMD, including crypto */
5063         disas_data_proc_simd(s, insn);
5064     }
5065 }
5066
5067 /* C3.1 A64 instruction index by encoding */
5068 static void disas_a64_insn(CPUARMState *env, DisasContext *s)
5069 {
5070     uint32_t insn;
5071
5072     insn = arm_ldl_code(env, s->pc, s->bswap_code);
5073     s->insn = insn;
5074     s->pc += 4;
5075
5076     switch (extract32(insn, 25, 4)) {
5077     case 0x0: case 0x1: case 0x2: case 0x3: /* UNALLOCATED */
5078         unallocated_encoding(s);
5079         break;
5080     case 0x8: case 0x9: /* Data processing - immediate */
5081         disas_data_proc_imm(s, insn);
5082         break;
5083     case 0xa: case 0xb: /* Branch, exception generation and system insns */
5084         disas_b_exc_sys(s, insn);
5085         break;
5086     case 0x4:
5087     case 0x6:
5088     case 0xc:
5089     case 0xe:      /* Loads and stores */
5090         disas_ldst(s, insn);
5091         break;
5092     case 0x5:
5093     case 0xd:      /* Data processing - register */
5094         disas_data_proc_reg(s, insn);
5095         break;
5096     case 0x7:
5097     case 0xf:      /* Data processing - SIMD and floating point */
5098         disas_data_proc_simd_fp(s, insn);
5099         break;
5100     default:
5101         assert(FALSE); /* all 15 cases should be handled above */
5102         break;
5103     }
5104
5105     /* if we allocated any temporaries, free them here */
5106     free_tmp_a64(s);
5107 }
5108
5109 void gen_intermediate_code_internal_a64(ARMCPU *cpu,
5110                                         TranslationBlock *tb,
5111                                         bool search_pc)
5112 {
5113     CPUState *cs = CPU(cpu);
5114     CPUARMState *env = &cpu->env;
5115     DisasContext dc1, *dc = &dc1;
5116     CPUBreakpoint *bp;
5117     uint16_t *gen_opc_end;
5118     int j, lj;
5119     target_ulong pc_start;
5120     target_ulong next_page_start;
5121     int num_insns;
5122     int max_insns;
5123
5124     pc_start = tb->pc;
5125
5126     dc->tb = tb;
5127
5128     gen_opc_end = tcg_ctx.gen_opc_buf + OPC_MAX_SIZE;
5129
5130     dc->is_jmp = DISAS_NEXT;
5131     dc->pc = pc_start;
5132     dc->singlestep_enabled = cs->singlestep_enabled;
5133     dc->condjmp = 0;
5134
5135     dc->aarch64 = 1;
5136     dc->thumb = 0;
5137     dc->bswap_code = 0;
5138     dc->condexec_mask = 0;
5139     dc->condexec_cond = 0;
5140 #if !defined(CONFIG_USER_ONLY)
5141     dc->user = 0;
5142 #endif
5143     dc->vfp_enabled = 0;
5144     dc->vec_len = 0;
5145     dc->vec_stride = 0;
5146     dc->cp_regs = cpu->cp_regs;
5147     dc->current_pl = arm_current_pl(env);
5148
5149     init_tmp_a64_array(dc);
5150
5151     next_page_start = (pc_start & TARGET_PAGE_MASK) + TARGET_PAGE_SIZE;
5152     lj = -1;
5153     num_insns = 0;
5154     max_insns = tb->cflags & CF_COUNT_MASK;
5155     if (max_insns == 0) {
5156         max_insns = CF_COUNT_MASK;
5157     }
5158
5159     gen_tb_start();
5160
5161     tcg_clear_temp_count();
5162
5163     do {
5164         if (unlikely(!QTAILQ_EMPTY(&env->breakpoints))) {
5165             QTAILQ_FOREACH(bp, &env->breakpoints, entry) {
5166                 if (bp->pc == dc->pc) {
5167                     gen_exception_insn(dc, 0, EXCP_DEBUG);
5168                     /* Advance PC so that clearing the breakpoint will
5169                        invalidate this TB.  */
5170                     dc->pc += 2;
5171                     goto done_generating;
5172                 }
5173             }
5174         }
5175
5176         if (search_pc) {
5177             j = tcg_ctx.gen_opc_ptr - tcg_ctx.gen_opc_buf;
5178             if (lj < j) {
5179                 lj++;
5180                 while (lj < j) {
5181                     tcg_ctx.gen_opc_instr_start[lj++] = 0;
5182                 }
5183             }
5184             tcg_ctx.gen_opc_pc[lj] = dc->pc;
5185             tcg_ctx.gen_opc_instr_start[lj] = 1;
5186             tcg_ctx.gen_opc_icount[lj] = num_insns;
5187         }
5188
5189         if (num_insns + 1 == max_insns && (tb->cflags & CF_LAST_IO)) {
5190             gen_io_start();
5191         }
5192
5193         if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP | CPU_LOG_TB_OP_OPT))) {
5194             tcg_gen_debug_insn_start(dc->pc);
5195         }
5196
5197         disas_a64_insn(env, dc);
5198
5199         if (tcg_check_temp_count()) {
5200             fprintf(stderr, "TCG temporary leak before "TARGET_FMT_lx"\n",
5201                     dc->pc);
5202         }
5203
5204         /* Translation stops when a conditional branch is encountered.
5205          * Otherwise the subsequent code could get translated several times.
5206          * Also stop translation when a page boundary is reached.  This
5207          * ensures prefetch aborts occur at the right place.
5208          */
5209         num_insns++;
5210     } while (!dc->is_jmp && tcg_ctx.gen_opc_ptr < gen_opc_end &&
5211              !cs->singlestep_enabled &&
5212              !singlestep &&
5213              dc->pc < next_page_start &&
5214              num_insns < max_insns);
5215
5216     if (tb->cflags & CF_LAST_IO) {
5217         gen_io_end();
5218     }
5219
5220     if (unlikely(cs->singlestep_enabled) && dc->is_jmp != DISAS_EXC) {
5221         /* Note that this means single stepping WFI doesn't halt the CPU.
5222          * For conditional branch insns this is harmless unreachable code as
5223          * gen_goto_tb() has already handled emitting the debug exception
5224          * (and thus a tb-jump is not possible when singlestepping).
5225          */
5226         assert(dc->is_jmp != DISAS_TB_JUMP);
5227         if (dc->is_jmp != DISAS_JUMP) {
5228             gen_a64_set_pc_im(dc->pc);
5229         }
5230         gen_exception(EXCP_DEBUG);
5231     } else {
5232         switch (dc->is_jmp) {
5233         case DISAS_NEXT:
5234             gen_goto_tb(dc, 1, dc->pc);
5235             break;
5236         default:
5237         case DISAS_UPDATE:
5238             gen_a64_set_pc_im(dc->pc);
5239             /* fall through */
5240         case DISAS_JUMP:
5241             /* indicate that the hash table must be used to find the next TB */
5242             tcg_gen_exit_tb(0);
5243             break;
5244         case DISAS_TB_JUMP:
5245         case DISAS_EXC:
5246         case DISAS_SWI:
5247             break;
5248         case DISAS_WFI:
5249             /* This is a special case because we don't want to just halt the CPU
5250              * if trying to debug across a WFI.
5251              */
5252             gen_helper_wfi(cpu_env);
5253             break;
5254         }
5255     }
5256
5257 done_generating:
5258     gen_tb_end(tb, num_insns);
5259     *tcg_ctx.gen_opc_ptr = INDEX_op_end;
5260
5261 #ifdef DEBUG_DISAS
5262     if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
5263         qemu_log("----------------\n");
5264         qemu_log("IN: %s\n", lookup_symbol(pc_start));
5265         log_target_disas(env, pc_start, dc->pc - pc_start,
5266                          dc->thumb | (dc->bswap_code << 1));
5267         qemu_log("\n");
5268     }
5269 #endif
5270     if (search_pc) {
5271         j = tcg_ctx.gen_opc_ptr - tcg_ctx.gen_opc_buf;
5272         lj++;
5273         while (lj <= j) {
5274             tcg_ctx.gen_opc_instr_start[lj++] = 0;
5275         }
5276     } else {
5277         tb->size = dc->pc - pc_start;
5278         tb->icount = num_insns;
5279     }
5280 }
This page took 0.310829 seconds and 4 git commands to generate.