Add qemu 2.4.0
[kvmfornfv.git] / qemu / target-arm / translate-a64.c
1 /*
2  *  AArch64 translation
3  *
4  *  Copyright (c) 2013 Alexander Graf <agraf@suse.de>
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 "arm_ldst.h"
29 #include "translate.h"
30 #include "internals.h"
31 #include "qemu/host-utils.h"
32
33 #include "exec/gen-icount.h"
34
35 #include "exec/helper-proto.h"
36 #include "exec/helper-gen.h"
37
38 #include "trace-tcg.h"
39
40 static TCGv_i64 cpu_X[32];
41 static TCGv_i64 cpu_pc;
42 static TCGv_i32 cpu_NF, cpu_ZF, cpu_CF, cpu_VF;
43
44 /* Load/store exclusive handling */
45 static TCGv_i64 cpu_exclusive_addr;
46 static TCGv_i64 cpu_exclusive_val;
47 static TCGv_i64 cpu_exclusive_high;
48 #ifdef CONFIG_USER_ONLY
49 static TCGv_i64 cpu_exclusive_test;
50 static TCGv_i32 cpu_exclusive_info;
51 #endif
52
53 static const char *regnames[] = {
54     "x0", "x1", "x2", "x3", "x4", "x5", "x6", "x7",
55     "x8", "x9", "x10", "x11", "x12", "x13", "x14", "x15",
56     "x16", "x17", "x18", "x19", "x20", "x21", "x22", "x23",
57     "x24", "x25", "x26", "x27", "x28", "x29", "lr", "sp"
58 };
59
60 enum a64_shift_type {
61     A64_SHIFT_TYPE_LSL = 0,
62     A64_SHIFT_TYPE_LSR = 1,
63     A64_SHIFT_TYPE_ASR = 2,
64     A64_SHIFT_TYPE_ROR = 3
65 };
66
67 /* Table based decoder typedefs - used when the relevant bits for decode
68  * are too awkwardly scattered across the instruction (eg SIMD).
69  */
70 typedef void AArch64DecodeFn(DisasContext *s, uint32_t insn);
71
72 typedef struct AArch64DecodeTable {
73     uint32_t pattern;
74     uint32_t mask;
75     AArch64DecodeFn *disas_fn;
76 } AArch64DecodeTable;
77
78 /* Function prototype for gen_ functions for calling Neon helpers */
79 typedef void NeonGenOneOpEnvFn(TCGv_i32, TCGv_ptr, TCGv_i32);
80 typedef void NeonGenTwoOpFn(TCGv_i32, TCGv_i32, TCGv_i32);
81 typedef void NeonGenTwoOpEnvFn(TCGv_i32, TCGv_ptr, TCGv_i32, TCGv_i32);
82 typedef void NeonGenTwo64OpFn(TCGv_i64, TCGv_i64, TCGv_i64);
83 typedef void NeonGenTwo64OpEnvFn(TCGv_i64, TCGv_ptr, TCGv_i64, TCGv_i64);
84 typedef void NeonGenNarrowFn(TCGv_i32, TCGv_i64);
85 typedef void NeonGenNarrowEnvFn(TCGv_i32, TCGv_ptr, TCGv_i64);
86 typedef void NeonGenWidenFn(TCGv_i64, TCGv_i32);
87 typedef void NeonGenTwoSingleOPFn(TCGv_i32, TCGv_i32, TCGv_i32, TCGv_ptr);
88 typedef void NeonGenTwoDoubleOPFn(TCGv_i64, TCGv_i64, TCGv_i64, TCGv_ptr);
89 typedef void NeonGenOneOpFn(TCGv_i64, TCGv_i64);
90 typedef void CryptoTwoOpEnvFn(TCGv_ptr, TCGv_i32, TCGv_i32);
91 typedef void CryptoThreeOpEnvFn(TCGv_ptr, TCGv_i32, TCGv_i32, TCGv_i32);
92
93 /* initialize TCG globals.  */
94 void a64_translate_init(void)
95 {
96     int i;
97
98     cpu_pc = tcg_global_mem_new_i64(TCG_AREG0,
99                                     offsetof(CPUARMState, pc),
100                                     "pc");
101     for (i = 0; i < 32; i++) {
102         cpu_X[i] = tcg_global_mem_new_i64(TCG_AREG0,
103                                           offsetof(CPUARMState, xregs[i]),
104                                           regnames[i]);
105     }
106
107     cpu_NF = tcg_global_mem_new_i32(TCG_AREG0, offsetof(CPUARMState, NF), "NF");
108     cpu_ZF = tcg_global_mem_new_i32(TCG_AREG0, offsetof(CPUARMState, ZF), "ZF");
109     cpu_CF = tcg_global_mem_new_i32(TCG_AREG0, offsetof(CPUARMState, CF), "CF");
110     cpu_VF = tcg_global_mem_new_i32(TCG_AREG0, offsetof(CPUARMState, VF), "VF");
111
112     cpu_exclusive_addr = tcg_global_mem_new_i64(TCG_AREG0,
113         offsetof(CPUARMState, exclusive_addr), "exclusive_addr");
114     cpu_exclusive_val = tcg_global_mem_new_i64(TCG_AREG0,
115         offsetof(CPUARMState, exclusive_val), "exclusive_val");
116     cpu_exclusive_high = tcg_global_mem_new_i64(TCG_AREG0,
117         offsetof(CPUARMState, exclusive_high), "exclusive_high");
118 #ifdef CONFIG_USER_ONLY
119     cpu_exclusive_test = tcg_global_mem_new_i64(TCG_AREG0,
120         offsetof(CPUARMState, exclusive_test), "exclusive_test");
121     cpu_exclusive_info = tcg_global_mem_new_i32(TCG_AREG0,
122         offsetof(CPUARMState, exclusive_info), "exclusive_info");
123 #endif
124 }
125
126 static inline ARMMMUIdx get_a64_user_mem_index(DisasContext *s)
127 {
128     /* Return the mmu_idx to use for A64 "unprivileged load/store" insns:
129      *  if EL1, access as if EL0; otherwise access at current EL
130      */
131     switch (s->mmu_idx) {
132     case ARMMMUIdx_S12NSE1:
133         return ARMMMUIdx_S12NSE0;
134     case ARMMMUIdx_S1SE1:
135         return ARMMMUIdx_S1SE0;
136     case ARMMMUIdx_S2NS:
137         g_assert_not_reached();
138     default:
139         return s->mmu_idx;
140     }
141 }
142
143 void aarch64_cpu_dump_state(CPUState *cs, FILE *f,
144                             fprintf_function cpu_fprintf, int flags)
145 {
146     ARMCPU *cpu = ARM_CPU(cs);
147     CPUARMState *env = &cpu->env;
148     uint32_t psr = pstate_read(env);
149     int i;
150
151     cpu_fprintf(f, "PC=%016"PRIx64"  SP=%016"PRIx64"\n",
152             env->pc, env->xregs[31]);
153     for (i = 0; i < 31; i++) {
154         cpu_fprintf(f, "X%02d=%016"PRIx64, i, env->xregs[i]);
155         if ((i % 4) == 3) {
156             cpu_fprintf(f, "\n");
157         } else {
158             cpu_fprintf(f, " ");
159         }
160     }
161     cpu_fprintf(f, "PSTATE=%08x (flags %c%c%c%c)\n",
162                 psr,
163                 psr & PSTATE_N ? 'N' : '-',
164                 psr & PSTATE_Z ? 'Z' : '-',
165                 psr & PSTATE_C ? 'C' : '-',
166                 psr & PSTATE_V ? 'V' : '-');
167     cpu_fprintf(f, "\n");
168
169     if (flags & CPU_DUMP_FPU) {
170         int numvfpregs = 32;
171         for (i = 0; i < numvfpregs; i += 2) {
172             uint64_t vlo = float64_val(env->vfp.regs[i * 2]);
173             uint64_t vhi = float64_val(env->vfp.regs[(i * 2) + 1]);
174             cpu_fprintf(f, "q%02d=%016" PRIx64 ":%016" PRIx64 " ",
175                         i, vhi, vlo);
176             vlo = float64_val(env->vfp.regs[(i + 1) * 2]);
177             vhi = float64_val(env->vfp.regs[((i + 1) * 2) + 1]);
178             cpu_fprintf(f, "q%02d=%016" PRIx64 ":%016" PRIx64 "\n",
179                         i + 1, vhi, vlo);
180         }
181         cpu_fprintf(f, "FPCR: %08x  FPSR: %08x\n",
182                     vfp_get_fpcr(env), vfp_get_fpsr(env));
183     }
184 }
185
186 void gen_a64_set_pc_im(uint64_t val)
187 {
188     tcg_gen_movi_i64(cpu_pc, val);
189 }
190
191 static void gen_exception_internal(int excp)
192 {
193     TCGv_i32 tcg_excp = tcg_const_i32(excp);
194
195     assert(excp_is_internal(excp));
196     gen_helper_exception_internal(cpu_env, tcg_excp);
197     tcg_temp_free_i32(tcg_excp);
198 }
199
200 static void gen_exception(int excp, uint32_t syndrome, uint32_t target_el)
201 {
202     TCGv_i32 tcg_excp = tcg_const_i32(excp);
203     TCGv_i32 tcg_syn = tcg_const_i32(syndrome);
204     TCGv_i32 tcg_el = tcg_const_i32(target_el);
205
206     gen_helper_exception_with_syndrome(cpu_env, tcg_excp,
207                                        tcg_syn, tcg_el);
208     tcg_temp_free_i32(tcg_el);
209     tcg_temp_free_i32(tcg_syn);
210     tcg_temp_free_i32(tcg_excp);
211 }
212
213 static void gen_exception_internal_insn(DisasContext *s, int offset, int excp)
214 {
215     gen_a64_set_pc_im(s->pc - offset);
216     gen_exception_internal(excp);
217     s->is_jmp = DISAS_EXC;
218 }
219
220 static void gen_exception_insn(DisasContext *s, int offset, int excp,
221                                uint32_t syndrome, uint32_t target_el)
222 {
223     gen_a64_set_pc_im(s->pc - offset);
224     gen_exception(excp, syndrome, target_el);
225     s->is_jmp = DISAS_EXC;
226 }
227
228 static void gen_ss_advance(DisasContext *s)
229 {
230     /* If the singlestep state is Active-not-pending, advance to
231      * Active-pending.
232      */
233     if (s->ss_active) {
234         s->pstate_ss = 0;
235         gen_helper_clear_pstate_ss(cpu_env);
236     }
237 }
238
239 static void gen_step_complete_exception(DisasContext *s)
240 {
241     /* We just completed step of an insn. Move from Active-not-pending
242      * to Active-pending, and then also take the swstep exception.
243      * This corresponds to making the (IMPDEF) choice to prioritize
244      * swstep exceptions over asynchronous exceptions taken to an exception
245      * level where debug is disabled. This choice has the advantage that
246      * we do not need to maintain internal state corresponding to the
247      * ISV/EX syndrome bits between completion of the step and generation
248      * of the exception, and our syndrome information is always correct.
249      */
250     gen_ss_advance(s);
251     gen_exception(EXCP_UDEF, syn_swstep(s->ss_same_el, 1, s->is_ldex),
252                   default_exception_el(s));
253     s->is_jmp = DISAS_EXC;
254 }
255
256 static inline bool use_goto_tb(DisasContext *s, int n, uint64_t dest)
257 {
258     /* No direct tb linking with singlestep (either QEMU's or the ARM
259      * debug architecture kind) or deterministic io
260      */
261     if (s->singlestep_enabled || s->ss_active || (s->tb->cflags & CF_LAST_IO)) {
262         return false;
263     }
264
265     /* Only link tbs from inside the same guest page */
266     if ((s->tb->pc & TARGET_PAGE_MASK) != (dest & TARGET_PAGE_MASK)) {
267         return false;
268     }
269
270     return true;
271 }
272
273 static inline void gen_goto_tb(DisasContext *s, int n, uint64_t dest)
274 {
275     TranslationBlock *tb;
276
277     tb = s->tb;
278     if (use_goto_tb(s, n, dest)) {
279         tcg_gen_goto_tb(n);
280         gen_a64_set_pc_im(dest);
281         tcg_gen_exit_tb((intptr_t)tb + n);
282         s->is_jmp = DISAS_TB_JUMP;
283     } else {
284         gen_a64_set_pc_im(dest);
285         if (s->ss_active) {
286             gen_step_complete_exception(s);
287         } else if (s->singlestep_enabled) {
288             gen_exception_internal(EXCP_DEBUG);
289         } else {
290             tcg_gen_exit_tb(0);
291             s->is_jmp = DISAS_TB_JUMP;
292         }
293     }
294 }
295
296 static void unallocated_encoding(DisasContext *s)
297 {
298     /* Unallocated and reserved encodings are uncategorized */
299     gen_exception_insn(s, 4, EXCP_UDEF, syn_uncategorized(),
300                        default_exception_el(s));
301 }
302
303 #define unsupported_encoding(s, insn)                                    \
304     do {                                                                 \
305         qemu_log_mask(LOG_UNIMP,                                         \
306                       "%s:%d: unsupported instruction encoding 0x%08x "  \
307                       "at pc=%016" PRIx64 "\n",                          \
308                       __FILE__, __LINE__, insn, s->pc - 4);              \
309         unallocated_encoding(s);                                         \
310     } while (0);
311
312 static void init_tmp_a64_array(DisasContext *s)
313 {
314 #ifdef CONFIG_DEBUG_TCG
315     int i;
316     for (i = 0; i < ARRAY_SIZE(s->tmp_a64); i++) {
317         TCGV_UNUSED_I64(s->tmp_a64[i]);
318     }
319 #endif
320     s->tmp_a64_count = 0;
321 }
322
323 static void free_tmp_a64(DisasContext *s)
324 {
325     int i;
326     for (i = 0; i < s->tmp_a64_count; i++) {
327         tcg_temp_free_i64(s->tmp_a64[i]);
328     }
329     init_tmp_a64_array(s);
330 }
331
332 static TCGv_i64 new_tmp_a64(DisasContext *s)
333 {
334     assert(s->tmp_a64_count < TMP_A64_MAX);
335     return s->tmp_a64[s->tmp_a64_count++] = tcg_temp_new_i64();
336 }
337
338 static TCGv_i64 new_tmp_a64_zero(DisasContext *s)
339 {
340     TCGv_i64 t = new_tmp_a64(s);
341     tcg_gen_movi_i64(t, 0);
342     return t;
343 }
344
345 /*
346  * Register access functions
347  *
348  * These functions are used for directly accessing a register in where
349  * changes to the final register value are likely to be made. If you
350  * need to use a register for temporary calculation (e.g. index type
351  * operations) use the read_* form.
352  *
353  * B1.2.1 Register mappings
354  *
355  * In instruction register encoding 31 can refer to ZR (zero register) or
356  * the SP (stack pointer) depending on context. In QEMU's case we map SP
357  * to cpu_X[31] and ZR accesses to a temporary which can be discarded.
358  * This is the point of the _sp forms.
359  */
360 static TCGv_i64 cpu_reg(DisasContext *s, int reg)
361 {
362     if (reg == 31) {
363         return new_tmp_a64_zero(s);
364     } else {
365         return cpu_X[reg];
366     }
367 }
368
369 /* register access for when 31 == SP */
370 static TCGv_i64 cpu_reg_sp(DisasContext *s, int reg)
371 {
372     return cpu_X[reg];
373 }
374
375 /* read a cpu register in 32bit/64bit mode. Returns a TCGv_i64
376  * representing the register contents. This TCGv is an auto-freed
377  * temporary so it need not be explicitly freed, and may be modified.
378  */
379 static TCGv_i64 read_cpu_reg(DisasContext *s, int reg, int sf)
380 {
381     TCGv_i64 v = new_tmp_a64(s);
382     if (reg != 31) {
383         if (sf) {
384             tcg_gen_mov_i64(v, cpu_X[reg]);
385         } else {
386             tcg_gen_ext32u_i64(v, cpu_X[reg]);
387         }
388     } else {
389         tcg_gen_movi_i64(v, 0);
390     }
391     return v;
392 }
393
394 static TCGv_i64 read_cpu_reg_sp(DisasContext *s, int reg, int sf)
395 {
396     TCGv_i64 v = new_tmp_a64(s);
397     if (sf) {
398         tcg_gen_mov_i64(v, cpu_X[reg]);
399     } else {
400         tcg_gen_ext32u_i64(v, cpu_X[reg]);
401     }
402     return v;
403 }
404
405 /* We should have at some point before trying to access an FP register
406  * done the necessary access check, so assert that
407  * (a) we did the check and
408  * (b) we didn't then just plough ahead anyway if it failed.
409  * Print the instruction pattern in the abort message so we can figure
410  * out what we need to fix if a user encounters this problem in the wild.
411  */
412 static inline void assert_fp_access_checked(DisasContext *s)
413 {
414 #ifdef CONFIG_DEBUG_TCG
415     if (unlikely(!s->fp_access_checked || s->fp_excp_el)) {
416         fprintf(stderr, "target-arm: FP access check missing for "
417                 "instruction 0x%08x\n", s->insn);
418         abort();
419     }
420 #endif
421 }
422
423 /* Return the offset into CPUARMState of an element of specified
424  * size, 'element' places in from the least significant end of
425  * the FP/vector register Qn.
426  */
427 static inline int vec_reg_offset(DisasContext *s, int regno,
428                                  int element, TCGMemOp size)
429 {
430     int offs = offsetof(CPUARMState, vfp.regs[regno * 2]);
431 #ifdef HOST_WORDS_BIGENDIAN
432     /* This is complicated slightly because vfp.regs[2n] is
433      * still the low half and  vfp.regs[2n+1] the high half
434      * of the 128 bit vector, even on big endian systems.
435      * Calculate the offset assuming a fully bigendian 128 bits,
436      * then XOR to account for the order of the two 64 bit halves.
437      */
438     offs += (16 - ((element + 1) * (1 << size)));
439     offs ^= 8;
440 #else
441     offs += element * (1 << size);
442 #endif
443     assert_fp_access_checked(s);
444     return offs;
445 }
446
447 /* Return the offset into CPUARMState of a slice (from
448  * the least significant end) of FP register Qn (ie
449  * Dn, Sn, Hn or Bn).
450  * (Note that this is not the same mapping as for A32; see cpu.h)
451  */
452 static inline int fp_reg_offset(DisasContext *s, int regno, TCGMemOp size)
453 {
454     int offs = offsetof(CPUARMState, vfp.regs[regno * 2]);
455 #ifdef HOST_WORDS_BIGENDIAN
456     offs += (8 - (1 << size));
457 #endif
458     assert_fp_access_checked(s);
459     return offs;
460 }
461
462 /* Offset of the high half of the 128 bit vector Qn */
463 static inline int fp_reg_hi_offset(DisasContext *s, int regno)
464 {
465     assert_fp_access_checked(s);
466     return offsetof(CPUARMState, vfp.regs[regno * 2 + 1]);
467 }
468
469 /* Convenience accessors for reading and writing single and double
470  * FP registers. Writing clears the upper parts of the associated
471  * 128 bit vector register, as required by the architecture.
472  * Note that unlike the GP register accessors, the values returned
473  * by the read functions must be manually freed.
474  */
475 static TCGv_i64 read_fp_dreg(DisasContext *s, int reg)
476 {
477     TCGv_i64 v = tcg_temp_new_i64();
478
479     tcg_gen_ld_i64(v, cpu_env, fp_reg_offset(s, reg, MO_64));
480     return v;
481 }
482
483 static TCGv_i32 read_fp_sreg(DisasContext *s, int reg)
484 {
485     TCGv_i32 v = tcg_temp_new_i32();
486
487     tcg_gen_ld_i32(v, cpu_env, fp_reg_offset(s, reg, MO_32));
488     return v;
489 }
490
491 static void write_fp_dreg(DisasContext *s, int reg, TCGv_i64 v)
492 {
493     TCGv_i64 tcg_zero = tcg_const_i64(0);
494
495     tcg_gen_st_i64(v, cpu_env, fp_reg_offset(s, reg, MO_64));
496     tcg_gen_st_i64(tcg_zero, cpu_env, fp_reg_hi_offset(s, reg));
497     tcg_temp_free_i64(tcg_zero);
498 }
499
500 static void write_fp_sreg(DisasContext *s, int reg, TCGv_i32 v)
501 {
502     TCGv_i64 tmp = tcg_temp_new_i64();
503
504     tcg_gen_extu_i32_i64(tmp, v);
505     write_fp_dreg(s, reg, tmp);
506     tcg_temp_free_i64(tmp);
507 }
508
509 static TCGv_ptr get_fpstatus_ptr(void)
510 {
511     TCGv_ptr statusptr = tcg_temp_new_ptr();
512     int offset;
513
514     /* In A64 all instructions (both FP and Neon) use the FPCR;
515      * there is no equivalent of the A32 Neon "standard FPSCR value"
516      * and all operations use vfp.fp_status.
517      */
518     offset = offsetof(CPUARMState, vfp.fp_status);
519     tcg_gen_addi_ptr(statusptr, cpu_env, offset);
520     return statusptr;
521 }
522
523 /* Set ZF and NF based on a 64 bit result. This is alas fiddlier
524  * than the 32 bit equivalent.
525  */
526 static inline void gen_set_NZ64(TCGv_i64 result)
527 {
528     TCGv_i64 flag = tcg_temp_new_i64();
529
530     tcg_gen_setcondi_i64(TCG_COND_NE, flag, result, 0);
531     tcg_gen_trunc_i64_i32(cpu_ZF, flag);
532     tcg_gen_shri_i64(flag, result, 32);
533     tcg_gen_trunc_i64_i32(cpu_NF, flag);
534     tcg_temp_free_i64(flag);
535 }
536
537 /* Set NZCV as for a logical operation: NZ as per result, CV cleared. */
538 static inline void gen_logic_CC(int sf, TCGv_i64 result)
539 {
540     if (sf) {
541         gen_set_NZ64(result);
542     } else {
543         tcg_gen_trunc_i64_i32(cpu_ZF, result);
544         tcg_gen_trunc_i64_i32(cpu_NF, result);
545     }
546     tcg_gen_movi_i32(cpu_CF, 0);
547     tcg_gen_movi_i32(cpu_VF, 0);
548 }
549
550 /* dest = T0 + T1; compute C, N, V and Z flags */
551 static void gen_add_CC(int sf, TCGv_i64 dest, TCGv_i64 t0, TCGv_i64 t1)
552 {
553     if (sf) {
554         TCGv_i64 result, flag, tmp;
555         result = tcg_temp_new_i64();
556         flag = tcg_temp_new_i64();
557         tmp = tcg_temp_new_i64();
558
559         tcg_gen_movi_i64(tmp, 0);
560         tcg_gen_add2_i64(result, flag, t0, tmp, t1, tmp);
561
562         tcg_gen_trunc_i64_i32(cpu_CF, flag);
563
564         gen_set_NZ64(result);
565
566         tcg_gen_xor_i64(flag, result, t0);
567         tcg_gen_xor_i64(tmp, t0, t1);
568         tcg_gen_andc_i64(flag, flag, tmp);
569         tcg_temp_free_i64(tmp);
570         tcg_gen_shri_i64(flag, flag, 32);
571         tcg_gen_trunc_i64_i32(cpu_VF, flag);
572
573         tcg_gen_mov_i64(dest, result);
574         tcg_temp_free_i64(result);
575         tcg_temp_free_i64(flag);
576     } else {
577         /* 32 bit arithmetic */
578         TCGv_i32 t0_32 = tcg_temp_new_i32();
579         TCGv_i32 t1_32 = tcg_temp_new_i32();
580         TCGv_i32 tmp = tcg_temp_new_i32();
581
582         tcg_gen_movi_i32(tmp, 0);
583         tcg_gen_trunc_i64_i32(t0_32, t0);
584         tcg_gen_trunc_i64_i32(t1_32, t1);
585         tcg_gen_add2_i32(cpu_NF, cpu_CF, t0_32, tmp, t1_32, tmp);
586         tcg_gen_mov_i32(cpu_ZF, cpu_NF);
587         tcg_gen_xor_i32(cpu_VF, cpu_NF, t0_32);
588         tcg_gen_xor_i32(tmp, t0_32, t1_32);
589         tcg_gen_andc_i32(cpu_VF, cpu_VF, tmp);
590         tcg_gen_extu_i32_i64(dest, cpu_NF);
591
592         tcg_temp_free_i32(tmp);
593         tcg_temp_free_i32(t0_32);
594         tcg_temp_free_i32(t1_32);
595     }
596 }
597
598 /* dest = T0 - T1; compute C, N, V and Z flags */
599 static void gen_sub_CC(int sf, TCGv_i64 dest, TCGv_i64 t0, TCGv_i64 t1)
600 {
601     if (sf) {
602         /* 64 bit arithmetic */
603         TCGv_i64 result, flag, tmp;
604
605         result = tcg_temp_new_i64();
606         flag = tcg_temp_new_i64();
607         tcg_gen_sub_i64(result, t0, t1);
608
609         gen_set_NZ64(result);
610
611         tcg_gen_setcond_i64(TCG_COND_GEU, flag, t0, t1);
612         tcg_gen_trunc_i64_i32(cpu_CF, flag);
613
614         tcg_gen_xor_i64(flag, result, t0);
615         tmp = tcg_temp_new_i64();
616         tcg_gen_xor_i64(tmp, t0, t1);
617         tcg_gen_and_i64(flag, flag, tmp);
618         tcg_temp_free_i64(tmp);
619         tcg_gen_shri_i64(flag, flag, 32);
620         tcg_gen_trunc_i64_i32(cpu_VF, flag);
621         tcg_gen_mov_i64(dest, result);
622         tcg_temp_free_i64(flag);
623         tcg_temp_free_i64(result);
624     } else {
625         /* 32 bit arithmetic */
626         TCGv_i32 t0_32 = tcg_temp_new_i32();
627         TCGv_i32 t1_32 = tcg_temp_new_i32();
628         TCGv_i32 tmp;
629
630         tcg_gen_trunc_i64_i32(t0_32, t0);
631         tcg_gen_trunc_i64_i32(t1_32, t1);
632         tcg_gen_sub_i32(cpu_NF, t0_32, t1_32);
633         tcg_gen_mov_i32(cpu_ZF, cpu_NF);
634         tcg_gen_setcond_i32(TCG_COND_GEU, cpu_CF, t0_32, t1_32);
635         tcg_gen_xor_i32(cpu_VF, cpu_NF, t0_32);
636         tmp = tcg_temp_new_i32();
637         tcg_gen_xor_i32(tmp, t0_32, t1_32);
638         tcg_temp_free_i32(t0_32);
639         tcg_temp_free_i32(t1_32);
640         tcg_gen_and_i32(cpu_VF, cpu_VF, tmp);
641         tcg_temp_free_i32(tmp);
642         tcg_gen_extu_i32_i64(dest, cpu_NF);
643     }
644 }
645
646 /* dest = T0 + T1 + CF; do not compute flags. */
647 static void gen_adc(int sf, TCGv_i64 dest, TCGv_i64 t0, TCGv_i64 t1)
648 {
649     TCGv_i64 flag = tcg_temp_new_i64();
650     tcg_gen_extu_i32_i64(flag, cpu_CF);
651     tcg_gen_add_i64(dest, t0, t1);
652     tcg_gen_add_i64(dest, dest, flag);
653     tcg_temp_free_i64(flag);
654
655     if (!sf) {
656         tcg_gen_ext32u_i64(dest, dest);
657     }
658 }
659
660 /* dest = T0 + T1 + CF; compute C, N, V and Z flags. */
661 static void gen_adc_CC(int sf, TCGv_i64 dest, TCGv_i64 t0, TCGv_i64 t1)
662 {
663     if (sf) {
664         TCGv_i64 result, cf_64, vf_64, tmp;
665         result = tcg_temp_new_i64();
666         cf_64 = tcg_temp_new_i64();
667         vf_64 = tcg_temp_new_i64();
668         tmp = tcg_const_i64(0);
669
670         tcg_gen_extu_i32_i64(cf_64, cpu_CF);
671         tcg_gen_add2_i64(result, cf_64, t0, tmp, cf_64, tmp);
672         tcg_gen_add2_i64(result, cf_64, result, cf_64, t1, tmp);
673         tcg_gen_trunc_i64_i32(cpu_CF, cf_64);
674         gen_set_NZ64(result);
675
676         tcg_gen_xor_i64(vf_64, result, t0);
677         tcg_gen_xor_i64(tmp, t0, t1);
678         tcg_gen_andc_i64(vf_64, vf_64, tmp);
679         tcg_gen_shri_i64(vf_64, vf_64, 32);
680         tcg_gen_trunc_i64_i32(cpu_VF, vf_64);
681
682         tcg_gen_mov_i64(dest, result);
683
684         tcg_temp_free_i64(tmp);
685         tcg_temp_free_i64(vf_64);
686         tcg_temp_free_i64(cf_64);
687         tcg_temp_free_i64(result);
688     } else {
689         TCGv_i32 t0_32, t1_32, tmp;
690         t0_32 = tcg_temp_new_i32();
691         t1_32 = tcg_temp_new_i32();
692         tmp = tcg_const_i32(0);
693
694         tcg_gen_trunc_i64_i32(t0_32, t0);
695         tcg_gen_trunc_i64_i32(t1_32, t1);
696         tcg_gen_add2_i32(cpu_NF, cpu_CF, t0_32, tmp, cpu_CF, tmp);
697         tcg_gen_add2_i32(cpu_NF, cpu_CF, cpu_NF, cpu_CF, t1_32, tmp);
698
699         tcg_gen_mov_i32(cpu_ZF, cpu_NF);
700         tcg_gen_xor_i32(cpu_VF, cpu_NF, t0_32);
701         tcg_gen_xor_i32(tmp, t0_32, t1_32);
702         tcg_gen_andc_i32(cpu_VF, cpu_VF, tmp);
703         tcg_gen_extu_i32_i64(dest, cpu_NF);
704
705         tcg_temp_free_i32(tmp);
706         tcg_temp_free_i32(t1_32);
707         tcg_temp_free_i32(t0_32);
708     }
709 }
710
711 /*
712  * Load/Store generators
713  */
714
715 /*
716  * Store from GPR register to memory.
717  */
718 static void do_gpr_st_memidx(DisasContext *s, TCGv_i64 source,
719                              TCGv_i64 tcg_addr, int size, int memidx)
720 {
721     g_assert(size <= 3);
722     tcg_gen_qemu_st_i64(source, tcg_addr, memidx, MO_TE + size);
723 }
724
725 static void do_gpr_st(DisasContext *s, TCGv_i64 source,
726                       TCGv_i64 tcg_addr, int size)
727 {
728     do_gpr_st_memidx(s, source, tcg_addr, size, get_mem_index(s));
729 }
730
731 /*
732  * Load from memory to GPR register
733  */
734 static void do_gpr_ld_memidx(DisasContext *s, TCGv_i64 dest, TCGv_i64 tcg_addr,
735                              int size, bool is_signed, bool extend, int memidx)
736 {
737     TCGMemOp memop = MO_TE + size;
738
739     g_assert(size <= 3);
740
741     if (is_signed) {
742         memop += MO_SIGN;
743     }
744
745     tcg_gen_qemu_ld_i64(dest, tcg_addr, memidx, memop);
746
747     if (extend && is_signed) {
748         g_assert(size < 3);
749         tcg_gen_ext32u_i64(dest, dest);
750     }
751 }
752
753 static void do_gpr_ld(DisasContext *s, TCGv_i64 dest, TCGv_i64 tcg_addr,
754                       int size, bool is_signed, bool extend)
755 {
756     do_gpr_ld_memidx(s, dest, tcg_addr, size, is_signed, extend,
757                      get_mem_index(s));
758 }
759
760 /*
761  * Store from FP register to memory
762  */
763 static void do_fp_st(DisasContext *s, int srcidx, TCGv_i64 tcg_addr, int size)
764 {
765     /* This writes the bottom N bits of a 128 bit wide vector to memory */
766     TCGv_i64 tmp = tcg_temp_new_i64();
767     tcg_gen_ld_i64(tmp, cpu_env, fp_reg_offset(s, srcidx, MO_64));
768     if (size < 4) {
769         tcg_gen_qemu_st_i64(tmp, tcg_addr, get_mem_index(s), MO_TE + size);
770     } else {
771         TCGv_i64 tcg_hiaddr = tcg_temp_new_i64();
772         tcg_gen_qemu_st_i64(tmp, tcg_addr, get_mem_index(s), MO_TEQ);
773         tcg_gen_ld_i64(tmp, cpu_env, fp_reg_hi_offset(s, srcidx));
774         tcg_gen_addi_i64(tcg_hiaddr, tcg_addr, 8);
775         tcg_gen_qemu_st_i64(tmp, tcg_hiaddr, get_mem_index(s), MO_TEQ);
776         tcg_temp_free_i64(tcg_hiaddr);
777     }
778
779     tcg_temp_free_i64(tmp);
780 }
781
782 /*
783  * Load from memory to FP register
784  */
785 static void do_fp_ld(DisasContext *s, int destidx, TCGv_i64 tcg_addr, int size)
786 {
787     /* This always zero-extends and writes to a full 128 bit wide vector */
788     TCGv_i64 tmplo = tcg_temp_new_i64();
789     TCGv_i64 tmphi;
790
791     if (size < 4) {
792         TCGMemOp memop = MO_TE + size;
793         tmphi = tcg_const_i64(0);
794         tcg_gen_qemu_ld_i64(tmplo, tcg_addr, get_mem_index(s), memop);
795     } else {
796         TCGv_i64 tcg_hiaddr;
797         tmphi = tcg_temp_new_i64();
798         tcg_hiaddr = tcg_temp_new_i64();
799
800         tcg_gen_qemu_ld_i64(tmplo, tcg_addr, get_mem_index(s), MO_TEQ);
801         tcg_gen_addi_i64(tcg_hiaddr, tcg_addr, 8);
802         tcg_gen_qemu_ld_i64(tmphi, tcg_hiaddr, get_mem_index(s), MO_TEQ);
803         tcg_temp_free_i64(tcg_hiaddr);
804     }
805
806     tcg_gen_st_i64(tmplo, cpu_env, fp_reg_offset(s, destidx, MO_64));
807     tcg_gen_st_i64(tmphi, cpu_env, fp_reg_hi_offset(s, destidx));
808
809     tcg_temp_free_i64(tmplo);
810     tcg_temp_free_i64(tmphi);
811 }
812
813 /*
814  * Vector load/store helpers.
815  *
816  * The principal difference between this and a FP load is that we don't
817  * zero extend as we are filling a partial chunk of the vector register.
818  * These functions don't support 128 bit loads/stores, which would be
819  * normal load/store operations.
820  *
821  * The _i32 versions are useful when operating on 32 bit quantities
822  * (eg for floating point single or using Neon helper functions).
823  */
824
825 /* Get value of an element within a vector register */
826 static void read_vec_element(DisasContext *s, TCGv_i64 tcg_dest, int srcidx,
827                              int element, TCGMemOp memop)
828 {
829     int vect_off = vec_reg_offset(s, srcidx, element, memop & MO_SIZE);
830     switch (memop) {
831     case MO_8:
832         tcg_gen_ld8u_i64(tcg_dest, cpu_env, vect_off);
833         break;
834     case MO_16:
835         tcg_gen_ld16u_i64(tcg_dest, cpu_env, vect_off);
836         break;
837     case MO_32:
838         tcg_gen_ld32u_i64(tcg_dest, cpu_env, vect_off);
839         break;
840     case MO_8|MO_SIGN:
841         tcg_gen_ld8s_i64(tcg_dest, cpu_env, vect_off);
842         break;
843     case MO_16|MO_SIGN:
844         tcg_gen_ld16s_i64(tcg_dest, cpu_env, vect_off);
845         break;
846     case MO_32|MO_SIGN:
847         tcg_gen_ld32s_i64(tcg_dest, cpu_env, vect_off);
848         break;
849     case MO_64:
850     case MO_64|MO_SIGN:
851         tcg_gen_ld_i64(tcg_dest, cpu_env, vect_off);
852         break;
853     default:
854         g_assert_not_reached();
855     }
856 }
857
858 static void read_vec_element_i32(DisasContext *s, TCGv_i32 tcg_dest, int srcidx,
859                                  int element, TCGMemOp memop)
860 {
861     int vect_off = vec_reg_offset(s, srcidx, element, memop & MO_SIZE);
862     switch (memop) {
863     case MO_8:
864         tcg_gen_ld8u_i32(tcg_dest, cpu_env, vect_off);
865         break;
866     case MO_16:
867         tcg_gen_ld16u_i32(tcg_dest, cpu_env, vect_off);
868         break;
869     case MO_8|MO_SIGN:
870         tcg_gen_ld8s_i32(tcg_dest, cpu_env, vect_off);
871         break;
872     case MO_16|MO_SIGN:
873         tcg_gen_ld16s_i32(tcg_dest, cpu_env, vect_off);
874         break;
875     case MO_32:
876     case MO_32|MO_SIGN:
877         tcg_gen_ld_i32(tcg_dest, cpu_env, vect_off);
878         break;
879     default:
880         g_assert_not_reached();
881     }
882 }
883
884 /* Set value of an element within a vector register */
885 static void write_vec_element(DisasContext *s, TCGv_i64 tcg_src, int destidx,
886                               int element, TCGMemOp memop)
887 {
888     int vect_off = vec_reg_offset(s, destidx, element, memop & MO_SIZE);
889     switch (memop) {
890     case MO_8:
891         tcg_gen_st8_i64(tcg_src, cpu_env, vect_off);
892         break;
893     case MO_16:
894         tcg_gen_st16_i64(tcg_src, cpu_env, vect_off);
895         break;
896     case MO_32:
897         tcg_gen_st32_i64(tcg_src, cpu_env, vect_off);
898         break;
899     case MO_64:
900         tcg_gen_st_i64(tcg_src, cpu_env, vect_off);
901         break;
902     default:
903         g_assert_not_reached();
904     }
905 }
906
907 static void write_vec_element_i32(DisasContext *s, TCGv_i32 tcg_src,
908                                   int destidx, int element, TCGMemOp memop)
909 {
910     int vect_off = vec_reg_offset(s, destidx, element, memop & MO_SIZE);
911     switch (memop) {
912     case MO_8:
913         tcg_gen_st8_i32(tcg_src, cpu_env, vect_off);
914         break;
915     case MO_16:
916         tcg_gen_st16_i32(tcg_src, cpu_env, vect_off);
917         break;
918     case MO_32:
919         tcg_gen_st_i32(tcg_src, cpu_env, vect_off);
920         break;
921     default:
922         g_assert_not_reached();
923     }
924 }
925
926 /* Clear the high 64 bits of a 128 bit vector (in general non-quad
927  * vector ops all need to do this).
928  */
929 static void clear_vec_high(DisasContext *s, int rd)
930 {
931     TCGv_i64 tcg_zero = tcg_const_i64(0);
932
933     write_vec_element(s, tcg_zero, rd, 1, MO_64);
934     tcg_temp_free_i64(tcg_zero);
935 }
936
937 /* Store from vector register to memory */
938 static void do_vec_st(DisasContext *s, int srcidx, int element,
939                       TCGv_i64 tcg_addr, int size)
940 {
941     TCGMemOp memop = MO_TE + size;
942     TCGv_i64 tcg_tmp = tcg_temp_new_i64();
943
944     read_vec_element(s, tcg_tmp, srcidx, element, size);
945     tcg_gen_qemu_st_i64(tcg_tmp, tcg_addr, get_mem_index(s), memop);
946
947     tcg_temp_free_i64(tcg_tmp);
948 }
949
950 /* Load from memory to vector register */
951 static void do_vec_ld(DisasContext *s, int destidx, int element,
952                       TCGv_i64 tcg_addr, int size)
953 {
954     TCGMemOp memop = MO_TE + size;
955     TCGv_i64 tcg_tmp = tcg_temp_new_i64();
956
957     tcg_gen_qemu_ld_i64(tcg_tmp, tcg_addr, get_mem_index(s), memop);
958     write_vec_element(s, tcg_tmp, destidx, element, size);
959
960     tcg_temp_free_i64(tcg_tmp);
961 }
962
963 /* Check that FP/Neon access is enabled. If it is, return
964  * true. If not, emit code to generate an appropriate exception,
965  * and return false; the caller should not emit any code for
966  * the instruction. Note that this check must happen after all
967  * unallocated-encoding checks (otherwise the syndrome information
968  * for the resulting exception will be incorrect).
969  */
970 static inline bool fp_access_check(DisasContext *s)
971 {
972     assert(!s->fp_access_checked);
973     s->fp_access_checked = true;
974
975     if (!s->fp_excp_el) {
976         return true;
977     }
978
979     gen_exception_insn(s, 4, EXCP_UDEF, syn_fp_access_trap(1, 0xe, false),
980                        s->fp_excp_el);
981     return false;
982 }
983
984 /*
985  * This utility function is for doing register extension with an
986  * optional shift. You will likely want to pass a temporary for the
987  * destination register. See DecodeRegExtend() in the ARM ARM.
988  */
989 static void ext_and_shift_reg(TCGv_i64 tcg_out, TCGv_i64 tcg_in,
990                               int option, unsigned int shift)
991 {
992     int extsize = extract32(option, 0, 2);
993     bool is_signed = extract32(option, 2, 1);
994
995     if (is_signed) {
996         switch (extsize) {
997         case 0:
998             tcg_gen_ext8s_i64(tcg_out, tcg_in);
999             break;
1000         case 1:
1001             tcg_gen_ext16s_i64(tcg_out, tcg_in);
1002             break;
1003         case 2:
1004             tcg_gen_ext32s_i64(tcg_out, tcg_in);
1005             break;
1006         case 3:
1007             tcg_gen_mov_i64(tcg_out, tcg_in);
1008             break;
1009         }
1010     } else {
1011         switch (extsize) {
1012         case 0:
1013             tcg_gen_ext8u_i64(tcg_out, tcg_in);
1014             break;
1015         case 1:
1016             tcg_gen_ext16u_i64(tcg_out, tcg_in);
1017             break;
1018         case 2:
1019             tcg_gen_ext32u_i64(tcg_out, tcg_in);
1020             break;
1021         case 3:
1022             tcg_gen_mov_i64(tcg_out, tcg_in);
1023             break;
1024         }
1025     }
1026
1027     if (shift) {
1028         tcg_gen_shli_i64(tcg_out, tcg_out, shift);
1029     }
1030 }
1031
1032 static inline void gen_check_sp_alignment(DisasContext *s)
1033 {
1034     /* The AArch64 architecture mandates that (if enabled via PSTATE
1035      * or SCTLR bits) there is a check that SP is 16-aligned on every
1036      * SP-relative load or store (with an exception generated if it is not).
1037      * In line with general QEMU practice regarding misaligned accesses,
1038      * we omit these checks for the sake of guest program performance.
1039      * This function is provided as a hook so we can more easily add these
1040      * checks in future (possibly as a "favour catching guest program bugs
1041      * over speed" user selectable option).
1042      */
1043 }
1044
1045 /*
1046  * This provides a simple table based table lookup decoder. It is
1047  * intended to be used when the relevant bits for decode are too
1048  * awkwardly placed and switch/if based logic would be confusing and
1049  * deeply nested. Since it's a linear search through the table, tables
1050  * should be kept small.
1051  *
1052  * It returns the first handler where insn & mask == pattern, or
1053  * NULL if there is no match.
1054  * The table is terminated by an empty mask (i.e. 0)
1055  */
1056 static inline AArch64DecodeFn *lookup_disas_fn(const AArch64DecodeTable *table,
1057                                                uint32_t insn)
1058 {
1059     const AArch64DecodeTable *tptr = table;
1060
1061     while (tptr->mask) {
1062         if ((insn & tptr->mask) == tptr->pattern) {
1063             return tptr->disas_fn;
1064         }
1065         tptr++;
1066     }
1067     return NULL;
1068 }
1069
1070 /*
1071  * the instruction disassembly implemented here matches
1072  * the instruction encoding classifications in chapter 3 (C3)
1073  * of the ARM Architecture Reference Manual (DDI0487A_a)
1074  */
1075
1076 /* C3.2.7 Unconditional branch (immediate)
1077  *   31  30       26 25                                  0
1078  * +----+-----------+-------------------------------------+
1079  * | op | 0 0 1 0 1 |                 imm26               |
1080  * +----+-----------+-------------------------------------+
1081  */
1082 static void disas_uncond_b_imm(DisasContext *s, uint32_t insn)
1083 {
1084     uint64_t addr = s->pc + sextract32(insn, 0, 26) * 4 - 4;
1085
1086     if (insn & (1U << 31)) {
1087         /* C5.6.26 BL Branch with link */
1088         tcg_gen_movi_i64(cpu_reg(s, 30), s->pc);
1089     }
1090
1091     /* C5.6.20 B Branch / C5.6.26 BL Branch with link */
1092     gen_goto_tb(s, 0, addr);
1093 }
1094
1095 /* C3.2.1 Compare & branch (immediate)
1096  *   31  30         25  24  23                  5 4      0
1097  * +----+-------------+----+---------------------+--------+
1098  * | sf | 0 1 1 0 1 0 | op |         imm19       |   Rt   |
1099  * +----+-------------+----+---------------------+--------+
1100  */
1101 static void disas_comp_b_imm(DisasContext *s, uint32_t insn)
1102 {
1103     unsigned int sf, op, rt;
1104     uint64_t addr;
1105     TCGLabel *label_match;
1106     TCGv_i64 tcg_cmp;
1107
1108     sf = extract32(insn, 31, 1);
1109     op = extract32(insn, 24, 1); /* 0: CBZ; 1: CBNZ */
1110     rt = extract32(insn, 0, 5);
1111     addr = s->pc + sextract32(insn, 5, 19) * 4 - 4;
1112
1113     tcg_cmp = read_cpu_reg(s, rt, sf);
1114     label_match = gen_new_label();
1115
1116     tcg_gen_brcondi_i64(op ? TCG_COND_NE : TCG_COND_EQ,
1117                         tcg_cmp, 0, label_match);
1118
1119     gen_goto_tb(s, 0, s->pc);
1120     gen_set_label(label_match);
1121     gen_goto_tb(s, 1, addr);
1122 }
1123
1124 /* C3.2.5 Test & branch (immediate)
1125  *   31  30         25  24  23   19 18          5 4    0
1126  * +----+-------------+----+-------+-------------+------+
1127  * | b5 | 0 1 1 0 1 1 | op |  b40  |    imm14    |  Rt  |
1128  * +----+-------------+----+-------+-------------+------+
1129  */
1130 static void disas_test_b_imm(DisasContext *s, uint32_t insn)
1131 {
1132     unsigned int bit_pos, op, rt;
1133     uint64_t addr;
1134     TCGLabel *label_match;
1135     TCGv_i64 tcg_cmp;
1136
1137     bit_pos = (extract32(insn, 31, 1) << 5) | extract32(insn, 19, 5);
1138     op = extract32(insn, 24, 1); /* 0: TBZ; 1: TBNZ */
1139     addr = s->pc + sextract32(insn, 5, 14) * 4 - 4;
1140     rt = extract32(insn, 0, 5);
1141
1142     tcg_cmp = tcg_temp_new_i64();
1143     tcg_gen_andi_i64(tcg_cmp, cpu_reg(s, rt), (1ULL << bit_pos));
1144     label_match = gen_new_label();
1145     tcg_gen_brcondi_i64(op ? TCG_COND_NE : TCG_COND_EQ,
1146                         tcg_cmp, 0, label_match);
1147     tcg_temp_free_i64(tcg_cmp);
1148     gen_goto_tb(s, 0, s->pc);
1149     gen_set_label(label_match);
1150     gen_goto_tb(s, 1, addr);
1151 }
1152
1153 /* C3.2.2 / C5.6.19 Conditional branch (immediate)
1154  *  31           25  24  23                  5   4  3    0
1155  * +---------------+----+---------------------+----+------+
1156  * | 0 1 0 1 0 1 0 | o1 |         imm19       | o0 | cond |
1157  * +---------------+----+---------------------+----+------+
1158  */
1159 static void disas_cond_b_imm(DisasContext *s, uint32_t insn)
1160 {
1161     unsigned int cond;
1162     uint64_t addr;
1163
1164     if ((insn & (1 << 4)) || (insn & (1 << 24))) {
1165         unallocated_encoding(s);
1166         return;
1167     }
1168     addr = s->pc + sextract32(insn, 5, 19) * 4 - 4;
1169     cond = extract32(insn, 0, 4);
1170
1171     if (cond < 0x0e) {
1172         /* genuinely conditional branches */
1173         TCGLabel *label_match = gen_new_label();
1174         arm_gen_test_cc(cond, label_match);
1175         gen_goto_tb(s, 0, s->pc);
1176         gen_set_label(label_match);
1177         gen_goto_tb(s, 1, addr);
1178     } else {
1179         /* 0xe and 0xf are both "always" conditions */
1180         gen_goto_tb(s, 0, addr);
1181     }
1182 }
1183
1184 /* C5.6.68 HINT */
1185 static void handle_hint(DisasContext *s, uint32_t insn,
1186                         unsigned int op1, unsigned int op2, unsigned int crm)
1187 {
1188     unsigned int selector = crm << 3 | op2;
1189
1190     if (op1 != 3) {
1191         unallocated_encoding(s);
1192         return;
1193     }
1194
1195     switch (selector) {
1196     case 0: /* NOP */
1197         return;
1198     case 3: /* WFI */
1199         s->is_jmp = DISAS_WFI;
1200         return;
1201     case 1: /* YIELD */
1202         s->is_jmp = DISAS_YIELD;
1203         return;
1204     case 2: /* WFE */
1205         s->is_jmp = DISAS_WFE;
1206         return;
1207     case 4: /* SEV */
1208     case 5: /* SEVL */
1209         /* we treat all as NOP at least for now */
1210         return;
1211     default:
1212         /* default specified as NOP equivalent */
1213         return;
1214     }
1215 }
1216
1217 static void gen_clrex(DisasContext *s, uint32_t insn)
1218 {
1219     tcg_gen_movi_i64(cpu_exclusive_addr, -1);
1220 }
1221
1222 /* CLREX, DSB, DMB, ISB */
1223 static void handle_sync(DisasContext *s, uint32_t insn,
1224                         unsigned int op1, unsigned int op2, unsigned int crm)
1225 {
1226     if (op1 != 3) {
1227         unallocated_encoding(s);
1228         return;
1229     }
1230
1231     switch (op2) {
1232     case 2: /* CLREX */
1233         gen_clrex(s, insn);
1234         return;
1235     case 4: /* DSB */
1236     case 5: /* DMB */
1237     case 6: /* ISB */
1238         /* We don't emulate caches so barriers are no-ops */
1239         return;
1240     default:
1241         unallocated_encoding(s);
1242         return;
1243     }
1244 }
1245
1246 /* C5.6.130 MSR (immediate) - move immediate to processor state field */
1247 static void handle_msr_i(DisasContext *s, uint32_t insn,
1248                          unsigned int op1, unsigned int op2, unsigned int crm)
1249 {
1250     int op = op1 << 3 | op2;
1251     switch (op) {
1252     case 0x05: /* SPSel */
1253         if (s->current_el == 0) {
1254             unallocated_encoding(s);
1255             return;
1256         }
1257         /* fall through */
1258     case 0x1e: /* DAIFSet */
1259     case 0x1f: /* DAIFClear */
1260     {
1261         TCGv_i32 tcg_imm = tcg_const_i32(crm);
1262         TCGv_i32 tcg_op = tcg_const_i32(op);
1263         gen_a64_set_pc_im(s->pc - 4);
1264         gen_helper_msr_i_pstate(cpu_env, tcg_op, tcg_imm);
1265         tcg_temp_free_i32(tcg_imm);
1266         tcg_temp_free_i32(tcg_op);
1267         s->is_jmp = DISAS_UPDATE;
1268         break;
1269     }
1270     default:
1271         unallocated_encoding(s);
1272         return;
1273     }
1274 }
1275
1276 static void gen_get_nzcv(TCGv_i64 tcg_rt)
1277 {
1278     TCGv_i32 tmp = tcg_temp_new_i32();
1279     TCGv_i32 nzcv = tcg_temp_new_i32();
1280
1281     /* build bit 31, N */
1282     tcg_gen_andi_i32(nzcv, cpu_NF, (1U << 31));
1283     /* build bit 30, Z */
1284     tcg_gen_setcondi_i32(TCG_COND_EQ, tmp, cpu_ZF, 0);
1285     tcg_gen_deposit_i32(nzcv, nzcv, tmp, 30, 1);
1286     /* build bit 29, C */
1287     tcg_gen_deposit_i32(nzcv, nzcv, cpu_CF, 29, 1);
1288     /* build bit 28, V */
1289     tcg_gen_shri_i32(tmp, cpu_VF, 31);
1290     tcg_gen_deposit_i32(nzcv, nzcv, tmp, 28, 1);
1291     /* generate result */
1292     tcg_gen_extu_i32_i64(tcg_rt, nzcv);
1293
1294     tcg_temp_free_i32(nzcv);
1295     tcg_temp_free_i32(tmp);
1296 }
1297
1298 static void gen_set_nzcv(TCGv_i64 tcg_rt)
1299
1300 {
1301     TCGv_i32 nzcv = tcg_temp_new_i32();
1302
1303     /* take NZCV from R[t] */
1304     tcg_gen_trunc_i64_i32(nzcv, tcg_rt);
1305
1306     /* bit 31, N */
1307     tcg_gen_andi_i32(cpu_NF, nzcv, (1U << 31));
1308     /* bit 30, Z */
1309     tcg_gen_andi_i32(cpu_ZF, nzcv, (1 << 30));
1310     tcg_gen_setcondi_i32(TCG_COND_EQ, cpu_ZF, cpu_ZF, 0);
1311     /* bit 29, C */
1312     tcg_gen_andi_i32(cpu_CF, nzcv, (1 << 29));
1313     tcg_gen_shri_i32(cpu_CF, cpu_CF, 29);
1314     /* bit 28, V */
1315     tcg_gen_andi_i32(cpu_VF, nzcv, (1 << 28));
1316     tcg_gen_shli_i32(cpu_VF, cpu_VF, 3);
1317     tcg_temp_free_i32(nzcv);
1318 }
1319
1320 /* C5.6.129 MRS - move from system register
1321  * C5.6.131 MSR (register) - move to system register
1322  * C5.6.204 SYS
1323  * C5.6.205 SYSL
1324  * These are all essentially the same insn in 'read' and 'write'
1325  * versions, with varying op0 fields.
1326  */
1327 static void handle_sys(DisasContext *s, uint32_t insn, bool isread,
1328                        unsigned int op0, unsigned int op1, unsigned int op2,
1329                        unsigned int crn, unsigned int crm, unsigned int rt)
1330 {
1331     const ARMCPRegInfo *ri;
1332     TCGv_i64 tcg_rt;
1333
1334     ri = get_arm_cp_reginfo(s->cp_regs,
1335                             ENCODE_AA64_CP_REG(CP_REG_ARM64_SYSREG_CP,
1336                                                crn, crm, op0, op1, op2));
1337
1338     if (!ri) {
1339         /* Unknown register; this might be a guest error or a QEMU
1340          * unimplemented feature.
1341          */
1342         qemu_log_mask(LOG_UNIMP, "%s access to unsupported AArch64 "
1343                       "system register op0:%d op1:%d crn:%d crm:%d op2:%d\n",
1344                       isread ? "read" : "write", op0, op1, crn, crm, op2);
1345         unallocated_encoding(s);
1346         return;
1347     }
1348
1349     /* Check access permissions */
1350     if (!cp_access_ok(s->current_el, ri, isread)) {
1351         unallocated_encoding(s);
1352         return;
1353     }
1354
1355     if (ri->accessfn) {
1356         /* Emit code to perform further access permissions checks at
1357          * runtime; this may result in an exception.
1358          */
1359         TCGv_ptr tmpptr;
1360         TCGv_i32 tcg_syn;
1361         uint32_t syndrome;
1362
1363         gen_a64_set_pc_im(s->pc - 4);
1364         tmpptr = tcg_const_ptr(ri);
1365         syndrome = syn_aa64_sysregtrap(op0, op1, op2, crn, crm, rt, isread);
1366         tcg_syn = tcg_const_i32(syndrome);
1367         gen_helper_access_check_cp_reg(cpu_env, tmpptr, tcg_syn);
1368         tcg_temp_free_ptr(tmpptr);
1369         tcg_temp_free_i32(tcg_syn);
1370     }
1371
1372     /* Handle special cases first */
1373     switch (ri->type & ~(ARM_CP_FLAG_MASK & ~ARM_CP_SPECIAL)) {
1374     case ARM_CP_NOP:
1375         return;
1376     case ARM_CP_NZCV:
1377         tcg_rt = cpu_reg(s, rt);
1378         if (isread) {
1379             gen_get_nzcv(tcg_rt);
1380         } else {
1381             gen_set_nzcv(tcg_rt);
1382         }
1383         return;
1384     case ARM_CP_CURRENTEL:
1385         /* Reads as current EL value from pstate, which is
1386          * guaranteed to be constant by the tb flags.
1387          */
1388         tcg_rt = cpu_reg(s, rt);
1389         tcg_gen_movi_i64(tcg_rt, s->current_el << 2);
1390         return;
1391     case ARM_CP_DC_ZVA:
1392         /* Writes clear the aligned block of memory which rt points into. */
1393         tcg_rt = cpu_reg(s, rt);
1394         gen_helper_dc_zva(cpu_env, tcg_rt);
1395         return;
1396     default:
1397         break;
1398     }
1399
1400     if ((s->tb->cflags & CF_USE_ICOUNT) && (ri->type & ARM_CP_IO)) {
1401         gen_io_start();
1402     }
1403
1404     tcg_rt = cpu_reg(s, rt);
1405
1406     if (isread) {
1407         if (ri->type & ARM_CP_CONST) {
1408             tcg_gen_movi_i64(tcg_rt, ri->resetvalue);
1409         } else if (ri->readfn) {
1410             TCGv_ptr tmpptr;
1411             tmpptr = tcg_const_ptr(ri);
1412             gen_helper_get_cp_reg64(tcg_rt, cpu_env, tmpptr);
1413             tcg_temp_free_ptr(tmpptr);
1414         } else {
1415             tcg_gen_ld_i64(tcg_rt, cpu_env, ri->fieldoffset);
1416         }
1417     } else {
1418         if (ri->type & ARM_CP_CONST) {
1419             /* If not forbidden by access permissions, treat as WI */
1420             return;
1421         } else if (ri->writefn) {
1422             TCGv_ptr tmpptr;
1423             tmpptr = tcg_const_ptr(ri);
1424             gen_helper_set_cp_reg64(cpu_env, tmpptr, tcg_rt);
1425             tcg_temp_free_ptr(tmpptr);
1426         } else {
1427             tcg_gen_st_i64(tcg_rt, cpu_env, ri->fieldoffset);
1428         }
1429     }
1430
1431     if ((s->tb->cflags & CF_USE_ICOUNT) && (ri->type & ARM_CP_IO)) {
1432         /* I/O operations must end the TB here (whether read or write) */
1433         gen_io_end();
1434         s->is_jmp = DISAS_UPDATE;
1435     } else if (!isread && !(ri->type & ARM_CP_SUPPRESS_TB_END)) {
1436         /* We default to ending the TB on a coprocessor register write,
1437          * but allow this to be suppressed by the register definition
1438          * (usually only necessary to work around guest bugs).
1439          */
1440         s->is_jmp = DISAS_UPDATE;
1441     }
1442 }
1443
1444 /* C3.2.4 System
1445  *  31                 22 21  20 19 18 16 15   12 11    8 7   5 4    0
1446  * +---------------------+---+-----+-----+-------+-------+-----+------+
1447  * | 1 1 0 1 0 1 0 1 0 0 | L | op0 | op1 |  CRn  |  CRm  | op2 |  Rt  |
1448  * +---------------------+---+-----+-----+-------+-------+-----+------+
1449  */
1450 static void disas_system(DisasContext *s, uint32_t insn)
1451 {
1452     unsigned int l, op0, op1, crn, crm, op2, rt;
1453     l = extract32(insn, 21, 1);
1454     op0 = extract32(insn, 19, 2);
1455     op1 = extract32(insn, 16, 3);
1456     crn = extract32(insn, 12, 4);
1457     crm = extract32(insn, 8, 4);
1458     op2 = extract32(insn, 5, 3);
1459     rt = extract32(insn, 0, 5);
1460
1461     if (op0 == 0) {
1462         if (l || rt != 31) {
1463             unallocated_encoding(s);
1464             return;
1465         }
1466         switch (crn) {
1467         case 2: /* C5.6.68 HINT */
1468             handle_hint(s, insn, op1, op2, crm);
1469             break;
1470         case 3: /* CLREX, DSB, DMB, ISB */
1471             handle_sync(s, insn, op1, op2, crm);
1472             break;
1473         case 4: /* C5.6.130 MSR (immediate) */
1474             handle_msr_i(s, insn, op1, op2, crm);
1475             break;
1476         default:
1477             unallocated_encoding(s);
1478             break;
1479         }
1480         return;
1481     }
1482     handle_sys(s, insn, l, op0, op1, op2, crn, crm, rt);
1483 }
1484
1485 /* C3.2.3 Exception generation
1486  *
1487  *  31             24 23 21 20                     5 4   2 1  0
1488  * +-----------------+-----+------------------------+-----+----+
1489  * | 1 1 0 1 0 1 0 0 | opc |          imm16         | op2 | LL |
1490  * +-----------------------+------------------------+----------+
1491  */
1492 static void disas_exc(DisasContext *s, uint32_t insn)
1493 {
1494     int opc = extract32(insn, 21, 3);
1495     int op2_ll = extract32(insn, 0, 5);
1496     int imm16 = extract32(insn, 5, 16);
1497     TCGv_i32 tmp;
1498
1499     switch (opc) {
1500     case 0:
1501         /* For SVC, HVC and SMC we advance the single-step state
1502          * machine before taking the exception. This is architecturally
1503          * mandated, to ensure that single-stepping a system call
1504          * instruction works properly.
1505          */
1506         switch (op2_ll) {
1507         case 1:
1508             gen_ss_advance(s);
1509             gen_exception_insn(s, 0, EXCP_SWI, syn_aa64_svc(imm16),
1510                                default_exception_el(s));
1511             break;
1512         case 2:
1513             if (s->current_el == 0) {
1514                 unallocated_encoding(s);
1515                 break;
1516             }
1517             /* The pre HVC helper handles cases when HVC gets trapped
1518              * as an undefined insn by runtime configuration.
1519              */
1520             gen_a64_set_pc_im(s->pc - 4);
1521             gen_helper_pre_hvc(cpu_env);
1522             gen_ss_advance(s);
1523             gen_exception_insn(s, 0, EXCP_HVC, syn_aa64_hvc(imm16), 2);
1524             break;
1525         case 3:
1526             if (s->current_el == 0) {
1527                 unallocated_encoding(s);
1528                 break;
1529             }
1530             gen_a64_set_pc_im(s->pc - 4);
1531             tmp = tcg_const_i32(syn_aa64_smc(imm16));
1532             gen_helper_pre_smc(cpu_env, tmp);
1533             tcg_temp_free_i32(tmp);
1534             gen_ss_advance(s);
1535             gen_exception_insn(s, 0, EXCP_SMC, syn_aa64_smc(imm16), 3);
1536             break;
1537         default:
1538             unallocated_encoding(s);
1539             break;
1540         }
1541         break;
1542     case 1:
1543         if (op2_ll != 0) {
1544             unallocated_encoding(s);
1545             break;
1546         }
1547         /* BRK */
1548         gen_exception_insn(s, 4, EXCP_BKPT, syn_aa64_bkpt(imm16),
1549                            default_exception_el(s));
1550         break;
1551     case 2:
1552         if (op2_ll != 0) {
1553             unallocated_encoding(s);
1554             break;
1555         }
1556         /* HLT */
1557         unsupported_encoding(s, insn);
1558         break;
1559     case 5:
1560         if (op2_ll < 1 || op2_ll > 3) {
1561             unallocated_encoding(s);
1562             break;
1563         }
1564         /* DCPS1, DCPS2, DCPS3 */
1565         unsupported_encoding(s, insn);
1566         break;
1567     default:
1568         unallocated_encoding(s);
1569         break;
1570     }
1571 }
1572
1573 /* C3.2.7 Unconditional branch (register)
1574  *  31           25 24   21 20   16 15   10 9    5 4     0
1575  * +---------------+-------+-------+-------+------+-------+
1576  * | 1 1 0 1 0 1 1 |  opc  |  op2  |  op3  |  Rn  |  op4  |
1577  * +---------------+-------+-------+-------+------+-------+
1578  */
1579 static void disas_uncond_b_reg(DisasContext *s, uint32_t insn)
1580 {
1581     unsigned int opc, op2, op3, rn, op4;
1582
1583     opc = extract32(insn, 21, 4);
1584     op2 = extract32(insn, 16, 5);
1585     op3 = extract32(insn, 10, 6);
1586     rn = extract32(insn, 5, 5);
1587     op4 = extract32(insn, 0, 5);
1588
1589     if (op4 != 0x0 || op3 != 0x0 || op2 != 0x1f) {
1590         unallocated_encoding(s);
1591         return;
1592     }
1593
1594     switch (opc) {
1595     case 0: /* BR */
1596     case 2: /* RET */
1597         tcg_gen_mov_i64(cpu_pc, cpu_reg(s, rn));
1598         break;
1599     case 1: /* BLR */
1600         tcg_gen_mov_i64(cpu_pc, cpu_reg(s, rn));
1601         tcg_gen_movi_i64(cpu_reg(s, 30), s->pc);
1602         break;
1603     case 4: /* ERET */
1604         if (s->current_el == 0) {
1605             unallocated_encoding(s);
1606             return;
1607         }
1608         gen_helper_exception_return(cpu_env);
1609         s->is_jmp = DISAS_JUMP;
1610         return;
1611     case 5: /* DRPS */
1612         if (rn != 0x1f) {
1613             unallocated_encoding(s);
1614         } else {
1615             unsupported_encoding(s, insn);
1616         }
1617         return;
1618     default:
1619         unallocated_encoding(s);
1620         return;
1621     }
1622
1623     s->is_jmp = DISAS_JUMP;
1624 }
1625
1626 /* C3.2 Branches, exception generating and system instructions */
1627 static void disas_b_exc_sys(DisasContext *s, uint32_t insn)
1628 {
1629     switch (extract32(insn, 25, 7)) {
1630     case 0x0a: case 0x0b:
1631     case 0x4a: case 0x4b: /* Unconditional branch (immediate) */
1632         disas_uncond_b_imm(s, insn);
1633         break;
1634     case 0x1a: case 0x5a: /* Compare & branch (immediate) */
1635         disas_comp_b_imm(s, insn);
1636         break;
1637     case 0x1b: case 0x5b: /* Test & branch (immediate) */
1638         disas_test_b_imm(s, insn);
1639         break;
1640     case 0x2a: /* Conditional branch (immediate) */
1641         disas_cond_b_imm(s, insn);
1642         break;
1643     case 0x6a: /* Exception generation / System */
1644         if (insn & (1 << 24)) {
1645             disas_system(s, insn);
1646         } else {
1647             disas_exc(s, insn);
1648         }
1649         break;
1650     case 0x6b: /* Unconditional branch (register) */
1651         disas_uncond_b_reg(s, insn);
1652         break;
1653     default:
1654         unallocated_encoding(s);
1655         break;
1656     }
1657 }
1658
1659 /*
1660  * Load/Store exclusive instructions are implemented by remembering
1661  * the value/address loaded, and seeing if these are the same
1662  * when the store is performed. This is not actually the architecturally
1663  * mandated semantics, but it works for typical guest code sequences
1664  * and avoids having to monitor regular stores.
1665  *
1666  * In system emulation mode only one CPU will be running at once, so
1667  * this sequence is effectively atomic.  In user emulation mode we
1668  * throw an exception and handle the atomic operation elsewhere.
1669  */
1670 static void gen_load_exclusive(DisasContext *s, int rt, int rt2,
1671                                TCGv_i64 addr, int size, bool is_pair)
1672 {
1673     TCGv_i64 tmp = tcg_temp_new_i64();
1674     TCGMemOp memop = MO_TE + size;
1675
1676     g_assert(size <= 3);
1677     tcg_gen_qemu_ld_i64(tmp, addr, get_mem_index(s), memop);
1678
1679     if (is_pair) {
1680         TCGv_i64 addr2 = tcg_temp_new_i64();
1681         TCGv_i64 hitmp = tcg_temp_new_i64();
1682
1683         g_assert(size >= 2);
1684         tcg_gen_addi_i64(addr2, addr, 1 << size);
1685         tcg_gen_qemu_ld_i64(hitmp, addr2, get_mem_index(s), memop);
1686         tcg_temp_free_i64(addr2);
1687         tcg_gen_mov_i64(cpu_exclusive_high, hitmp);
1688         tcg_gen_mov_i64(cpu_reg(s, rt2), hitmp);
1689         tcg_temp_free_i64(hitmp);
1690     }
1691
1692     tcg_gen_mov_i64(cpu_exclusive_val, tmp);
1693     tcg_gen_mov_i64(cpu_reg(s, rt), tmp);
1694
1695     tcg_temp_free_i64(tmp);
1696     tcg_gen_mov_i64(cpu_exclusive_addr, addr);
1697 }
1698
1699 #ifdef CONFIG_USER_ONLY
1700 static void gen_store_exclusive(DisasContext *s, int rd, int rt, int rt2,
1701                                 TCGv_i64 addr, int size, int is_pair)
1702 {
1703     tcg_gen_mov_i64(cpu_exclusive_test, addr);
1704     tcg_gen_movi_i32(cpu_exclusive_info,
1705                      size | is_pair << 2 | (rd << 4) | (rt << 9) | (rt2 << 14));
1706     gen_exception_internal_insn(s, 4, EXCP_STREX);
1707 }
1708 #else
1709 static void gen_store_exclusive(DisasContext *s, int rd, int rt, int rt2,
1710                                 TCGv_i64 inaddr, int size, int is_pair)
1711 {
1712     /* if (env->exclusive_addr == addr && env->exclusive_val == [addr]
1713      *     && (!is_pair || env->exclusive_high == [addr + datasize])) {
1714      *     [addr] = {Rt};
1715      *     if (is_pair) {
1716      *         [addr + datasize] = {Rt2};
1717      *     }
1718      *     {Rd} = 0;
1719      * } else {
1720      *     {Rd} = 1;
1721      * }
1722      * env->exclusive_addr = -1;
1723      */
1724     TCGLabel *fail_label = gen_new_label();
1725     TCGLabel *done_label = gen_new_label();
1726     TCGv_i64 addr = tcg_temp_local_new_i64();
1727     TCGv_i64 tmp;
1728
1729     /* Copy input into a local temp so it is not trashed when the
1730      * basic block ends at the branch insn.
1731      */
1732     tcg_gen_mov_i64(addr, inaddr);
1733     tcg_gen_brcond_i64(TCG_COND_NE, addr, cpu_exclusive_addr, fail_label);
1734
1735     tmp = tcg_temp_new_i64();
1736     tcg_gen_qemu_ld_i64(tmp, addr, get_mem_index(s), MO_TE + size);
1737     tcg_gen_brcond_i64(TCG_COND_NE, tmp, cpu_exclusive_val, fail_label);
1738     tcg_temp_free_i64(tmp);
1739
1740     if (is_pair) {
1741         TCGv_i64 addrhi = tcg_temp_new_i64();
1742         TCGv_i64 tmphi = tcg_temp_new_i64();
1743
1744         tcg_gen_addi_i64(addrhi, addr, 1 << size);
1745         tcg_gen_qemu_ld_i64(tmphi, addrhi, get_mem_index(s), MO_TE + size);
1746         tcg_gen_brcond_i64(TCG_COND_NE, tmphi, cpu_exclusive_high, fail_label);
1747
1748         tcg_temp_free_i64(tmphi);
1749         tcg_temp_free_i64(addrhi);
1750     }
1751
1752     /* We seem to still have the exclusive monitor, so do the store */
1753     tcg_gen_qemu_st_i64(cpu_reg(s, rt), addr, get_mem_index(s), MO_TE + size);
1754     if (is_pair) {
1755         TCGv_i64 addrhi = tcg_temp_new_i64();
1756
1757         tcg_gen_addi_i64(addrhi, addr, 1 << size);
1758         tcg_gen_qemu_st_i64(cpu_reg(s, rt2), addrhi,
1759                             get_mem_index(s), MO_TE + size);
1760         tcg_temp_free_i64(addrhi);
1761     }
1762
1763     tcg_temp_free_i64(addr);
1764
1765     tcg_gen_movi_i64(cpu_reg(s, rd), 0);
1766     tcg_gen_br(done_label);
1767     gen_set_label(fail_label);
1768     tcg_gen_movi_i64(cpu_reg(s, rd), 1);
1769     gen_set_label(done_label);
1770     tcg_gen_movi_i64(cpu_exclusive_addr, -1);
1771
1772 }
1773 #endif
1774
1775 /* C3.3.6 Load/store exclusive
1776  *
1777  *  31 30 29         24  23  22   21  20  16  15  14   10 9    5 4    0
1778  * +-----+-------------+----+---+----+------+----+-------+------+------+
1779  * | sz  | 0 0 1 0 0 0 | o2 | L | o1 |  Rs  | o0 |  Rt2  |  Rn  | Rt   |
1780  * +-----+-------------+----+---+----+------+----+-------+------+------+
1781  *
1782  *  sz: 00 -> 8 bit, 01 -> 16 bit, 10 -> 32 bit, 11 -> 64 bit
1783  *   L: 0 -> store, 1 -> load
1784  *  o2: 0 -> exclusive, 1 -> not
1785  *  o1: 0 -> single register, 1 -> register pair
1786  *  o0: 1 -> load-acquire/store-release, 0 -> not
1787  *
1788  *  o0 == 0 AND o2 == 1 is un-allocated
1789  *  o1 == 1 is un-allocated except for 32 and 64 bit sizes
1790  */
1791 static void disas_ldst_excl(DisasContext *s, uint32_t insn)
1792 {
1793     int rt = extract32(insn, 0, 5);
1794     int rn = extract32(insn, 5, 5);
1795     int rt2 = extract32(insn, 10, 5);
1796     int is_lasr = extract32(insn, 15, 1);
1797     int rs = extract32(insn, 16, 5);
1798     int is_pair = extract32(insn, 21, 1);
1799     int is_store = !extract32(insn, 22, 1);
1800     int is_excl = !extract32(insn, 23, 1);
1801     int size = extract32(insn, 30, 2);
1802     TCGv_i64 tcg_addr;
1803
1804     if ((!is_excl && !is_lasr) ||
1805         (is_pair && size < 2)) {
1806         unallocated_encoding(s);
1807         return;
1808     }
1809
1810     if (rn == 31) {
1811         gen_check_sp_alignment(s);
1812     }
1813     tcg_addr = read_cpu_reg_sp(s, rn, 1);
1814
1815     /* Note that since TCG is single threaded load-acquire/store-release
1816      * semantics require no extra if (is_lasr) { ... } handling.
1817      */
1818
1819     if (is_excl) {
1820         if (!is_store) {
1821             s->is_ldex = true;
1822             gen_load_exclusive(s, rt, rt2, tcg_addr, size, is_pair);
1823         } else {
1824             gen_store_exclusive(s, rs, rt, rt2, tcg_addr, size, is_pair);
1825         }
1826     } else {
1827         TCGv_i64 tcg_rt = cpu_reg(s, rt);
1828         if (is_store) {
1829             do_gpr_st(s, tcg_rt, tcg_addr, size);
1830         } else {
1831             do_gpr_ld(s, tcg_rt, tcg_addr, size, false, false);
1832         }
1833         if (is_pair) {
1834             TCGv_i64 tcg_rt2 = cpu_reg(s, rt);
1835             tcg_gen_addi_i64(tcg_addr, tcg_addr, 1 << size);
1836             if (is_store) {
1837                 do_gpr_st(s, tcg_rt2, tcg_addr, size);
1838             } else {
1839                 do_gpr_ld(s, tcg_rt2, tcg_addr, size, false, false);
1840             }
1841         }
1842     }
1843 }
1844
1845 /*
1846  * C3.3.5 Load register (literal)
1847  *
1848  *  31 30 29   27  26 25 24 23                5 4     0
1849  * +-----+-------+---+-----+-------------------+-------+
1850  * | opc | 0 1 1 | V | 0 0 |     imm19         |  Rt   |
1851  * +-----+-------+---+-----+-------------------+-------+
1852  *
1853  * V: 1 -> vector (simd/fp)
1854  * opc (non-vector): 00 -> 32 bit, 01 -> 64 bit,
1855  *                   10-> 32 bit signed, 11 -> prefetch
1856  * opc (vector): 00 -> 32 bit, 01 -> 64 bit, 10 -> 128 bit (11 unallocated)
1857  */
1858 static void disas_ld_lit(DisasContext *s, uint32_t insn)
1859 {
1860     int rt = extract32(insn, 0, 5);
1861     int64_t imm = sextract32(insn, 5, 19) << 2;
1862     bool is_vector = extract32(insn, 26, 1);
1863     int opc = extract32(insn, 30, 2);
1864     bool is_signed = false;
1865     int size = 2;
1866     TCGv_i64 tcg_rt, tcg_addr;
1867
1868     if (is_vector) {
1869         if (opc == 3) {
1870             unallocated_encoding(s);
1871             return;
1872         }
1873         size = 2 + opc;
1874         if (!fp_access_check(s)) {
1875             return;
1876         }
1877     } else {
1878         if (opc == 3) {
1879             /* PRFM (literal) : prefetch */
1880             return;
1881         }
1882         size = 2 + extract32(opc, 0, 1);
1883         is_signed = extract32(opc, 1, 1);
1884     }
1885
1886     tcg_rt = cpu_reg(s, rt);
1887
1888     tcg_addr = tcg_const_i64((s->pc - 4) + imm);
1889     if (is_vector) {
1890         do_fp_ld(s, rt, tcg_addr, size);
1891     } else {
1892         do_gpr_ld(s, tcg_rt, tcg_addr, size, is_signed, false);
1893     }
1894     tcg_temp_free_i64(tcg_addr);
1895 }
1896
1897 /*
1898  * C5.6.80 LDNP (Load Pair - non-temporal hint)
1899  * C5.6.81 LDP (Load Pair - non vector)
1900  * C5.6.82 LDPSW (Load Pair Signed Word - non vector)
1901  * C5.6.176 STNP (Store Pair - non-temporal hint)
1902  * C5.6.177 STP (Store Pair - non vector)
1903  * C6.3.165 LDNP (Load Pair of SIMD&FP - non-temporal hint)
1904  * C6.3.165 LDP (Load Pair of SIMD&FP)
1905  * C6.3.284 STNP (Store Pair of SIMD&FP - non-temporal hint)
1906  * C6.3.284 STP (Store Pair of SIMD&FP)
1907  *
1908  *  31 30 29   27  26  25 24   23  22 21   15 14   10 9    5 4    0
1909  * +-----+-------+---+---+-------+---+-----------------------------+
1910  * | opc | 1 0 1 | V | 0 | index | L |  imm7 |  Rt2  |  Rn  | Rt   |
1911  * +-----+-------+---+---+-------+---+-------+-------+------+------+
1912  *
1913  * opc: LDP/STP/LDNP/STNP        00 -> 32 bit, 10 -> 64 bit
1914  *      LDPSW                    01
1915  *      LDP/STP/LDNP/STNP (SIMD) 00 -> 32 bit, 01 -> 64 bit, 10 -> 128 bit
1916  *   V: 0 -> GPR, 1 -> Vector
1917  * idx: 00 -> signed offset with non-temporal hint, 01 -> post-index,
1918  *      10 -> signed offset, 11 -> pre-index
1919  *   L: 0 -> Store 1 -> Load
1920  *
1921  * Rt, Rt2 = GPR or SIMD registers to be stored
1922  * Rn = general purpose register containing address
1923  * imm7 = signed offset (multiple of 4 or 8 depending on size)
1924  */
1925 static void disas_ldst_pair(DisasContext *s, uint32_t insn)
1926 {
1927     int rt = extract32(insn, 0, 5);
1928     int rn = extract32(insn, 5, 5);
1929     int rt2 = extract32(insn, 10, 5);
1930     uint64_t offset = sextract64(insn, 15, 7);
1931     int index = extract32(insn, 23, 2);
1932     bool is_vector = extract32(insn, 26, 1);
1933     bool is_load = extract32(insn, 22, 1);
1934     int opc = extract32(insn, 30, 2);
1935
1936     bool is_signed = false;
1937     bool postindex = false;
1938     bool wback = false;
1939
1940     TCGv_i64 tcg_addr; /* calculated address */
1941     int size;
1942
1943     if (opc == 3) {
1944         unallocated_encoding(s);
1945         return;
1946     }
1947
1948     if (is_vector) {
1949         size = 2 + opc;
1950     } else {
1951         size = 2 + extract32(opc, 1, 1);
1952         is_signed = extract32(opc, 0, 1);
1953         if (!is_load && is_signed) {
1954             unallocated_encoding(s);
1955             return;
1956         }
1957     }
1958
1959     switch (index) {
1960     case 1: /* post-index */
1961         postindex = true;
1962         wback = true;
1963         break;
1964     case 0:
1965         /* signed offset with "non-temporal" hint. Since we don't emulate
1966          * caches we don't care about hints to the cache system about
1967          * data access patterns, and handle this identically to plain
1968          * signed offset.
1969          */
1970         if (is_signed) {
1971             /* There is no non-temporal-hint version of LDPSW */
1972             unallocated_encoding(s);
1973             return;
1974         }
1975         postindex = false;
1976         break;
1977     case 2: /* signed offset, rn not updated */
1978         postindex = false;
1979         break;
1980     case 3: /* pre-index */
1981         postindex = false;
1982         wback = true;
1983         break;
1984     }
1985
1986     if (is_vector && !fp_access_check(s)) {
1987         return;
1988     }
1989
1990     offset <<= size;
1991
1992     if (rn == 31) {
1993         gen_check_sp_alignment(s);
1994     }
1995
1996     tcg_addr = read_cpu_reg_sp(s, rn, 1);
1997
1998     if (!postindex) {
1999         tcg_gen_addi_i64(tcg_addr, tcg_addr, offset);
2000     }
2001
2002     if (is_vector) {
2003         if (is_load) {
2004             do_fp_ld(s, rt, tcg_addr, size);
2005         } else {
2006             do_fp_st(s, rt, tcg_addr, size);
2007         }
2008     } else {
2009         TCGv_i64 tcg_rt = cpu_reg(s, rt);
2010         if (is_load) {
2011             do_gpr_ld(s, tcg_rt, tcg_addr, size, is_signed, false);
2012         } else {
2013             do_gpr_st(s, tcg_rt, tcg_addr, size);
2014         }
2015     }
2016     tcg_gen_addi_i64(tcg_addr, tcg_addr, 1 << size);
2017     if (is_vector) {
2018         if (is_load) {
2019             do_fp_ld(s, rt2, tcg_addr, size);
2020         } else {
2021             do_fp_st(s, rt2, tcg_addr, size);
2022         }
2023     } else {
2024         TCGv_i64 tcg_rt2 = cpu_reg(s, rt2);
2025         if (is_load) {
2026             do_gpr_ld(s, tcg_rt2, tcg_addr, size, is_signed, false);
2027         } else {
2028             do_gpr_st(s, tcg_rt2, tcg_addr, size);
2029         }
2030     }
2031
2032     if (wback) {
2033         if (postindex) {
2034             tcg_gen_addi_i64(tcg_addr, tcg_addr, offset - (1 << size));
2035         } else {
2036             tcg_gen_subi_i64(tcg_addr, tcg_addr, 1 << size);
2037         }
2038         tcg_gen_mov_i64(cpu_reg_sp(s, rn), tcg_addr);
2039     }
2040 }
2041
2042 /*
2043  * C3.3.8 Load/store (immediate post-indexed)
2044  * C3.3.9 Load/store (immediate pre-indexed)
2045  * C3.3.12 Load/store (unscaled immediate)
2046  *
2047  * 31 30 29   27  26 25 24 23 22 21  20    12 11 10 9    5 4    0
2048  * +----+-------+---+-----+-----+---+--------+-----+------+------+
2049  * |size| 1 1 1 | V | 0 0 | opc | 0 |  imm9  | idx |  Rn  |  Rt  |
2050  * +----+-------+---+-----+-----+---+--------+-----+------+------+
2051  *
2052  * idx = 01 -> post-indexed, 11 pre-indexed, 00 unscaled imm. (no writeback)
2053          10 -> unprivileged
2054  * V = 0 -> non-vector
2055  * size: 00 -> 8 bit, 01 -> 16 bit, 10 -> 32 bit, 11 -> 64bit
2056  * opc: 00 -> store, 01 -> loadu, 10 -> loads 64, 11 -> loads 32
2057  */
2058 static void disas_ldst_reg_imm9(DisasContext *s, uint32_t insn)
2059 {
2060     int rt = extract32(insn, 0, 5);
2061     int rn = extract32(insn, 5, 5);
2062     int imm9 = sextract32(insn, 12, 9);
2063     int opc = extract32(insn, 22, 2);
2064     int size = extract32(insn, 30, 2);
2065     int idx = extract32(insn, 10, 2);
2066     bool is_signed = false;
2067     bool is_store = false;
2068     bool is_extended = false;
2069     bool is_unpriv = (idx == 2);
2070     bool is_vector = extract32(insn, 26, 1);
2071     bool post_index;
2072     bool writeback;
2073
2074     TCGv_i64 tcg_addr;
2075
2076     if (is_vector) {
2077         size |= (opc & 2) << 1;
2078         if (size > 4 || is_unpriv) {
2079             unallocated_encoding(s);
2080             return;
2081         }
2082         is_store = ((opc & 1) == 0);
2083         if (!fp_access_check(s)) {
2084             return;
2085         }
2086     } else {
2087         if (size == 3 && opc == 2) {
2088             /* PRFM - prefetch */
2089             if (is_unpriv) {
2090                 unallocated_encoding(s);
2091                 return;
2092             }
2093             return;
2094         }
2095         if (opc == 3 && size > 1) {
2096             unallocated_encoding(s);
2097             return;
2098         }
2099         is_store = (opc == 0);
2100         is_signed = opc & (1<<1);
2101         is_extended = (size < 3) && (opc & 1);
2102     }
2103
2104     switch (idx) {
2105     case 0:
2106     case 2:
2107         post_index = false;
2108         writeback = false;
2109         break;
2110     case 1:
2111         post_index = true;
2112         writeback = true;
2113         break;
2114     case 3:
2115         post_index = false;
2116         writeback = true;
2117         break;
2118     }
2119
2120     if (rn == 31) {
2121         gen_check_sp_alignment(s);
2122     }
2123     tcg_addr = read_cpu_reg_sp(s, rn, 1);
2124
2125     if (!post_index) {
2126         tcg_gen_addi_i64(tcg_addr, tcg_addr, imm9);
2127     }
2128
2129     if (is_vector) {
2130         if (is_store) {
2131             do_fp_st(s, rt, tcg_addr, size);
2132         } else {
2133             do_fp_ld(s, rt, tcg_addr, size);
2134         }
2135     } else {
2136         TCGv_i64 tcg_rt = cpu_reg(s, rt);
2137         int memidx = is_unpriv ? get_a64_user_mem_index(s) : get_mem_index(s);
2138
2139         if (is_store) {
2140             do_gpr_st_memidx(s, tcg_rt, tcg_addr, size, memidx);
2141         } else {
2142             do_gpr_ld_memidx(s, tcg_rt, tcg_addr, size,
2143                              is_signed, is_extended, memidx);
2144         }
2145     }
2146
2147     if (writeback) {
2148         TCGv_i64 tcg_rn = cpu_reg_sp(s, rn);
2149         if (post_index) {
2150             tcg_gen_addi_i64(tcg_addr, tcg_addr, imm9);
2151         }
2152         tcg_gen_mov_i64(tcg_rn, tcg_addr);
2153     }
2154 }
2155
2156 /*
2157  * C3.3.10 Load/store (register offset)
2158  *
2159  * 31 30 29   27  26 25 24 23 22 21  20  16 15 13 12 11 10 9  5 4  0
2160  * +----+-------+---+-----+-----+---+------+-----+--+-----+----+----+
2161  * |size| 1 1 1 | V | 0 0 | opc | 1 |  Rm  | opt | S| 1 0 | Rn | Rt |
2162  * +----+-------+---+-----+-----+---+------+-----+--+-----+----+----+
2163  *
2164  * For non-vector:
2165  *   size: 00-> byte, 01 -> 16 bit, 10 -> 32bit, 11 -> 64bit
2166  *   opc: 00 -> store, 01 -> loadu, 10 -> loads 64, 11 -> loads 32
2167  * For vector:
2168  *   size is opc<1>:size<1:0> so 100 -> 128 bit; 110 and 111 unallocated
2169  *   opc<0>: 0 -> store, 1 -> load
2170  * V: 1 -> vector/simd
2171  * opt: extend encoding (see DecodeRegExtend)
2172  * S: if S=1 then scale (essentially index by sizeof(size))
2173  * Rt: register to transfer into/out of
2174  * Rn: address register or SP for base
2175  * Rm: offset register or ZR for offset
2176  */
2177 static void disas_ldst_reg_roffset(DisasContext *s, uint32_t insn)
2178 {
2179     int rt = extract32(insn, 0, 5);
2180     int rn = extract32(insn, 5, 5);
2181     int shift = extract32(insn, 12, 1);
2182     int rm = extract32(insn, 16, 5);
2183     int opc = extract32(insn, 22, 2);
2184     int opt = extract32(insn, 13, 3);
2185     int size = extract32(insn, 30, 2);
2186     bool is_signed = false;
2187     bool is_store = false;
2188     bool is_extended = false;
2189     bool is_vector = extract32(insn, 26, 1);
2190
2191     TCGv_i64 tcg_rm;
2192     TCGv_i64 tcg_addr;
2193
2194     if (extract32(opt, 1, 1) == 0) {
2195         unallocated_encoding(s);
2196         return;
2197     }
2198
2199     if (is_vector) {
2200         size |= (opc & 2) << 1;
2201         if (size > 4) {
2202             unallocated_encoding(s);
2203             return;
2204         }
2205         is_store = !extract32(opc, 0, 1);
2206         if (!fp_access_check(s)) {
2207             return;
2208         }
2209     } else {
2210         if (size == 3 && opc == 2) {
2211             /* PRFM - prefetch */
2212             return;
2213         }
2214         if (opc == 3 && size > 1) {
2215             unallocated_encoding(s);
2216             return;
2217         }
2218         is_store = (opc == 0);
2219         is_signed = extract32(opc, 1, 1);
2220         is_extended = (size < 3) && extract32(opc, 0, 1);
2221     }
2222
2223     if (rn == 31) {
2224         gen_check_sp_alignment(s);
2225     }
2226     tcg_addr = read_cpu_reg_sp(s, rn, 1);
2227
2228     tcg_rm = read_cpu_reg(s, rm, 1);
2229     ext_and_shift_reg(tcg_rm, tcg_rm, opt, shift ? size : 0);
2230
2231     tcg_gen_add_i64(tcg_addr, tcg_addr, tcg_rm);
2232
2233     if (is_vector) {
2234         if (is_store) {
2235             do_fp_st(s, rt, tcg_addr, size);
2236         } else {
2237             do_fp_ld(s, rt, tcg_addr, size);
2238         }
2239     } else {
2240         TCGv_i64 tcg_rt = cpu_reg(s, rt);
2241         if (is_store) {
2242             do_gpr_st(s, tcg_rt, tcg_addr, size);
2243         } else {
2244             do_gpr_ld(s, tcg_rt, tcg_addr, size, is_signed, is_extended);
2245         }
2246     }
2247 }
2248
2249 /*
2250  * C3.3.13 Load/store (unsigned immediate)
2251  *
2252  * 31 30 29   27  26 25 24 23 22 21        10 9     5
2253  * +----+-------+---+-----+-----+------------+-------+------+
2254  * |size| 1 1 1 | V | 0 1 | opc |   imm12    |  Rn   |  Rt  |
2255  * +----+-------+---+-----+-----+------------+-------+------+
2256  *
2257  * For non-vector:
2258  *   size: 00-> byte, 01 -> 16 bit, 10 -> 32bit, 11 -> 64bit
2259  *   opc: 00 -> store, 01 -> loadu, 10 -> loads 64, 11 -> loads 32
2260  * For vector:
2261  *   size is opc<1>:size<1:0> so 100 -> 128 bit; 110 and 111 unallocated
2262  *   opc<0>: 0 -> store, 1 -> load
2263  * Rn: base address register (inc SP)
2264  * Rt: target register
2265  */
2266 static void disas_ldst_reg_unsigned_imm(DisasContext *s, uint32_t insn)
2267 {
2268     int rt = extract32(insn, 0, 5);
2269     int rn = extract32(insn, 5, 5);
2270     unsigned int imm12 = extract32(insn, 10, 12);
2271     bool is_vector = extract32(insn, 26, 1);
2272     int size = extract32(insn, 30, 2);
2273     int opc = extract32(insn, 22, 2);
2274     unsigned int offset;
2275
2276     TCGv_i64 tcg_addr;
2277
2278     bool is_store;
2279     bool is_signed = false;
2280     bool is_extended = false;
2281
2282     if (is_vector) {
2283         size |= (opc & 2) << 1;
2284         if (size > 4) {
2285             unallocated_encoding(s);
2286             return;
2287         }
2288         is_store = !extract32(opc, 0, 1);
2289         if (!fp_access_check(s)) {
2290             return;
2291         }
2292     } else {
2293         if (size == 3 && opc == 2) {
2294             /* PRFM - prefetch */
2295             return;
2296         }
2297         if (opc == 3 && size > 1) {
2298             unallocated_encoding(s);
2299             return;
2300         }
2301         is_store = (opc == 0);
2302         is_signed = extract32(opc, 1, 1);
2303         is_extended = (size < 3) && extract32(opc, 0, 1);
2304     }
2305
2306     if (rn == 31) {
2307         gen_check_sp_alignment(s);
2308     }
2309     tcg_addr = read_cpu_reg_sp(s, rn, 1);
2310     offset = imm12 << size;
2311     tcg_gen_addi_i64(tcg_addr, tcg_addr, offset);
2312
2313     if (is_vector) {
2314         if (is_store) {
2315             do_fp_st(s, rt, tcg_addr, size);
2316         } else {
2317             do_fp_ld(s, rt, tcg_addr, size);
2318         }
2319     } else {
2320         TCGv_i64 tcg_rt = cpu_reg(s, rt);
2321         if (is_store) {
2322             do_gpr_st(s, tcg_rt, tcg_addr, size);
2323         } else {
2324             do_gpr_ld(s, tcg_rt, tcg_addr, size, is_signed, is_extended);
2325         }
2326     }
2327 }
2328
2329 /* Load/store register (all forms) */
2330 static void disas_ldst_reg(DisasContext *s, uint32_t insn)
2331 {
2332     switch (extract32(insn, 24, 2)) {
2333     case 0:
2334         if (extract32(insn, 21, 1) == 1 && extract32(insn, 10, 2) == 2) {
2335             disas_ldst_reg_roffset(s, insn);
2336         } else {
2337             /* Load/store register (unscaled immediate)
2338              * Load/store immediate pre/post-indexed
2339              * Load/store register unprivileged
2340              */
2341             disas_ldst_reg_imm9(s, insn);
2342         }
2343         break;
2344     case 1:
2345         disas_ldst_reg_unsigned_imm(s, insn);
2346         break;
2347     default:
2348         unallocated_encoding(s);
2349         break;
2350     }
2351 }
2352
2353 /* C3.3.1 AdvSIMD load/store multiple structures
2354  *
2355  *  31  30  29           23 22  21         16 15    12 11  10 9    5 4    0
2356  * +---+---+---------------+---+-------------+--------+------+------+------+
2357  * | 0 | Q | 0 0 1 1 0 0 0 | L | 0 0 0 0 0 0 | opcode | size |  Rn  |  Rt  |
2358  * +---+---+---------------+---+-------------+--------+------+------+------+
2359  *
2360  * C3.3.2 AdvSIMD load/store multiple structures (post-indexed)
2361  *
2362  *  31  30  29           23 22  21  20     16 15    12 11  10 9    5 4    0
2363  * +---+---+---------------+---+---+---------+--------+------+------+------+
2364  * | 0 | Q | 0 0 1 1 0 0 1 | L | 0 |   Rm    | opcode | size |  Rn  |  Rt  |
2365  * +---+---+---------------+---+---+---------+--------+------+------+------+
2366  *
2367  * Rt: first (or only) SIMD&FP register to be transferred
2368  * Rn: base address or SP
2369  * Rm (post-index only): post-index register (when !31) or size dependent #imm
2370  */
2371 static void disas_ldst_multiple_struct(DisasContext *s, uint32_t insn)
2372 {
2373     int rt = extract32(insn, 0, 5);
2374     int rn = extract32(insn, 5, 5);
2375     int size = extract32(insn, 10, 2);
2376     int opcode = extract32(insn, 12, 4);
2377     bool is_store = !extract32(insn, 22, 1);
2378     bool is_postidx = extract32(insn, 23, 1);
2379     bool is_q = extract32(insn, 30, 1);
2380     TCGv_i64 tcg_addr, tcg_rn;
2381
2382     int ebytes = 1 << size;
2383     int elements = (is_q ? 128 : 64) / (8 << size);
2384     int rpt;    /* num iterations */
2385     int selem;  /* structure elements */
2386     int r;
2387
2388     if (extract32(insn, 31, 1) || extract32(insn, 21, 1)) {
2389         unallocated_encoding(s);
2390         return;
2391     }
2392
2393     /* From the shared decode logic */
2394     switch (opcode) {
2395     case 0x0:
2396         rpt = 1;
2397         selem = 4;
2398         break;
2399     case 0x2:
2400         rpt = 4;
2401         selem = 1;
2402         break;
2403     case 0x4:
2404         rpt = 1;
2405         selem = 3;
2406         break;
2407     case 0x6:
2408         rpt = 3;
2409         selem = 1;
2410         break;
2411     case 0x7:
2412         rpt = 1;
2413         selem = 1;
2414         break;
2415     case 0x8:
2416         rpt = 1;
2417         selem = 2;
2418         break;
2419     case 0xa:
2420         rpt = 2;
2421         selem = 1;
2422         break;
2423     default:
2424         unallocated_encoding(s);
2425         return;
2426     }
2427
2428     if (size == 3 && !is_q && selem != 1) {
2429         /* reserved */
2430         unallocated_encoding(s);
2431         return;
2432     }
2433
2434     if (!fp_access_check(s)) {
2435         return;
2436     }
2437
2438     if (rn == 31) {
2439         gen_check_sp_alignment(s);
2440     }
2441
2442     tcg_rn = cpu_reg_sp(s, rn);
2443     tcg_addr = tcg_temp_new_i64();
2444     tcg_gen_mov_i64(tcg_addr, tcg_rn);
2445
2446     for (r = 0; r < rpt; r++) {
2447         int e;
2448         for (e = 0; e < elements; e++) {
2449             int tt = (rt + r) % 32;
2450             int xs;
2451             for (xs = 0; xs < selem; xs++) {
2452                 if (is_store) {
2453                     do_vec_st(s, tt, e, tcg_addr, size);
2454                 } else {
2455                     do_vec_ld(s, tt, e, tcg_addr, size);
2456
2457                     /* For non-quad operations, setting a slice of the low
2458                      * 64 bits of the register clears the high 64 bits (in
2459                      * the ARM ARM pseudocode this is implicit in the fact
2460                      * that 'rval' is a 64 bit wide variable). We optimize
2461                      * by noticing that we only need to do this the first
2462                      * time we touch a register.
2463                      */
2464                     if (!is_q && e == 0 && (r == 0 || xs == selem - 1)) {
2465                         clear_vec_high(s, tt);
2466                     }
2467                 }
2468                 tcg_gen_addi_i64(tcg_addr, tcg_addr, ebytes);
2469                 tt = (tt + 1) % 32;
2470             }
2471         }
2472     }
2473
2474     if (is_postidx) {
2475         int rm = extract32(insn, 16, 5);
2476         if (rm == 31) {
2477             tcg_gen_mov_i64(tcg_rn, tcg_addr);
2478         } else {
2479             tcg_gen_add_i64(tcg_rn, tcg_rn, cpu_reg(s, rm));
2480         }
2481     }
2482     tcg_temp_free_i64(tcg_addr);
2483 }
2484
2485 /* C3.3.3 AdvSIMD load/store single structure
2486  *
2487  *  31  30  29           23 22 21 20       16 15 13 12  11  10 9    5 4    0
2488  * +---+---+---------------+-----+-----------+-----+---+------+------+------+
2489  * | 0 | Q | 0 0 1 1 0 1 0 | L R | 0 0 0 0 0 | opc | S | size |  Rn  |  Rt  |
2490  * +---+---+---------------+-----+-----------+-----+---+------+------+------+
2491  *
2492  * C3.3.4 AdvSIMD load/store single structure (post-indexed)
2493  *
2494  *  31  30  29           23 22 21 20       16 15 13 12  11  10 9    5 4    0
2495  * +---+---+---------------+-----+-----------+-----+---+------+------+------+
2496  * | 0 | Q | 0 0 1 1 0 1 1 | L R |     Rm    | opc | S | size |  Rn  |  Rt  |
2497  * +---+---+---------------+-----+-----------+-----+---+------+------+------+
2498  *
2499  * Rt: first (or only) SIMD&FP register to be transferred
2500  * Rn: base address or SP
2501  * Rm (post-index only): post-index register (when !31) or size dependent #imm
2502  * index = encoded in Q:S:size dependent on size
2503  *
2504  * lane_size = encoded in R, opc
2505  * transfer width = encoded in opc, S, size
2506  */
2507 static void disas_ldst_single_struct(DisasContext *s, uint32_t insn)
2508 {
2509     int rt = extract32(insn, 0, 5);
2510     int rn = extract32(insn, 5, 5);
2511     int size = extract32(insn, 10, 2);
2512     int S = extract32(insn, 12, 1);
2513     int opc = extract32(insn, 13, 3);
2514     int R = extract32(insn, 21, 1);
2515     int is_load = extract32(insn, 22, 1);
2516     int is_postidx = extract32(insn, 23, 1);
2517     int is_q = extract32(insn, 30, 1);
2518
2519     int scale = extract32(opc, 1, 2);
2520     int selem = (extract32(opc, 0, 1) << 1 | R) + 1;
2521     bool replicate = false;
2522     int index = is_q << 3 | S << 2 | size;
2523     int ebytes, xs;
2524     TCGv_i64 tcg_addr, tcg_rn;
2525
2526     switch (scale) {
2527     case 3:
2528         if (!is_load || S) {
2529             unallocated_encoding(s);
2530             return;
2531         }
2532         scale = size;
2533         replicate = true;
2534         break;
2535     case 0:
2536         break;
2537     case 1:
2538         if (extract32(size, 0, 1)) {
2539             unallocated_encoding(s);
2540             return;
2541         }
2542         index >>= 1;
2543         break;
2544     case 2:
2545         if (extract32(size, 1, 1)) {
2546             unallocated_encoding(s);
2547             return;
2548         }
2549         if (!extract32(size, 0, 1)) {
2550             index >>= 2;
2551         } else {
2552             if (S) {
2553                 unallocated_encoding(s);
2554                 return;
2555             }
2556             index >>= 3;
2557             scale = 3;
2558         }
2559         break;
2560     default:
2561         g_assert_not_reached();
2562     }
2563
2564     if (!fp_access_check(s)) {
2565         return;
2566     }
2567
2568     ebytes = 1 << scale;
2569
2570     if (rn == 31) {
2571         gen_check_sp_alignment(s);
2572     }
2573
2574     tcg_rn = cpu_reg_sp(s, rn);
2575     tcg_addr = tcg_temp_new_i64();
2576     tcg_gen_mov_i64(tcg_addr, tcg_rn);
2577
2578     for (xs = 0; xs < selem; xs++) {
2579         if (replicate) {
2580             /* Load and replicate to all elements */
2581             uint64_t mulconst;
2582             TCGv_i64 tcg_tmp = tcg_temp_new_i64();
2583
2584             tcg_gen_qemu_ld_i64(tcg_tmp, tcg_addr,
2585                                 get_mem_index(s), MO_TE + scale);
2586             switch (scale) {
2587             case 0:
2588                 mulconst = 0x0101010101010101ULL;
2589                 break;
2590             case 1:
2591                 mulconst = 0x0001000100010001ULL;
2592                 break;
2593             case 2:
2594                 mulconst = 0x0000000100000001ULL;
2595                 break;
2596             case 3:
2597                 mulconst = 0;
2598                 break;
2599             default:
2600                 g_assert_not_reached();
2601             }
2602             if (mulconst) {
2603                 tcg_gen_muli_i64(tcg_tmp, tcg_tmp, mulconst);
2604             }
2605             write_vec_element(s, tcg_tmp, rt, 0, MO_64);
2606             if (is_q) {
2607                 write_vec_element(s, tcg_tmp, rt, 1, MO_64);
2608             } else {
2609                 clear_vec_high(s, rt);
2610             }
2611             tcg_temp_free_i64(tcg_tmp);
2612         } else {
2613             /* Load/store one element per register */
2614             if (is_load) {
2615                 do_vec_ld(s, rt, index, tcg_addr, MO_TE + scale);
2616             } else {
2617                 do_vec_st(s, rt, index, tcg_addr, MO_TE + scale);
2618             }
2619         }
2620         tcg_gen_addi_i64(tcg_addr, tcg_addr, ebytes);
2621         rt = (rt + 1) % 32;
2622     }
2623
2624     if (is_postidx) {
2625         int rm = extract32(insn, 16, 5);
2626         if (rm == 31) {
2627             tcg_gen_mov_i64(tcg_rn, tcg_addr);
2628         } else {
2629             tcg_gen_add_i64(tcg_rn, tcg_rn, cpu_reg(s, rm));
2630         }
2631     }
2632     tcg_temp_free_i64(tcg_addr);
2633 }
2634
2635 /* C3.3 Loads and stores */
2636 static void disas_ldst(DisasContext *s, uint32_t insn)
2637 {
2638     switch (extract32(insn, 24, 6)) {
2639     case 0x08: /* Load/store exclusive */
2640         disas_ldst_excl(s, insn);
2641         break;
2642     case 0x18: case 0x1c: /* Load register (literal) */
2643         disas_ld_lit(s, insn);
2644         break;
2645     case 0x28: case 0x29:
2646     case 0x2c: case 0x2d: /* Load/store pair (all forms) */
2647         disas_ldst_pair(s, insn);
2648         break;
2649     case 0x38: case 0x39:
2650     case 0x3c: case 0x3d: /* Load/store register (all forms) */
2651         disas_ldst_reg(s, insn);
2652         break;
2653     case 0x0c: /* AdvSIMD load/store multiple structures */
2654         disas_ldst_multiple_struct(s, insn);
2655         break;
2656     case 0x0d: /* AdvSIMD load/store single structure */
2657         disas_ldst_single_struct(s, insn);
2658         break;
2659     default:
2660         unallocated_encoding(s);
2661         break;
2662     }
2663 }
2664
2665 /* C3.4.6 PC-rel. addressing
2666  *   31  30   29 28       24 23                5 4    0
2667  * +----+-------+-----------+-------------------+------+
2668  * | op | immlo | 1 0 0 0 0 |       immhi       |  Rd  |
2669  * +----+-------+-----------+-------------------+------+
2670  */
2671 static void disas_pc_rel_adr(DisasContext *s, uint32_t insn)
2672 {
2673     unsigned int page, rd;
2674     uint64_t base;
2675     uint64_t offset;
2676
2677     page = extract32(insn, 31, 1);
2678     /* SignExtend(immhi:immlo) -> offset */
2679     offset = sextract64(insn, 5, 19);
2680     offset = offset << 2 | extract32(insn, 29, 2);
2681     rd = extract32(insn, 0, 5);
2682     base = s->pc - 4;
2683
2684     if (page) {
2685         /* ADRP (page based) */
2686         base &= ~0xfff;
2687         offset <<= 12;
2688     }
2689
2690     tcg_gen_movi_i64(cpu_reg(s, rd), base + offset);
2691 }
2692
2693 /*
2694  * C3.4.1 Add/subtract (immediate)
2695  *
2696  *  31 30 29 28       24 23 22 21         10 9   5 4   0
2697  * +--+--+--+-----------+-----+-------------+-----+-----+
2698  * |sf|op| S| 1 0 0 0 1 |shift|    imm12    |  Rn | Rd  |
2699  * +--+--+--+-----------+-----+-------------+-----+-----+
2700  *
2701  *    sf: 0 -> 32bit, 1 -> 64bit
2702  *    op: 0 -> add  , 1 -> sub
2703  *     S: 1 -> set flags
2704  * shift: 00 -> LSL imm by 0, 01 -> LSL imm by 12
2705  */
2706 static void disas_add_sub_imm(DisasContext *s, uint32_t insn)
2707 {
2708     int rd = extract32(insn, 0, 5);
2709     int rn = extract32(insn, 5, 5);
2710     uint64_t imm = extract32(insn, 10, 12);
2711     int shift = extract32(insn, 22, 2);
2712     bool setflags = extract32(insn, 29, 1);
2713     bool sub_op = extract32(insn, 30, 1);
2714     bool is_64bit = extract32(insn, 31, 1);
2715
2716     TCGv_i64 tcg_rn = cpu_reg_sp(s, rn);
2717     TCGv_i64 tcg_rd = setflags ? cpu_reg(s, rd) : cpu_reg_sp(s, rd);
2718     TCGv_i64 tcg_result;
2719
2720     switch (shift) {
2721     case 0x0:
2722         break;
2723     case 0x1:
2724         imm <<= 12;
2725         break;
2726     default:
2727         unallocated_encoding(s);
2728         return;
2729     }
2730
2731     tcg_result = tcg_temp_new_i64();
2732     if (!setflags) {
2733         if (sub_op) {
2734             tcg_gen_subi_i64(tcg_result, tcg_rn, imm);
2735         } else {
2736             tcg_gen_addi_i64(tcg_result, tcg_rn, imm);
2737         }
2738     } else {
2739         TCGv_i64 tcg_imm = tcg_const_i64(imm);
2740         if (sub_op) {
2741             gen_sub_CC(is_64bit, tcg_result, tcg_rn, tcg_imm);
2742         } else {
2743             gen_add_CC(is_64bit, tcg_result, tcg_rn, tcg_imm);
2744         }
2745         tcg_temp_free_i64(tcg_imm);
2746     }
2747
2748     if (is_64bit) {
2749         tcg_gen_mov_i64(tcg_rd, tcg_result);
2750     } else {
2751         tcg_gen_ext32u_i64(tcg_rd, tcg_result);
2752     }
2753
2754     tcg_temp_free_i64(tcg_result);
2755 }
2756
2757 /* The input should be a value in the bottom e bits (with higher
2758  * bits zero); returns that value replicated into every element
2759  * of size e in a 64 bit integer.
2760  */
2761 static uint64_t bitfield_replicate(uint64_t mask, unsigned int e)
2762 {
2763     assert(e != 0);
2764     while (e < 64) {
2765         mask |= mask << e;
2766         e *= 2;
2767     }
2768     return mask;
2769 }
2770
2771 /* Return a value with the bottom len bits set (where 0 < len <= 64) */
2772 static inline uint64_t bitmask64(unsigned int length)
2773 {
2774     assert(length > 0 && length <= 64);
2775     return ~0ULL >> (64 - length);
2776 }
2777
2778 /* Simplified variant of pseudocode DecodeBitMasks() for the case where we
2779  * only require the wmask. Returns false if the imms/immr/immn are a reserved
2780  * value (ie should cause a guest UNDEF exception), and true if they are
2781  * valid, in which case the decoded bit pattern is written to result.
2782  */
2783 static bool logic_imm_decode_wmask(uint64_t *result, unsigned int immn,
2784                                    unsigned int imms, unsigned int immr)
2785 {
2786     uint64_t mask;
2787     unsigned e, levels, s, r;
2788     int len;
2789
2790     assert(immn < 2 && imms < 64 && immr < 64);
2791
2792     /* The bit patterns we create here are 64 bit patterns which
2793      * are vectors of identical elements of size e = 2, 4, 8, 16, 32 or
2794      * 64 bits each. Each element contains the same value: a run
2795      * of between 1 and e-1 non-zero bits, rotated within the
2796      * element by between 0 and e-1 bits.
2797      *
2798      * The element size and run length are encoded into immn (1 bit)
2799      * and imms (6 bits) as follows:
2800      * 64 bit elements: immn = 1, imms = <length of run - 1>
2801      * 32 bit elements: immn = 0, imms = 0 : <length of run - 1>
2802      * 16 bit elements: immn = 0, imms = 10 : <length of run - 1>
2803      *  8 bit elements: immn = 0, imms = 110 : <length of run - 1>
2804      *  4 bit elements: immn = 0, imms = 1110 : <length of run - 1>
2805      *  2 bit elements: immn = 0, imms = 11110 : <length of run - 1>
2806      * Notice that immn = 0, imms = 11111x is the only combination
2807      * not covered by one of the above options; this is reserved.
2808      * Further, <length of run - 1> all-ones is a reserved pattern.
2809      *
2810      * In all cases the rotation is by immr % e (and immr is 6 bits).
2811      */
2812
2813     /* First determine the element size */
2814     len = 31 - clz32((immn << 6) | (~imms & 0x3f));
2815     if (len < 1) {
2816         /* This is the immn == 0, imms == 0x11111x case */
2817         return false;
2818     }
2819     e = 1 << len;
2820
2821     levels = e - 1;
2822     s = imms & levels;
2823     r = immr & levels;
2824
2825     if (s == levels) {
2826         /* <length of run - 1> mustn't be all-ones. */
2827         return false;
2828     }
2829
2830     /* Create the value of one element: s+1 set bits rotated
2831      * by r within the element (which is e bits wide)...
2832      */
2833     mask = bitmask64(s + 1);
2834     if (r) {
2835         mask = (mask >> r) | (mask << (e - r));
2836         mask &= bitmask64(e);
2837     }
2838     /* ...then replicate the element over the whole 64 bit value */
2839     mask = bitfield_replicate(mask, e);
2840     *result = mask;
2841     return true;
2842 }
2843
2844 /* C3.4.4 Logical (immediate)
2845  *   31  30 29 28         23 22  21  16 15  10 9    5 4    0
2846  * +----+-----+-------------+---+------+------+------+------+
2847  * | sf | opc | 1 0 0 1 0 0 | N | immr | imms |  Rn  |  Rd  |
2848  * +----+-----+-------------+---+------+------+------+------+
2849  */
2850 static void disas_logic_imm(DisasContext *s, uint32_t insn)
2851 {
2852     unsigned int sf, opc, is_n, immr, imms, rn, rd;
2853     TCGv_i64 tcg_rd, tcg_rn;
2854     uint64_t wmask;
2855     bool is_and = false;
2856
2857     sf = extract32(insn, 31, 1);
2858     opc = extract32(insn, 29, 2);
2859     is_n = extract32(insn, 22, 1);
2860     immr = extract32(insn, 16, 6);
2861     imms = extract32(insn, 10, 6);
2862     rn = extract32(insn, 5, 5);
2863     rd = extract32(insn, 0, 5);
2864
2865     if (!sf && is_n) {
2866         unallocated_encoding(s);
2867         return;
2868     }
2869
2870     if (opc == 0x3) { /* ANDS */
2871         tcg_rd = cpu_reg(s, rd);
2872     } else {
2873         tcg_rd = cpu_reg_sp(s, rd);
2874     }
2875     tcg_rn = cpu_reg(s, rn);
2876
2877     if (!logic_imm_decode_wmask(&wmask, is_n, imms, immr)) {
2878         /* some immediate field values are reserved */
2879         unallocated_encoding(s);
2880         return;
2881     }
2882
2883     if (!sf) {
2884         wmask &= 0xffffffff;
2885     }
2886
2887     switch (opc) {
2888     case 0x3: /* ANDS */
2889     case 0x0: /* AND */
2890         tcg_gen_andi_i64(tcg_rd, tcg_rn, wmask);
2891         is_and = true;
2892         break;
2893     case 0x1: /* ORR */
2894         tcg_gen_ori_i64(tcg_rd, tcg_rn, wmask);
2895         break;
2896     case 0x2: /* EOR */
2897         tcg_gen_xori_i64(tcg_rd, tcg_rn, wmask);
2898         break;
2899     default:
2900         assert(FALSE); /* must handle all above */
2901         break;
2902     }
2903
2904     if (!sf && !is_and) {
2905         /* zero extend final result; we know we can skip this for AND
2906          * since the immediate had the high 32 bits clear.
2907          */
2908         tcg_gen_ext32u_i64(tcg_rd, tcg_rd);
2909     }
2910
2911     if (opc == 3) { /* ANDS */
2912         gen_logic_CC(sf, tcg_rd);
2913     }
2914 }
2915
2916 /*
2917  * C3.4.5 Move wide (immediate)
2918  *
2919  *  31 30 29 28         23 22 21 20             5 4    0
2920  * +--+-----+-------------+-----+----------------+------+
2921  * |sf| opc | 1 0 0 1 0 1 |  hw |  imm16         |  Rd  |
2922  * +--+-----+-------------+-----+----------------+------+
2923  *
2924  * sf: 0 -> 32 bit, 1 -> 64 bit
2925  * opc: 00 -> N, 10 -> Z, 11 -> K
2926  * hw: shift/16 (0,16, and sf only 32, 48)
2927  */
2928 static void disas_movw_imm(DisasContext *s, uint32_t insn)
2929 {
2930     int rd = extract32(insn, 0, 5);
2931     uint64_t imm = extract32(insn, 5, 16);
2932     int sf = extract32(insn, 31, 1);
2933     int opc = extract32(insn, 29, 2);
2934     int pos = extract32(insn, 21, 2) << 4;
2935     TCGv_i64 tcg_rd = cpu_reg(s, rd);
2936     TCGv_i64 tcg_imm;
2937
2938     if (!sf && (pos >= 32)) {
2939         unallocated_encoding(s);
2940         return;
2941     }
2942
2943     switch (opc) {
2944     case 0: /* MOVN */
2945     case 2: /* MOVZ */
2946         imm <<= pos;
2947         if (opc == 0) {
2948             imm = ~imm;
2949         }
2950         if (!sf) {
2951             imm &= 0xffffffffu;
2952         }
2953         tcg_gen_movi_i64(tcg_rd, imm);
2954         break;
2955     case 3: /* MOVK */
2956         tcg_imm = tcg_const_i64(imm);
2957         tcg_gen_deposit_i64(tcg_rd, tcg_rd, tcg_imm, pos, 16);
2958         tcg_temp_free_i64(tcg_imm);
2959         if (!sf) {
2960             tcg_gen_ext32u_i64(tcg_rd, tcg_rd);
2961         }
2962         break;
2963     default:
2964         unallocated_encoding(s);
2965         break;
2966     }
2967 }
2968
2969 /* C3.4.2 Bitfield
2970  *   31  30 29 28         23 22  21  16 15  10 9    5 4    0
2971  * +----+-----+-------------+---+------+------+------+------+
2972  * | sf | opc | 1 0 0 1 1 0 | N | immr | imms |  Rn  |  Rd  |
2973  * +----+-----+-------------+---+------+------+------+------+
2974  */
2975 static void disas_bitfield(DisasContext *s, uint32_t insn)
2976 {
2977     unsigned int sf, n, opc, ri, si, rn, rd, bitsize, pos, len;
2978     TCGv_i64 tcg_rd, tcg_tmp;
2979
2980     sf = extract32(insn, 31, 1);
2981     opc = extract32(insn, 29, 2);
2982     n = extract32(insn, 22, 1);
2983     ri = extract32(insn, 16, 6);
2984     si = extract32(insn, 10, 6);
2985     rn = extract32(insn, 5, 5);
2986     rd = extract32(insn, 0, 5);
2987     bitsize = sf ? 64 : 32;
2988
2989     if (sf != n || ri >= bitsize || si >= bitsize || opc > 2) {
2990         unallocated_encoding(s);
2991         return;
2992     }
2993
2994     tcg_rd = cpu_reg(s, rd);
2995     tcg_tmp = read_cpu_reg(s, rn, sf);
2996
2997     /* OPTME: probably worth recognizing common cases of ext{8,16,32}{u,s} */
2998
2999     if (opc != 1) { /* SBFM or UBFM */
3000         tcg_gen_movi_i64(tcg_rd, 0);
3001     }
3002
3003     /* do the bit move operation */
3004     if (si >= ri) {
3005         /* Wd<s-r:0> = Wn<s:r> */
3006         tcg_gen_shri_i64(tcg_tmp, tcg_tmp, ri);
3007         pos = 0;
3008         len = (si - ri) + 1;
3009     } else {
3010         /* Wd<32+s-r,32-r> = Wn<s:0> */
3011         pos = bitsize - ri;
3012         len = si + 1;
3013     }
3014
3015     tcg_gen_deposit_i64(tcg_rd, tcg_rd, tcg_tmp, pos, len);
3016
3017     if (opc == 0) { /* SBFM - sign extend the destination field */
3018         tcg_gen_shli_i64(tcg_rd, tcg_rd, 64 - (pos + len));
3019         tcg_gen_sari_i64(tcg_rd, tcg_rd, 64 - (pos + len));
3020     }
3021
3022     if (!sf) { /* zero extend final result */
3023         tcg_gen_ext32u_i64(tcg_rd, tcg_rd);
3024     }
3025 }
3026
3027 /* C3.4.3 Extract
3028  *   31  30  29 28         23 22   21  20  16 15    10 9    5 4    0
3029  * +----+------+-------------+---+----+------+--------+------+------+
3030  * | sf | op21 | 1 0 0 1 1 1 | N | o0 |  Rm  |  imms  |  Rn  |  Rd  |
3031  * +----+------+-------------+---+----+------+--------+------+------+
3032  */
3033 static void disas_extract(DisasContext *s, uint32_t insn)
3034 {
3035     unsigned int sf, n, rm, imm, rn, rd, bitsize, op21, op0;
3036
3037     sf = extract32(insn, 31, 1);
3038     n = extract32(insn, 22, 1);
3039     rm = extract32(insn, 16, 5);
3040     imm = extract32(insn, 10, 6);
3041     rn = extract32(insn, 5, 5);
3042     rd = extract32(insn, 0, 5);
3043     op21 = extract32(insn, 29, 2);
3044     op0 = extract32(insn, 21, 1);
3045     bitsize = sf ? 64 : 32;
3046
3047     if (sf != n || op21 || op0 || imm >= bitsize) {
3048         unallocated_encoding(s);
3049     } else {
3050         TCGv_i64 tcg_rd, tcg_rm, tcg_rn;
3051
3052         tcg_rd = cpu_reg(s, rd);
3053
3054         if (imm) {
3055             /* OPTME: we can special case rm==rn as a rotate */
3056             tcg_rm = read_cpu_reg(s, rm, sf);
3057             tcg_rn = read_cpu_reg(s, rn, sf);
3058             tcg_gen_shri_i64(tcg_rm, tcg_rm, imm);
3059             tcg_gen_shli_i64(tcg_rn, tcg_rn, bitsize - imm);
3060             tcg_gen_or_i64(tcg_rd, tcg_rm, tcg_rn);
3061             if (!sf) {
3062                 tcg_gen_ext32u_i64(tcg_rd, tcg_rd);
3063             }
3064         } else {
3065             /* tcg shl_i32/shl_i64 is undefined for 32/64 bit shifts,
3066              * so an extract from bit 0 is a special case.
3067              */
3068             if (sf) {
3069                 tcg_gen_mov_i64(tcg_rd, cpu_reg(s, rm));
3070             } else {
3071                 tcg_gen_ext32u_i64(tcg_rd, cpu_reg(s, rm));
3072             }
3073         }
3074
3075     }
3076 }
3077
3078 /* C3.4 Data processing - immediate */
3079 static void disas_data_proc_imm(DisasContext *s, uint32_t insn)
3080 {
3081     switch (extract32(insn, 23, 6)) {
3082     case 0x20: case 0x21: /* PC-rel. addressing */
3083         disas_pc_rel_adr(s, insn);
3084         break;
3085     case 0x22: case 0x23: /* Add/subtract (immediate) */
3086         disas_add_sub_imm(s, insn);
3087         break;
3088     case 0x24: /* Logical (immediate) */
3089         disas_logic_imm(s, insn);
3090         break;
3091     case 0x25: /* Move wide (immediate) */
3092         disas_movw_imm(s, insn);
3093         break;
3094     case 0x26: /* Bitfield */
3095         disas_bitfield(s, insn);
3096         break;
3097     case 0x27: /* Extract */
3098         disas_extract(s, insn);
3099         break;
3100     default:
3101         unallocated_encoding(s);
3102         break;
3103     }
3104 }
3105
3106 /* Shift a TCGv src by TCGv shift_amount, put result in dst.
3107  * Note that it is the caller's responsibility to ensure that the
3108  * shift amount is in range (ie 0..31 or 0..63) and provide the ARM
3109  * mandated semantics for out of range shifts.
3110  */
3111 static void shift_reg(TCGv_i64 dst, TCGv_i64 src, int sf,
3112                       enum a64_shift_type shift_type, TCGv_i64 shift_amount)
3113 {
3114     switch (shift_type) {
3115     case A64_SHIFT_TYPE_LSL:
3116         tcg_gen_shl_i64(dst, src, shift_amount);
3117         break;
3118     case A64_SHIFT_TYPE_LSR:
3119         tcg_gen_shr_i64(dst, src, shift_amount);
3120         break;
3121     case A64_SHIFT_TYPE_ASR:
3122         if (!sf) {
3123             tcg_gen_ext32s_i64(dst, src);
3124         }
3125         tcg_gen_sar_i64(dst, sf ? src : dst, shift_amount);
3126         break;
3127     case A64_SHIFT_TYPE_ROR:
3128         if (sf) {
3129             tcg_gen_rotr_i64(dst, src, shift_amount);
3130         } else {
3131             TCGv_i32 t0, t1;
3132             t0 = tcg_temp_new_i32();
3133             t1 = tcg_temp_new_i32();
3134             tcg_gen_trunc_i64_i32(t0, src);
3135             tcg_gen_trunc_i64_i32(t1, shift_amount);
3136             tcg_gen_rotr_i32(t0, t0, t1);
3137             tcg_gen_extu_i32_i64(dst, t0);
3138             tcg_temp_free_i32(t0);
3139             tcg_temp_free_i32(t1);
3140         }
3141         break;
3142     default:
3143         assert(FALSE); /* all shift types should be handled */
3144         break;
3145     }
3146
3147     if (!sf) { /* zero extend final result */
3148         tcg_gen_ext32u_i64(dst, dst);
3149     }
3150 }
3151
3152 /* Shift a TCGv src by immediate, put result in dst.
3153  * The shift amount must be in range (this should always be true as the
3154  * relevant instructions will UNDEF on bad shift immediates).
3155  */
3156 static void shift_reg_imm(TCGv_i64 dst, TCGv_i64 src, int sf,
3157                           enum a64_shift_type shift_type, unsigned int shift_i)
3158 {
3159     assert(shift_i < (sf ? 64 : 32));
3160
3161     if (shift_i == 0) {
3162         tcg_gen_mov_i64(dst, src);
3163     } else {
3164         TCGv_i64 shift_const;
3165
3166         shift_const = tcg_const_i64(shift_i);
3167         shift_reg(dst, src, sf, shift_type, shift_const);
3168         tcg_temp_free_i64(shift_const);
3169     }
3170 }
3171
3172 /* C3.5.10 Logical (shifted register)
3173  *   31  30 29 28       24 23   22 21  20  16 15    10 9    5 4    0
3174  * +----+-----+-----------+-------+---+------+--------+------+------+
3175  * | sf | opc | 0 1 0 1 0 | shift | N |  Rm  |  imm6  |  Rn  |  Rd  |
3176  * +----+-----+-----------+-------+---+------+--------+------+------+
3177  */
3178 static void disas_logic_reg(DisasContext *s, uint32_t insn)
3179 {
3180     TCGv_i64 tcg_rd, tcg_rn, tcg_rm;
3181     unsigned int sf, opc, shift_type, invert, rm, shift_amount, rn, rd;
3182
3183     sf = extract32(insn, 31, 1);
3184     opc = extract32(insn, 29, 2);
3185     shift_type = extract32(insn, 22, 2);
3186     invert = extract32(insn, 21, 1);
3187     rm = extract32(insn, 16, 5);
3188     shift_amount = extract32(insn, 10, 6);
3189     rn = extract32(insn, 5, 5);
3190     rd = extract32(insn, 0, 5);
3191
3192     if (!sf && (shift_amount & (1 << 5))) {
3193         unallocated_encoding(s);
3194         return;
3195     }
3196
3197     tcg_rd = cpu_reg(s, rd);
3198
3199     if (opc == 1 && shift_amount == 0 && shift_type == 0 && rn == 31) {
3200         /* Unshifted ORR and ORN with WZR/XZR is the standard encoding for
3201          * register-register MOV and MVN, so it is worth special casing.
3202          */
3203         tcg_rm = cpu_reg(s, rm);
3204         if (invert) {
3205             tcg_gen_not_i64(tcg_rd, tcg_rm);
3206             if (!sf) {
3207                 tcg_gen_ext32u_i64(tcg_rd, tcg_rd);
3208             }
3209         } else {
3210             if (sf) {
3211                 tcg_gen_mov_i64(tcg_rd, tcg_rm);
3212             } else {
3213                 tcg_gen_ext32u_i64(tcg_rd, tcg_rm);
3214             }
3215         }
3216         return;
3217     }
3218
3219     tcg_rm = read_cpu_reg(s, rm, sf);
3220
3221     if (shift_amount) {
3222         shift_reg_imm(tcg_rm, tcg_rm, sf, shift_type, shift_amount);
3223     }
3224
3225     tcg_rn = cpu_reg(s, rn);
3226
3227     switch (opc | (invert << 2)) {
3228     case 0: /* AND */
3229     case 3: /* ANDS */
3230         tcg_gen_and_i64(tcg_rd, tcg_rn, tcg_rm);
3231         break;
3232     case 1: /* ORR */
3233         tcg_gen_or_i64(tcg_rd, tcg_rn, tcg_rm);
3234         break;
3235     case 2: /* EOR */
3236         tcg_gen_xor_i64(tcg_rd, tcg_rn, tcg_rm);
3237         break;
3238     case 4: /* BIC */
3239     case 7: /* BICS */
3240         tcg_gen_andc_i64(tcg_rd, tcg_rn, tcg_rm);
3241         break;
3242     case 5: /* ORN */
3243         tcg_gen_orc_i64(tcg_rd, tcg_rn, tcg_rm);
3244         break;
3245     case 6: /* EON */
3246         tcg_gen_eqv_i64(tcg_rd, tcg_rn, tcg_rm);
3247         break;
3248     default:
3249         assert(FALSE);
3250         break;
3251     }
3252
3253     if (!sf) {
3254         tcg_gen_ext32u_i64(tcg_rd, tcg_rd);
3255     }
3256
3257     if (opc == 3) {
3258         gen_logic_CC(sf, tcg_rd);
3259     }
3260 }
3261
3262 /*
3263  * C3.5.1 Add/subtract (extended register)
3264  *
3265  *  31|30|29|28       24|23 22|21|20   16|15  13|12  10|9  5|4  0|
3266  * +--+--+--+-----------+-----+--+-------+------+------+----+----+
3267  * |sf|op| S| 0 1 0 1 1 | opt | 1|  Rm   |option| imm3 | Rn | Rd |
3268  * +--+--+--+-----------+-----+--+-------+------+------+----+----+
3269  *
3270  *  sf: 0 -> 32bit, 1 -> 64bit
3271  *  op: 0 -> add  , 1 -> sub
3272  *   S: 1 -> set flags
3273  * opt: 00
3274  * option: extension type (see DecodeRegExtend)
3275  * imm3: optional shift to Rm
3276  *
3277  * Rd = Rn + LSL(extend(Rm), amount)
3278  */
3279 static void disas_add_sub_ext_reg(DisasContext *s, uint32_t insn)
3280 {
3281     int rd = extract32(insn, 0, 5);
3282     int rn = extract32(insn, 5, 5);
3283     int imm3 = extract32(insn, 10, 3);
3284     int option = extract32(insn, 13, 3);
3285     int rm = extract32(insn, 16, 5);
3286     bool setflags = extract32(insn, 29, 1);
3287     bool sub_op = extract32(insn, 30, 1);
3288     bool sf = extract32(insn, 31, 1);
3289
3290     TCGv_i64 tcg_rm, tcg_rn; /* temps */
3291     TCGv_i64 tcg_rd;
3292     TCGv_i64 tcg_result;
3293
3294     if (imm3 > 4) {
3295         unallocated_encoding(s);
3296         return;
3297     }
3298
3299     /* non-flag setting ops may use SP */
3300     if (!setflags) {
3301         tcg_rd = cpu_reg_sp(s, rd);
3302     } else {
3303         tcg_rd = cpu_reg(s, rd);
3304     }
3305     tcg_rn = read_cpu_reg_sp(s, rn, sf);
3306
3307     tcg_rm = read_cpu_reg(s, rm, sf);
3308     ext_and_shift_reg(tcg_rm, tcg_rm, option, imm3);
3309
3310     tcg_result = tcg_temp_new_i64();
3311
3312     if (!setflags) {
3313         if (sub_op) {
3314             tcg_gen_sub_i64(tcg_result, tcg_rn, tcg_rm);
3315         } else {
3316             tcg_gen_add_i64(tcg_result, tcg_rn, tcg_rm);
3317         }
3318     } else {
3319         if (sub_op) {
3320             gen_sub_CC(sf, tcg_result, tcg_rn, tcg_rm);
3321         } else {
3322             gen_add_CC(sf, tcg_result, tcg_rn, tcg_rm);
3323         }
3324     }
3325
3326     if (sf) {
3327         tcg_gen_mov_i64(tcg_rd, tcg_result);
3328     } else {
3329         tcg_gen_ext32u_i64(tcg_rd, tcg_result);
3330     }
3331
3332     tcg_temp_free_i64(tcg_result);
3333 }
3334
3335 /*
3336  * C3.5.2 Add/subtract (shifted register)
3337  *
3338  *  31 30 29 28       24 23 22 21 20   16 15     10 9    5 4    0
3339  * +--+--+--+-----------+-----+--+-------+---------+------+------+
3340  * |sf|op| S| 0 1 0 1 1 |shift| 0|  Rm   |  imm6   |  Rn  |  Rd  |
3341  * +--+--+--+-----------+-----+--+-------+---------+------+------+
3342  *
3343  *    sf: 0 -> 32bit, 1 -> 64bit
3344  *    op: 0 -> add  , 1 -> sub
3345  *     S: 1 -> set flags
3346  * shift: 00 -> LSL, 01 -> LSR, 10 -> ASR, 11 -> RESERVED
3347  *  imm6: Shift amount to apply to Rm before the add/sub
3348  */
3349 static void disas_add_sub_reg(DisasContext *s, uint32_t insn)
3350 {
3351     int rd = extract32(insn, 0, 5);
3352     int rn = extract32(insn, 5, 5);
3353     int imm6 = extract32(insn, 10, 6);
3354     int rm = extract32(insn, 16, 5);
3355     int shift_type = extract32(insn, 22, 2);
3356     bool setflags = extract32(insn, 29, 1);
3357     bool sub_op = extract32(insn, 30, 1);
3358     bool sf = extract32(insn, 31, 1);
3359
3360     TCGv_i64 tcg_rd = cpu_reg(s, rd);
3361     TCGv_i64 tcg_rn, tcg_rm;
3362     TCGv_i64 tcg_result;
3363
3364     if ((shift_type == 3) || (!sf && (imm6 > 31))) {
3365         unallocated_encoding(s);
3366         return;
3367     }
3368
3369     tcg_rn = read_cpu_reg(s, rn, sf);
3370     tcg_rm = read_cpu_reg(s, rm, sf);
3371
3372     shift_reg_imm(tcg_rm, tcg_rm, sf, shift_type, imm6);
3373
3374     tcg_result = tcg_temp_new_i64();
3375
3376     if (!setflags) {
3377         if (sub_op) {
3378             tcg_gen_sub_i64(tcg_result, tcg_rn, tcg_rm);
3379         } else {
3380             tcg_gen_add_i64(tcg_result, tcg_rn, tcg_rm);
3381         }
3382     } else {
3383         if (sub_op) {
3384             gen_sub_CC(sf, tcg_result, tcg_rn, tcg_rm);
3385         } else {
3386             gen_add_CC(sf, tcg_result, tcg_rn, tcg_rm);
3387         }
3388     }
3389
3390     if (sf) {
3391         tcg_gen_mov_i64(tcg_rd, tcg_result);
3392     } else {
3393         tcg_gen_ext32u_i64(tcg_rd, tcg_result);
3394     }
3395
3396     tcg_temp_free_i64(tcg_result);
3397 }
3398
3399 /* C3.5.9 Data-processing (3 source)
3400
3401    31 30  29 28       24 23 21  20  16  15  14  10 9    5 4    0
3402   +--+------+-----------+------+------+----+------+------+------+
3403   |sf| op54 | 1 1 0 1 1 | op31 |  Rm  | o0 |  Ra  |  Rn  |  Rd  |
3404   +--+------+-----------+------+------+----+------+------+------+
3405
3406  */
3407 static void disas_data_proc_3src(DisasContext *s, uint32_t insn)
3408 {
3409     int rd = extract32(insn, 0, 5);
3410     int rn = extract32(insn, 5, 5);
3411     int ra = extract32(insn, 10, 5);
3412     int rm = extract32(insn, 16, 5);
3413     int op_id = (extract32(insn, 29, 3) << 4) |
3414         (extract32(insn, 21, 3) << 1) |
3415         extract32(insn, 15, 1);
3416     bool sf = extract32(insn, 31, 1);
3417     bool is_sub = extract32(op_id, 0, 1);
3418     bool is_high = extract32(op_id, 2, 1);
3419     bool is_signed = false;
3420     TCGv_i64 tcg_op1;
3421     TCGv_i64 tcg_op2;
3422     TCGv_i64 tcg_tmp;
3423
3424     /* Note that op_id is sf:op54:op31:o0 so it includes the 32/64 size flag */
3425     switch (op_id) {
3426     case 0x42: /* SMADDL */
3427     case 0x43: /* SMSUBL */
3428     case 0x44: /* SMULH */
3429         is_signed = true;
3430         break;
3431     case 0x0: /* MADD (32bit) */
3432     case 0x1: /* MSUB (32bit) */
3433     case 0x40: /* MADD (64bit) */
3434     case 0x41: /* MSUB (64bit) */
3435     case 0x4a: /* UMADDL */
3436     case 0x4b: /* UMSUBL */
3437     case 0x4c: /* UMULH */
3438         break;
3439     default:
3440         unallocated_encoding(s);
3441         return;
3442     }
3443
3444     if (is_high) {
3445         TCGv_i64 low_bits = tcg_temp_new_i64(); /* low bits discarded */
3446         TCGv_i64 tcg_rd = cpu_reg(s, rd);
3447         TCGv_i64 tcg_rn = cpu_reg(s, rn);
3448         TCGv_i64 tcg_rm = cpu_reg(s, rm);
3449
3450         if (is_signed) {
3451             tcg_gen_muls2_i64(low_bits, tcg_rd, tcg_rn, tcg_rm);
3452         } else {
3453             tcg_gen_mulu2_i64(low_bits, tcg_rd, tcg_rn, tcg_rm);
3454         }
3455
3456         tcg_temp_free_i64(low_bits);
3457         return;
3458     }
3459
3460     tcg_op1 = tcg_temp_new_i64();
3461     tcg_op2 = tcg_temp_new_i64();
3462     tcg_tmp = tcg_temp_new_i64();
3463
3464     if (op_id < 0x42) {
3465         tcg_gen_mov_i64(tcg_op1, cpu_reg(s, rn));
3466         tcg_gen_mov_i64(tcg_op2, cpu_reg(s, rm));
3467     } else {
3468         if (is_signed) {
3469             tcg_gen_ext32s_i64(tcg_op1, cpu_reg(s, rn));
3470             tcg_gen_ext32s_i64(tcg_op2, cpu_reg(s, rm));
3471         } else {
3472             tcg_gen_ext32u_i64(tcg_op1, cpu_reg(s, rn));
3473             tcg_gen_ext32u_i64(tcg_op2, cpu_reg(s, rm));
3474         }
3475     }
3476
3477     if (ra == 31 && !is_sub) {
3478         /* Special-case MADD with rA == XZR; it is the standard MUL alias */
3479         tcg_gen_mul_i64(cpu_reg(s, rd), tcg_op1, tcg_op2);
3480     } else {
3481         tcg_gen_mul_i64(tcg_tmp, tcg_op1, tcg_op2);
3482         if (is_sub) {
3483             tcg_gen_sub_i64(cpu_reg(s, rd), cpu_reg(s, ra), tcg_tmp);
3484         } else {
3485             tcg_gen_add_i64(cpu_reg(s, rd), cpu_reg(s, ra), tcg_tmp);
3486         }
3487     }
3488
3489     if (!sf) {
3490         tcg_gen_ext32u_i64(cpu_reg(s, rd), cpu_reg(s, rd));
3491     }
3492
3493     tcg_temp_free_i64(tcg_op1);
3494     tcg_temp_free_i64(tcg_op2);
3495     tcg_temp_free_i64(tcg_tmp);
3496 }
3497
3498 /* C3.5.3 - Add/subtract (with carry)
3499  *  31 30 29 28 27 26 25 24 23 22 21  20  16  15   10  9    5 4   0
3500  * +--+--+--+------------------------+------+---------+------+-----+
3501  * |sf|op| S| 1  1  0  1  0  0  0  0 |  rm  | opcode2 |  Rn  |  Rd |
3502  * +--+--+--+------------------------+------+---------+------+-----+
3503  *                                            [000000]
3504  */
3505
3506 static void disas_adc_sbc(DisasContext *s, uint32_t insn)
3507 {
3508     unsigned int sf, op, setflags, rm, rn, rd;
3509     TCGv_i64 tcg_y, tcg_rn, tcg_rd;
3510
3511     if (extract32(insn, 10, 6) != 0) {
3512         unallocated_encoding(s);
3513         return;
3514     }
3515
3516     sf = extract32(insn, 31, 1);
3517     op = extract32(insn, 30, 1);
3518     setflags = extract32(insn, 29, 1);
3519     rm = extract32(insn, 16, 5);
3520     rn = extract32(insn, 5, 5);
3521     rd = extract32(insn, 0, 5);
3522
3523     tcg_rd = cpu_reg(s, rd);
3524     tcg_rn = cpu_reg(s, rn);
3525
3526     if (op) {
3527         tcg_y = new_tmp_a64(s);
3528         tcg_gen_not_i64(tcg_y, cpu_reg(s, rm));
3529     } else {
3530         tcg_y = cpu_reg(s, rm);
3531     }
3532
3533     if (setflags) {
3534         gen_adc_CC(sf, tcg_rd, tcg_rn, tcg_y);
3535     } else {
3536         gen_adc(sf, tcg_rd, tcg_rn, tcg_y);
3537     }
3538 }
3539
3540 /* C3.5.4 - C3.5.5 Conditional compare (immediate / register)
3541  *  31 30 29 28 27 26 25 24 23 22 21  20    16 15  12  11  10  9   5  4 3   0
3542  * +--+--+--+------------------------+--------+------+----+--+------+--+-----+
3543  * |sf|op| S| 1  1  0  1  0  0  1  0 |imm5/rm | cond |i/r |o2|  Rn  |o3|nzcv |
3544  * +--+--+--+------------------------+--------+------+----+--+------+--+-----+
3545  *        [1]                             y                [0]       [0]
3546  */
3547 static void disas_cc(DisasContext *s, uint32_t insn)
3548 {
3549     unsigned int sf, op, y, cond, rn, nzcv, is_imm;
3550     TCGLabel *label_continue = NULL;
3551     TCGv_i64 tcg_tmp, tcg_y, tcg_rn;
3552
3553     if (!extract32(insn, 29, 1)) {
3554         unallocated_encoding(s);
3555         return;
3556     }
3557     if (insn & (1 << 10 | 1 << 4)) {
3558         unallocated_encoding(s);
3559         return;
3560     }
3561     sf = extract32(insn, 31, 1);
3562     op = extract32(insn, 30, 1);
3563     is_imm = extract32(insn, 11, 1);
3564     y = extract32(insn, 16, 5); /* y = rm (reg) or imm5 (imm) */
3565     cond = extract32(insn, 12, 4);
3566     rn = extract32(insn, 5, 5);
3567     nzcv = extract32(insn, 0, 4);
3568
3569     if (cond < 0x0e) { /* not always */
3570         TCGLabel *label_match = gen_new_label();
3571         label_continue = gen_new_label();
3572         arm_gen_test_cc(cond, label_match);
3573         /* nomatch: */
3574         tcg_tmp = tcg_temp_new_i64();
3575         tcg_gen_movi_i64(tcg_tmp, nzcv << 28);
3576         gen_set_nzcv(tcg_tmp);
3577         tcg_temp_free_i64(tcg_tmp);
3578         tcg_gen_br(label_continue);
3579         gen_set_label(label_match);
3580     }
3581     /* match, or condition is always */
3582     if (is_imm) {
3583         tcg_y = new_tmp_a64(s);
3584         tcg_gen_movi_i64(tcg_y, y);
3585     } else {
3586         tcg_y = cpu_reg(s, y);
3587     }
3588     tcg_rn = cpu_reg(s, rn);
3589
3590     tcg_tmp = tcg_temp_new_i64();
3591     if (op) {
3592         gen_sub_CC(sf, tcg_tmp, tcg_rn, tcg_y);
3593     } else {
3594         gen_add_CC(sf, tcg_tmp, tcg_rn, tcg_y);
3595     }
3596     tcg_temp_free_i64(tcg_tmp);
3597
3598     if (cond < 0x0e) { /* continue */
3599         gen_set_label(label_continue);
3600     }
3601 }
3602
3603 /* C3.5.6 Conditional select
3604  *   31   30  29  28             21 20  16 15  12 11 10 9    5 4    0
3605  * +----+----+---+-----------------+------+------+-----+------+------+
3606  * | sf | op | S | 1 1 0 1 0 1 0 0 |  Rm  | cond | op2 |  Rn  |  Rd  |
3607  * +----+----+---+-----------------+------+------+-----+------+------+
3608  */
3609 static void disas_cond_select(DisasContext *s, uint32_t insn)
3610 {
3611     unsigned int sf, else_inv, rm, cond, else_inc, rn, rd;
3612     TCGv_i64 tcg_rd, tcg_src;
3613
3614     if (extract32(insn, 29, 1) || extract32(insn, 11, 1)) {
3615         /* S == 1 or op2<1> == 1 */
3616         unallocated_encoding(s);
3617         return;
3618     }
3619     sf = extract32(insn, 31, 1);
3620     else_inv = extract32(insn, 30, 1);
3621     rm = extract32(insn, 16, 5);
3622     cond = extract32(insn, 12, 4);
3623     else_inc = extract32(insn, 10, 1);
3624     rn = extract32(insn, 5, 5);
3625     rd = extract32(insn, 0, 5);
3626
3627     if (rd == 31) {
3628         /* silly no-op write; until we use movcond we must special-case
3629          * this to avoid a dead temporary across basic blocks.
3630          */
3631         return;
3632     }
3633
3634     tcg_rd = cpu_reg(s, rd);
3635
3636     if (cond >= 0x0e) { /* condition "always" */
3637         tcg_src = read_cpu_reg(s, rn, sf);
3638         tcg_gen_mov_i64(tcg_rd, tcg_src);
3639     } else {
3640         /* OPTME: we could use movcond here, at the cost of duplicating
3641          * a lot of the arm_gen_test_cc() logic.
3642          */
3643         TCGLabel *label_match = gen_new_label();
3644         TCGLabel *label_continue = gen_new_label();
3645
3646         arm_gen_test_cc(cond, label_match);
3647         /* nomatch: */
3648         tcg_src = cpu_reg(s, rm);
3649
3650         if (else_inv && else_inc) {
3651             tcg_gen_neg_i64(tcg_rd, tcg_src);
3652         } else if (else_inv) {
3653             tcg_gen_not_i64(tcg_rd, tcg_src);
3654         } else if (else_inc) {
3655             tcg_gen_addi_i64(tcg_rd, tcg_src, 1);
3656         } else {
3657             tcg_gen_mov_i64(tcg_rd, tcg_src);
3658         }
3659         if (!sf) {
3660             tcg_gen_ext32u_i64(tcg_rd, tcg_rd);
3661         }
3662         tcg_gen_br(label_continue);
3663         /* match: */
3664         gen_set_label(label_match);
3665         tcg_src = read_cpu_reg(s, rn, sf);
3666         tcg_gen_mov_i64(tcg_rd, tcg_src);
3667         /* continue: */
3668         gen_set_label(label_continue);
3669     }
3670 }
3671
3672 static void handle_clz(DisasContext *s, unsigned int sf,
3673                        unsigned int rn, unsigned int rd)
3674 {
3675     TCGv_i64 tcg_rd, tcg_rn;
3676     tcg_rd = cpu_reg(s, rd);
3677     tcg_rn = cpu_reg(s, rn);
3678
3679     if (sf) {
3680         gen_helper_clz64(tcg_rd, tcg_rn);
3681     } else {
3682         TCGv_i32 tcg_tmp32 = tcg_temp_new_i32();
3683         tcg_gen_trunc_i64_i32(tcg_tmp32, tcg_rn);
3684         gen_helper_clz(tcg_tmp32, tcg_tmp32);
3685         tcg_gen_extu_i32_i64(tcg_rd, tcg_tmp32);
3686         tcg_temp_free_i32(tcg_tmp32);
3687     }
3688 }
3689
3690 static void handle_cls(DisasContext *s, unsigned int sf,
3691                        unsigned int rn, unsigned int rd)
3692 {
3693     TCGv_i64 tcg_rd, tcg_rn;
3694     tcg_rd = cpu_reg(s, rd);
3695     tcg_rn = cpu_reg(s, rn);
3696
3697     if (sf) {
3698         gen_helper_cls64(tcg_rd, tcg_rn);
3699     } else {
3700         TCGv_i32 tcg_tmp32 = tcg_temp_new_i32();
3701         tcg_gen_trunc_i64_i32(tcg_tmp32, tcg_rn);
3702         gen_helper_cls32(tcg_tmp32, tcg_tmp32);
3703         tcg_gen_extu_i32_i64(tcg_rd, tcg_tmp32);
3704         tcg_temp_free_i32(tcg_tmp32);
3705     }
3706 }
3707
3708 static void handle_rbit(DisasContext *s, unsigned int sf,
3709                         unsigned int rn, unsigned int rd)
3710 {
3711     TCGv_i64 tcg_rd, tcg_rn;
3712     tcg_rd = cpu_reg(s, rd);
3713     tcg_rn = cpu_reg(s, rn);
3714
3715     if (sf) {
3716         gen_helper_rbit64(tcg_rd, tcg_rn);
3717     } else {
3718         TCGv_i32 tcg_tmp32 = tcg_temp_new_i32();
3719         tcg_gen_trunc_i64_i32(tcg_tmp32, tcg_rn);
3720         gen_helper_rbit(tcg_tmp32, tcg_tmp32);
3721         tcg_gen_extu_i32_i64(tcg_rd, tcg_tmp32);
3722         tcg_temp_free_i32(tcg_tmp32);
3723     }
3724 }
3725
3726 /* C5.6.149 REV with sf==1, opcode==3 ("REV64") */
3727 static void handle_rev64(DisasContext *s, unsigned int sf,
3728                          unsigned int rn, unsigned int rd)
3729 {
3730     if (!sf) {
3731         unallocated_encoding(s);
3732         return;
3733     }
3734     tcg_gen_bswap64_i64(cpu_reg(s, rd), cpu_reg(s, rn));
3735 }
3736
3737 /* C5.6.149 REV with sf==0, opcode==2
3738  * C5.6.151 REV32 (sf==1, opcode==2)
3739  */
3740 static void handle_rev32(DisasContext *s, unsigned int sf,
3741                          unsigned int rn, unsigned int rd)
3742 {
3743     TCGv_i64 tcg_rd = cpu_reg(s, rd);
3744
3745     if (sf) {
3746         TCGv_i64 tcg_tmp = tcg_temp_new_i64();
3747         TCGv_i64 tcg_rn = read_cpu_reg(s, rn, sf);
3748
3749         /* bswap32_i64 requires zero high word */
3750         tcg_gen_ext32u_i64(tcg_tmp, tcg_rn);
3751         tcg_gen_bswap32_i64(tcg_rd, tcg_tmp);
3752         tcg_gen_shri_i64(tcg_tmp, tcg_rn, 32);
3753         tcg_gen_bswap32_i64(tcg_tmp, tcg_tmp);
3754         tcg_gen_concat32_i64(tcg_rd, tcg_rd, tcg_tmp);
3755
3756         tcg_temp_free_i64(tcg_tmp);
3757     } else {
3758         tcg_gen_ext32u_i64(tcg_rd, cpu_reg(s, rn));
3759         tcg_gen_bswap32_i64(tcg_rd, tcg_rd);
3760     }
3761 }
3762
3763 /* C5.6.150 REV16 (opcode==1) */
3764 static void handle_rev16(DisasContext *s, unsigned int sf,
3765                          unsigned int rn, unsigned int rd)
3766 {
3767     TCGv_i64 tcg_rd = cpu_reg(s, rd);
3768     TCGv_i64 tcg_tmp = tcg_temp_new_i64();
3769     TCGv_i64 tcg_rn = read_cpu_reg(s, rn, sf);
3770
3771     tcg_gen_andi_i64(tcg_tmp, tcg_rn, 0xffff);
3772     tcg_gen_bswap16_i64(tcg_rd, tcg_tmp);
3773
3774     tcg_gen_shri_i64(tcg_tmp, tcg_rn, 16);
3775     tcg_gen_andi_i64(tcg_tmp, tcg_tmp, 0xffff);
3776     tcg_gen_bswap16_i64(tcg_tmp, tcg_tmp);
3777     tcg_gen_deposit_i64(tcg_rd, tcg_rd, tcg_tmp, 16, 16);
3778
3779     if (sf) {
3780         tcg_gen_shri_i64(tcg_tmp, tcg_rn, 32);
3781         tcg_gen_andi_i64(tcg_tmp, tcg_tmp, 0xffff);
3782         tcg_gen_bswap16_i64(tcg_tmp, tcg_tmp);
3783         tcg_gen_deposit_i64(tcg_rd, tcg_rd, tcg_tmp, 32, 16);
3784
3785         tcg_gen_shri_i64(tcg_tmp, tcg_rn, 48);
3786         tcg_gen_bswap16_i64(tcg_tmp, tcg_tmp);
3787         tcg_gen_deposit_i64(tcg_rd, tcg_rd, tcg_tmp, 48, 16);
3788     }
3789
3790     tcg_temp_free_i64(tcg_tmp);
3791 }
3792
3793 /* C3.5.7 Data-processing (1 source)
3794  *   31  30  29  28             21 20     16 15    10 9    5 4    0
3795  * +----+---+---+-----------------+---------+--------+------+------+
3796  * | sf | 1 | S | 1 1 0 1 0 1 1 0 | opcode2 | opcode |  Rn  |  Rd  |
3797  * +----+---+---+-----------------+---------+--------+------+------+
3798  */
3799 static void disas_data_proc_1src(DisasContext *s, uint32_t insn)
3800 {
3801     unsigned int sf, opcode, rn, rd;
3802
3803     if (extract32(insn, 29, 1) || extract32(insn, 16, 5)) {
3804         unallocated_encoding(s);
3805         return;
3806     }
3807
3808     sf = extract32(insn, 31, 1);
3809     opcode = extract32(insn, 10, 6);
3810     rn = extract32(insn, 5, 5);
3811     rd = extract32(insn, 0, 5);
3812
3813     switch (opcode) {
3814     case 0: /* RBIT */
3815         handle_rbit(s, sf, rn, rd);
3816         break;
3817     case 1: /* REV16 */
3818         handle_rev16(s, sf, rn, rd);
3819         break;
3820     case 2: /* REV32 */
3821         handle_rev32(s, sf, rn, rd);
3822         break;
3823     case 3: /* REV64 */
3824         handle_rev64(s, sf, rn, rd);
3825         break;
3826     case 4: /* CLZ */
3827         handle_clz(s, sf, rn, rd);
3828         break;
3829     case 5: /* CLS */
3830         handle_cls(s, sf, rn, rd);
3831         break;
3832     }
3833 }
3834
3835 static void handle_div(DisasContext *s, bool is_signed, unsigned int sf,
3836                        unsigned int rm, unsigned int rn, unsigned int rd)
3837 {
3838     TCGv_i64 tcg_n, tcg_m, tcg_rd;
3839     tcg_rd = cpu_reg(s, rd);
3840
3841     if (!sf && is_signed) {
3842         tcg_n = new_tmp_a64(s);
3843         tcg_m = new_tmp_a64(s);
3844         tcg_gen_ext32s_i64(tcg_n, cpu_reg(s, rn));
3845         tcg_gen_ext32s_i64(tcg_m, cpu_reg(s, rm));
3846     } else {
3847         tcg_n = read_cpu_reg(s, rn, sf);
3848         tcg_m = read_cpu_reg(s, rm, sf);
3849     }
3850
3851     if (is_signed) {
3852         gen_helper_sdiv64(tcg_rd, tcg_n, tcg_m);
3853     } else {
3854         gen_helper_udiv64(tcg_rd, tcg_n, tcg_m);
3855     }
3856
3857     if (!sf) { /* zero extend final result */
3858         tcg_gen_ext32u_i64(tcg_rd, tcg_rd);
3859     }
3860 }
3861
3862 /* C5.6.115 LSLV, C5.6.118 LSRV, C5.6.17 ASRV, C5.6.154 RORV */
3863 static void handle_shift_reg(DisasContext *s,
3864                              enum a64_shift_type shift_type, unsigned int sf,
3865                              unsigned int rm, unsigned int rn, unsigned int rd)
3866 {
3867     TCGv_i64 tcg_shift = tcg_temp_new_i64();
3868     TCGv_i64 tcg_rd = cpu_reg(s, rd);
3869     TCGv_i64 tcg_rn = read_cpu_reg(s, rn, sf);
3870
3871     tcg_gen_andi_i64(tcg_shift, cpu_reg(s, rm), sf ? 63 : 31);
3872     shift_reg(tcg_rd, tcg_rn, sf, shift_type, tcg_shift);
3873     tcg_temp_free_i64(tcg_shift);
3874 }
3875
3876 /* CRC32[BHWX], CRC32C[BHWX] */
3877 static void handle_crc32(DisasContext *s,
3878                          unsigned int sf, unsigned int sz, bool crc32c,
3879                          unsigned int rm, unsigned int rn, unsigned int rd)
3880 {
3881     TCGv_i64 tcg_acc, tcg_val;
3882     TCGv_i32 tcg_bytes;
3883
3884     if (!arm_dc_feature(s, ARM_FEATURE_CRC)
3885         || (sf == 1 && sz != 3)
3886         || (sf == 0 && sz == 3)) {
3887         unallocated_encoding(s);
3888         return;
3889     }
3890
3891     if (sz == 3) {
3892         tcg_val = cpu_reg(s, rm);
3893     } else {
3894         uint64_t mask;
3895         switch (sz) {
3896         case 0:
3897             mask = 0xFF;
3898             break;
3899         case 1:
3900             mask = 0xFFFF;
3901             break;
3902         case 2:
3903             mask = 0xFFFFFFFF;
3904             break;
3905         default:
3906             g_assert_not_reached();
3907         }
3908         tcg_val = new_tmp_a64(s);
3909         tcg_gen_andi_i64(tcg_val, cpu_reg(s, rm), mask);
3910     }
3911
3912     tcg_acc = cpu_reg(s, rn);
3913     tcg_bytes = tcg_const_i32(1 << sz);
3914
3915     if (crc32c) {
3916         gen_helper_crc32c_64(cpu_reg(s, rd), tcg_acc, tcg_val, tcg_bytes);
3917     } else {
3918         gen_helper_crc32_64(cpu_reg(s, rd), tcg_acc, tcg_val, tcg_bytes);
3919     }
3920
3921     tcg_temp_free_i32(tcg_bytes);
3922 }
3923
3924 /* C3.5.8 Data-processing (2 source)
3925  *   31   30  29 28             21 20  16 15    10 9    5 4    0
3926  * +----+---+---+-----------------+------+--------+------+------+
3927  * | sf | 0 | S | 1 1 0 1 0 1 1 0 |  Rm  | opcode |  Rn  |  Rd  |
3928  * +----+---+---+-----------------+------+--------+------+------+
3929  */
3930 static void disas_data_proc_2src(DisasContext *s, uint32_t insn)
3931 {
3932     unsigned int sf, rm, opcode, rn, rd;
3933     sf = extract32(insn, 31, 1);
3934     rm = extract32(insn, 16, 5);
3935     opcode = extract32(insn, 10, 6);
3936     rn = extract32(insn, 5, 5);
3937     rd = extract32(insn, 0, 5);
3938
3939     if (extract32(insn, 29, 1)) {
3940         unallocated_encoding(s);
3941         return;
3942     }
3943
3944     switch (opcode) {
3945     case 2: /* UDIV */
3946         handle_div(s, false, sf, rm, rn, rd);
3947         break;
3948     case 3: /* SDIV */
3949         handle_div(s, true, sf, rm, rn, rd);
3950         break;
3951     case 8: /* LSLV */
3952         handle_shift_reg(s, A64_SHIFT_TYPE_LSL, sf, rm, rn, rd);
3953         break;
3954     case 9: /* LSRV */
3955         handle_shift_reg(s, A64_SHIFT_TYPE_LSR, sf, rm, rn, rd);
3956         break;
3957     case 10: /* ASRV */
3958         handle_shift_reg(s, A64_SHIFT_TYPE_ASR, sf, rm, rn, rd);
3959         break;
3960     case 11: /* RORV */
3961         handle_shift_reg(s, A64_SHIFT_TYPE_ROR, sf, rm, rn, rd);
3962         break;
3963     case 16:
3964     case 17:
3965     case 18:
3966     case 19:
3967     case 20:
3968     case 21:
3969     case 22:
3970     case 23: /* CRC32 */
3971     {
3972         int sz = extract32(opcode, 0, 2);
3973         bool crc32c = extract32(opcode, 2, 1);
3974         handle_crc32(s, sf, sz, crc32c, rm, rn, rd);
3975         break;
3976     }
3977     default:
3978         unallocated_encoding(s);
3979         break;
3980     }
3981 }
3982
3983 /* C3.5 Data processing - register */
3984 static void disas_data_proc_reg(DisasContext *s, uint32_t insn)
3985 {
3986     switch (extract32(insn, 24, 5)) {
3987     case 0x0a: /* Logical (shifted register) */
3988         disas_logic_reg(s, insn);
3989         break;
3990     case 0x0b: /* Add/subtract */
3991         if (insn & (1 << 21)) { /* (extended register) */
3992             disas_add_sub_ext_reg(s, insn);
3993         } else {
3994             disas_add_sub_reg(s, insn);
3995         }
3996         break;
3997     case 0x1b: /* Data-processing (3 source) */
3998         disas_data_proc_3src(s, insn);
3999         break;
4000     case 0x1a:
4001         switch (extract32(insn, 21, 3)) {
4002         case 0x0: /* Add/subtract (with carry) */
4003             disas_adc_sbc(s, insn);
4004             break;
4005         case 0x2: /* Conditional compare */
4006             disas_cc(s, insn); /* both imm and reg forms */
4007             break;
4008         case 0x4: /* Conditional select */
4009             disas_cond_select(s, insn);
4010             break;
4011         case 0x6: /* Data-processing */
4012             if (insn & (1 << 30)) { /* (1 source) */
4013                 disas_data_proc_1src(s, insn);
4014             } else {            /* (2 source) */
4015                 disas_data_proc_2src(s, insn);
4016             }
4017             break;
4018         default:
4019             unallocated_encoding(s);
4020             break;
4021         }
4022         break;
4023     default:
4024         unallocated_encoding(s);
4025         break;
4026     }
4027 }
4028
4029 static void handle_fp_compare(DisasContext *s, bool is_double,
4030                               unsigned int rn, unsigned int rm,
4031                               bool cmp_with_zero, bool signal_all_nans)
4032 {
4033     TCGv_i64 tcg_flags = tcg_temp_new_i64();
4034     TCGv_ptr fpst = get_fpstatus_ptr();
4035
4036     if (is_double) {
4037         TCGv_i64 tcg_vn, tcg_vm;
4038
4039         tcg_vn = read_fp_dreg(s, rn);
4040         if (cmp_with_zero) {
4041             tcg_vm = tcg_const_i64(0);
4042         } else {
4043             tcg_vm = read_fp_dreg(s, rm);
4044         }
4045         if (signal_all_nans) {
4046             gen_helper_vfp_cmped_a64(tcg_flags, tcg_vn, tcg_vm, fpst);
4047         } else {
4048             gen_helper_vfp_cmpd_a64(tcg_flags, tcg_vn, tcg_vm, fpst);
4049         }
4050         tcg_temp_free_i64(tcg_vn);
4051         tcg_temp_free_i64(tcg_vm);
4052     } else {
4053         TCGv_i32 tcg_vn, tcg_vm;
4054
4055         tcg_vn = read_fp_sreg(s, rn);
4056         if (cmp_with_zero) {
4057             tcg_vm = tcg_const_i32(0);
4058         } else {
4059             tcg_vm = read_fp_sreg(s, rm);
4060         }
4061         if (signal_all_nans) {
4062             gen_helper_vfp_cmpes_a64(tcg_flags, tcg_vn, tcg_vm, fpst);
4063         } else {
4064             gen_helper_vfp_cmps_a64(tcg_flags, tcg_vn, tcg_vm, fpst);
4065         }
4066         tcg_temp_free_i32(tcg_vn);
4067         tcg_temp_free_i32(tcg_vm);
4068     }
4069
4070     tcg_temp_free_ptr(fpst);
4071
4072     gen_set_nzcv(tcg_flags);
4073
4074     tcg_temp_free_i64(tcg_flags);
4075 }
4076
4077 /* C3.6.22 Floating point compare
4078  *   31  30  29 28       24 23  22  21 20  16 15 14 13  10    9    5 4     0
4079  * +---+---+---+-----------+------+---+------+-----+---------+------+-------+
4080  * | M | 0 | S | 1 1 1 1 0 | type | 1 |  Rm  | op  | 1 0 0 0 |  Rn  |  op2  |
4081  * +---+---+---+-----------+------+---+------+-----+---------+------+-------+
4082  */
4083 static void disas_fp_compare(DisasContext *s, uint32_t insn)
4084 {
4085     unsigned int mos, type, rm, op, rn, opc, op2r;
4086
4087     mos = extract32(insn, 29, 3);
4088     type = extract32(insn, 22, 2); /* 0 = single, 1 = double */
4089     rm = extract32(insn, 16, 5);
4090     op = extract32(insn, 14, 2);
4091     rn = extract32(insn, 5, 5);
4092     opc = extract32(insn, 3, 2);
4093     op2r = extract32(insn, 0, 3);
4094
4095     if (mos || op || op2r || type > 1) {
4096         unallocated_encoding(s);
4097         return;
4098     }
4099
4100     if (!fp_access_check(s)) {
4101         return;
4102     }
4103
4104     handle_fp_compare(s, type, rn, rm, opc & 1, opc & 2);
4105 }
4106
4107 /* C3.6.23 Floating point conditional compare
4108  *   31  30  29 28       24 23  22  21 20  16 15  12 11 10 9    5  4   3    0
4109  * +---+---+---+-----------+------+---+------+------+-----+------+----+------+
4110  * | M | 0 | S | 1 1 1 1 0 | type | 1 |  Rm  | cond | 0 1 |  Rn  | op | nzcv |
4111  * +---+---+---+-----------+------+---+------+------+-----+------+----+------+
4112  */
4113 static void disas_fp_ccomp(DisasContext *s, uint32_t insn)
4114 {
4115     unsigned int mos, type, rm, cond, rn, op, nzcv;
4116     TCGv_i64 tcg_flags;
4117     TCGLabel *label_continue = NULL;
4118
4119     mos = extract32(insn, 29, 3);
4120     type = extract32(insn, 22, 2); /* 0 = single, 1 = double */
4121     rm = extract32(insn, 16, 5);
4122     cond = extract32(insn, 12, 4);
4123     rn = extract32(insn, 5, 5);
4124     op = extract32(insn, 4, 1);
4125     nzcv = extract32(insn, 0, 4);
4126
4127     if (mos || type > 1) {
4128         unallocated_encoding(s);
4129         return;
4130     }
4131
4132     if (!fp_access_check(s)) {
4133         return;
4134     }
4135
4136     if (cond < 0x0e) { /* not always */
4137         TCGLabel *label_match = gen_new_label();
4138         label_continue = gen_new_label();
4139         arm_gen_test_cc(cond, label_match);
4140         /* nomatch: */
4141         tcg_flags = tcg_const_i64(nzcv << 28);
4142         gen_set_nzcv(tcg_flags);
4143         tcg_temp_free_i64(tcg_flags);
4144         tcg_gen_br(label_continue);
4145         gen_set_label(label_match);
4146     }
4147
4148     handle_fp_compare(s, type, rn, rm, false, op);
4149
4150     if (cond < 0x0e) {
4151         gen_set_label(label_continue);
4152     }
4153 }
4154
4155 /* copy src FP register to dst FP register; type specifies single or double */
4156 static void gen_mov_fp2fp(DisasContext *s, int type, int dst, int src)
4157 {
4158     if (type) {
4159         TCGv_i64 v = read_fp_dreg(s, src);
4160         write_fp_dreg(s, dst, v);
4161         tcg_temp_free_i64(v);
4162     } else {
4163         TCGv_i32 v = read_fp_sreg(s, src);
4164         write_fp_sreg(s, dst, v);
4165         tcg_temp_free_i32(v);
4166     }
4167 }
4168
4169 /* C3.6.24 Floating point conditional select
4170  *   31  30  29 28       24 23  22  21 20  16 15  12 11 10 9    5 4    0
4171  * +---+---+---+-----------+------+---+------+------+-----+------+------+
4172  * | M | 0 | S | 1 1 1 1 0 | type | 1 |  Rm  | cond | 1 1 |  Rn  |  Rd  |
4173  * +---+---+---+-----------+------+---+------+------+-----+------+------+
4174  */
4175 static void disas_fp_csel(DisasContext *s, uint32_t insn)
4176 {
4177     unsigned int mos, type, rm, cond, rn, rd;
4178     TCGLabel *label_continue = NULL;
4179
4180     mos = extract32(insn, 29, 3);
4181     type = extract32(insn, 22, 2); /* 0 = single, 1 = double */
4182     rm = extract32(insn, 16, 5);
4183     cond = extract32(insn, 12, 4);
4184     rn = extract32(insn, 5, 5);
4185     rd = extract32(insn, 0, 5);
4186
4187     if (mos || type > 1) {
4188         unallocated_encoding(s);
4189         return;
4190     }
4191
4192     if (!fp_access_check(s)) {
4193         return;
4194     }
4195
4196     if (cond < 0x0e) { /* not always */
4197         TCGLabel *label_match = gen_new_label();
4198         label_continue = gen_new_label();
4199         arm_gen_test_cc(cond, label_match);
4200         /* nomatch: */
4201         gen_mov_fp2fp(s, type, rd, rm);
4202         tcg_gen_br(label_continue);
4203         gen_set_label(label_match);
4204     }
4205
4206     gen_mov_fp2fp(s, type, rd, rn);
4207
4208     if (cond < 0x0e) { /* continue */
4209         gen_set_label(label_continue);
4210     }
4211 }
4212
4213 /* C3.6.25 Floating-point data-processing (1 source) - single precision */
4214 static void handle_fp_1src_single(DisasContext *s, int opcode, int rd, int rn)
4215 {
4216     TCGv_ptr fpst;
4217     TCGv_i32 tcg_op;
4218     TCGv_i32 tcg_res;
4219
4220     fpst = get_fpstatus_ptr();
4221     tcg_op = read_fp_sreg(s, rn);
4222     tcg_res = tcg_temp_new_i32();
4223
4224     switch (opcode) {
4225     case 0x0: /* FMOV */
4226         tcg_gen_mov_i32(tcg_res, tcg_op);
4227         break;
4228     case 0x1: /* FABS */
4229         gen_helper_vfp_abss(tcg_res, tcg_op);
4230         break;
4231     case 0x2: /* FNEG */
4232         gen_helper_vfp_negs(tcg_res, tcg_op);
4233         break;
4234     case 0x3: /* FSQRT */
4235         gen_helper_vfp_sqrts(tcg_res, tcg_op, cpu_env);
4236         break;
4237     case 0x8: /* FRINTN */
4238     case 0x9: /* FRINTP */
4239     case 0xa: /* FRINTM */
4240     case 0xb: /* FRINTZ */
4241     case 0xc: /* FRINTA */
4242     {
4243         TCGv_i32 tcg_rmode = tcg_const_i32(arm_rmode_to_sf(opcode & 7));
4244
4245         gen_helper_set_rmode(tcg_rmode, tcg_rmode, cpu_env);
4246         gen_helper_rints(tcg_res, tcg_op, fpst);
4247
4248         gen_helper_set_rmode(tcg_rmode, tcg_rmode, cpu_env);
4249         tcg_temp_free_i32(tcg_rmode);
4250         break;
4251     }
4252     case 0xe: /* FRINTX */
4253         gen_helper_rints_exact(tcg_res, tcg_op, fpst);
4254         break;
4255     case 0xf: /* FRINTI */
4256         gen_helper_rints(tcg_res, tcg_op, fpst);
4257         break;
4258     default:
4259         abort();
4260     }
4261
4262     write_fp_sreg(s, rd, tcg_res);
4263
4264     tcg_temp_free_ptr(fpst);
4265     tcg_temp_free_i32(tcg_op);
4266     tcg_temp_free_i32(tcg_res);
4267 }
4268
4269 /* C3.6.25 Floating-point data-processing (1 source) - double precision */
4270 static void handle_fp_1src_double(DisasContext *s, int opcode, int rd, int rn)
4271 {
4272     TCGv_ptr fpst;
4273     TCGv_i64 tcg_op;
4274     TCGv_i64 tcg_res;
4275
4276     fpst = get_fpstatus_ptr();
4277     tcg_op = read_fp_dreg(s, rn);
4278     tcg_res = tcg_temp_new_i64();
4279
4280     switch (opcode) {
4281     case 0x0: /* FMOV */
4282         tcg_gen_mov_i64(tcg_res, tcg_op);
4283         break;
4284     case 0x1: /* FABS */
4285         gen_helper_vfp_absd(tcg_res, tcg_op);
4286         break;
4287     case 0x2: /* FNEG */
4288         gen_helper_vfp_negd(tcg_res, tcg_op);
4289         break;
4290     case 0x3: /* FSQRT */
4291         gen_helper_vfp_sqrtd(tcg_res, tcg_op, cpu_env);
4292         break;
4293     case 0x8: /* FRINTN */
4294     case 0x9: /* FRINTP */
4295     case 0xa: /* FRINTM */
4296     case 0xb: /* FRINTZ */
4297     case 0xc: /* FRINTA */
4298     {
4299         TCGv_i32 tcg_rmode = tcg_const_i32(arm_rmode_to_sf(opcode & 7));
4300
4301         gen_helper_set_rmode(tcg_rmode, tcg_rmode, cpu_env);
4302         gen_helper_rintd(tcg_res, tcg_op, fpst);
4303
4304         gen_helper_set_rmode(tcg_rmode, tcg_rmode, cpu_env);
4305         tcg_temp_free_i32(tcg_rmode);
4306         break;
4307     }
4308     case 0xe: /* FRINTX */
4309         gen_helper_rintd_exact(tcg_res, tcg_op, fpst);
4310         break;
4311     case 0xf: /* FRINTI */
4312         gen_helper_rintd(tcg_res, tcg_op, fpst);
4313         break;
4314     default:
4315         abort();
4316     }
4317
4318     write_fp_dreg(s, rd, tcg_res);
4319
4320     tcg_temp_free_ptr(fpst);
4321     tcg_temp_free_i64(tcg_op);
4322     tcg_temp_free_i64(tcg_res);
4323 }
4324
4325 static void handle_fp_fcvt(DisasContext *s, int opcode,
4326                            int rd, int rn, int dtype, int ntype)
4327 {
4328     switch (ntype) {
4329     case 0x0:
4330     {
4331         TCGv_i32 tcg_rn = read_fp_sreg(s, rn);
4332         if (dtype == 1) {
4333             /* Single to double */
4334             TCGv_i64 tcg_rd = tcg_temp_new_i64();
4335             gen_helper_vfp_fcvtds(tcg_rd, tcg_rn, cpu_env);
4336             write_fp_dreg(s, rd, tcg_rd);
4337             tcg_temp_free_i64(tcg_rd);
4338         } else {
4339             /* Single to half */
4340             TCGv_i32 tcg_rd = tcg_temp_new_i32();
4341             gen_helper_vfp_fcvt_f32_to_f16(tcg_rd, tcg_rn, cpu_env);
4342             /* write_fp_sreg is OK here because top half of tcg_rd is zero */
4343             write_fp_sreg(s, rd, tcg_rd);
4344             tcg_temp_free_i32(tcg_rd);
4345         }
4346         tcg_temp_free_i32(tcg_rn);
4347         break;
4348     }
4349     case 0x1:
4350     {
4351         TCGv_i64 tcg_rn = read_fp_dreg(s, rn);
4352         TCGv_i32 tcg_rd = tcg_temp_new_i32();
4353         if (dtype == 0) {
4354             /* Double to single */
4355             gen_helper_vfp_fcvtsd(tcg_rd, tcg_rn, cpu_env);
4356         } else {
4357             /* Double to half */
4358             gen_helper_vfp_fcvt_f64_to_f16(tcg_rd, tcg_rn, cpu_env);
4359             /* write_fp_sreg is OK here because top half of tcg_rd is zero */
4360         }
4361         write_fp_sreg(s, rd, tcg_rd);
4362         tcg_temp_free_i32(tcg_rd);
4363         tcg_temp_free_i64(tcg_rn);
4364         break;
4365     }
4366     case 0x3:
4367     {
4368         TCGv_i32 tcg_rn = read_fp_sreg(s, rn);
4369         tcg_gen_ext16u_i32(tcg_rn, tcg_rn);
4370         if (dtype == 0) {
4371             /* Half to single */
4372             TCGv_i32 tcg_rd = tcg_temp_new_i32();
4373             gen_helper_vfp_fcvt_f16_to_f32(tcg_rd, tcg_rn, cpu_env);
4374             write_fp_sreg(s, rd, tcg_rd);
4375             tcg_temp_free_i32(tcg_rd);
4376         } else {
4377             /* Half to double */
4378             TCGv_i64 tcg_rd = tcg_temp_new_i64();
4379             gen_helper_vfp_fcvt_f16_to_f64(tcg_rd, tcg_rn, cpu_env);
4380             write_fp_dreg(s, rd, tcg_rd);
4381             tcg_temp_free_i64(tcg_rd);
4382         }
4383         tcg_temp_free_i32(tcg_rn);
4384         break;
4385     }
4386     default:
4387         abort();
4388     }
4389 }
4390
4391 /* C3.6.25 Floating point data-processing (1 source)
4392  *   31  30  29 28       24 23  22  21 20    15 14       10 9    5 4    0
4393  * +---+---+---+-----------+------+---+--------+-----------+------+------+
4394  * | M | 0 | S | 1 1 1 1 0 | type | 1 | opcode | 1 0 0 0 0 |  Rn  |  Rd  |
4395  * +---+---+---+-----------+------+---+--------+-----------+------+------+
4396  */
4397 static void disas_fp_1src(DisasContext *s, uint32_t insn)
4398 {
4399     int type = extract32(insn, 22, 2);
4400     int opcode = extract32(insn, 15, 6);
4401     int rn = extract32(insn, 5, 5);
4402     int rd = extract32(insn, 0, 5);
4403
4404     switch (opcode) {
4405     case 0x4: case 0x5: case 0x7:
4406     {
4407         /* FCVT between half, single and double precision */
4408         int dtype = extract32(opcode, 0, 2);
4409         if (type == 2 || dtype == type) {
4410             unallocated_encoding(s);
4411             return;
4412         }
4413         if (!fp_access_check(s)) {
4414             return;
4415         }
4416
4417         handle_fp_fcvt(s, opcode, rd, rn, dtype, type);
4418         break;
4419     }
4420     case 0x0 ... 0x3:
4421     case 0x8 ... 0xc:
4422     case 0xe ... 0xf:
4423         /* 32-to-32 and 64-to-64 ops */
4424         switch (type) {
4425         case 0:
4426             if (!fp_access_check(s)) {
4427                 return;
4428             }
4429
4430             handle_fp_1src_single(s, opcode, rd, rn);
4431             break;
4432         case 1:
4433             if (!fp_access_check(s)) {
4434                 return;
4435             }
4436
4437             handle_fp_1src_double(s, opcode, rd, rn);
4438             break;
4439         default:
4440             unallocated_encoding(s);
4441         }
4442         break;
4443     default:
4444         unallocated_encoding(s);
4445         break;
4446     }
4447 }
4448
4449 /* C3.6.26 Floating-point data-processing (2 source) - single precision */
4450 static void handle_fp_2src_single(DisasContext *s, int opcode,
4451                                   int rd, int rn, int rm)
4452 {
4453     TCGv_i32 tcg_op1;
4454     TCGv_i32 tcg_op2;
4455     TCGv_i32 tcg_res;
4456     TCGv_ptr fpst;
4457
4458     tcg_res = tcg_temp_new_i32();
4459     fpst = get_fpstatus_ptr();
4460     tcg_op1 = read_fp_sreg(s, rn);
4461     tcg_op2 = read_fp_sreg(s, rm);
4462
4463     switch (opcode) {
4464     case 0x0: /* FMUL */
4465         gen_helper_vfp_muls(tcg_res, tcg_op1, tcg_op2, fpst);
4466         break;
4467     case 0x1: /* FDIV */
4468         gen_helper_vfp_divs(tcg_res, tcg_op1, tcg_op2, fpst);
4469         break;
4470     case 0x2: /* FADD */
4471         gen_helper_vfp_adds(tcg_res, tcg_op1, tcg_op2, fpst);
4472         break;
4473     case 0x3: /* FSUB */
4474         gen_helper_vfp_subs(tcg_res, tcg_op1, tcg_op2, fpst);
4475         break;
4476     case 0x4: /* FMAX */
4477         gen_helper_vfp_maxs(tcg_res, tcg_op1, tcg_op2, fpst);
4478         break;
4479     case 0x5: /* FMIN */
4480         gen_helper_vfp_mins(tcg_res, tcg_op1, tcg_op2, fpst);
4481         break;
4482     case 0x6: /* FMAXNM */
4483         gen_helper_vfp_maxnums(tcg_res, tcg_op1, tcg_op2, fpst);
4484         break;
4485     case 0x7: /* FMINNM */
4486         gen_helper_vfp_minnums(tcg_res, tcg_op1, tcg_op2, fpst);
4487         break;
4488     case 0x8: /* FNMUL */
4489         gen_helper_vfp_muls(tcg_res, tcg_op1, tcg_op2, fpst);
4490         gen_helper_vfp_negs(tcg_res, tcg_res);
4491         break;
4492     }
4493
4494     write_fp_sreg(s, rd, tcg_res);
4495
4496     tcg_temp_free_ptr(fpst);
4497     tcg_temp_free_i32(tcg_op1);
4498     tcg_temp_free_i32(tcg_op2);
4499     tcg_temp_free_i32(tcg_res);
4500 }
4501
4502 /* C3.6.26 Floating-point data-processing (2 source) - double precision */
4503 static void handle_fp_2src_double(DisasContext *s, int opcode,
4504                                   int rd, int rn, int rm)
4505 {
4506     TCGv_i64 tcg_op1;
4507     TCGv_i64 tcg_op2;
4508     TCGv_i64 tcg_res;
4509     TCGv_ptr fpst;
4510
4511     tcg_res = tcg_temp_new_i64();
4512     fpst = get_fpstatus_ptr();
4513     tcg_op1 = read_fp_dreg(s, rn);
4514     tcg_op2 = read_fp_dreg(s, rm);
4515
4516     switch (opcode) {
4517     case 0x0: /* FMUL */
4518         gen_helper_vfp_muld(tcg_res, tcg_op1, tcg_op2, fpst);
4519         break;
4520     case 0x1: /* FDIV */
4521         gen_helper_vfp_divd(tcg_res, tcg_op1, tcg_op2, fpst);
4522         break;
4523     case 0x2: /* FADD */
4524         gen_helper_vfp_addd(tcg_res, tcg_op1, tcg_op2, fpst);
4525         break;
4526     case 0x3: /* FSUB */
4527         gen_helper_vfp_subd(tcg_res, tcg_op1, tcg_op2, fpst);
4528         break;
4529     case 0x4: /* FMAX */
4530         gen_helper_vfp_maxd(tcg_res, tcg_op1, tcg_op2, fpst);
4531         break;
4532     case 0x5: /* FMIN */
4533         gen_helper_vfp_mind(tcg_res, tcg_op1, tcg_op2, fpst);
4534         break;
4535     case 0x6: /* FMAXNM */
4536         gen_helper_vfp_maxnumd(tcg_res, tcg_op1, tcg_op2, fpst);
4537         break;
4538     case 0x7: /* FMINNM */
4539         gen_helper_vfp_minnumd(tcg_res, tcg_op1, tcg_op2, fpst);
4540         break;
4541     case 0x8: /* FNMUL */
4542         gen_helper_vfp_muld(tcg_res, tcg_op1, tcg_op2, fpst);
4543         gen_helper_vfp_negd(tcg_res, tcg_res);
4544         break;
4545     }
4546
4547     write_fp_dreg(s, rd, tcg_res);
4548
4549     tcg_temp_free_ptr(fpst);
4550     tcg_temp_free_i64(tcg_op1);
4551     tcg_temp_free_i64(tcg_op2);
4552     tcg_temp_free_i64(tcg_res);
4553 }
4554
4555 /* C3.6.26 Floating point data-processing (2 source)
4556  *   31  30  29 28       24 23  22  21 20  16 15    12 11 10 9    5 4    0
4557  * +---+---+---+-----------+------+---+------+--------+-----+------+------+
4558  * | M | 0 | S | 1 1 1 1 0 | type | 1 |  Rm  | opcode | 1 0 |  Rn  |  Rd  |
4559  * +---+---+---+-----------+------+---+------+--------+-----+------+------+
4560  */
4561 static void disas_fp_2src(DisasContext *s, uint32_t insn)
4562 {
4563     int type = extract32(insn, 22, 2);
4564     int rd = extract32(insn, 0, 5);
4565     int rn = extract32(insn, 5, 5);
4566     int rm = extract32(insn, 16, 5);
4567     int opcode = extract32(insn, 12, 4);
4568
4569     if (opcode > 8) {
4570         unallocated_encoding(s);
4571         return;
4572     }
4573
4574     switch (type) {
4575     case 0:
4576         if (!fp_access_check(s)) {
4577             return;
4578         }
4579         handle_fp_2src_single(s, opcode, rd, rn, rm);
4580         break;
4581     case 1:
4582         if (!fp_access_check(s)) {
4583             return;
4584         }
4585         handle_fp_2src_double(s, opcode, rd, rn, rm);
4586         break;
4587     default:
4588         unallocated_encoding(s);
4589     }
4590 }
4591
4592 /* C3.6.27 Floating-point data-processing (3 source) - single precision */
4593 static void handle_fp_3src_single(DisasContext *s, bool o0, bool o1,
4594                                   int rd, int rn, int rm, int ra)
4595 {
4596     TCGv_i32 tcg_op1, tcg_op2, tcg_op3;
4597     TCGv_i32 tcg_res = tcg_temp_new_i32();
4598     TCGv_ptr fpst = get_fpstatus_ptr();
4599
4600     tcg_op1 = read_fp_sreg(s, rn);
4601     tcg_op2 = read_fp_sreg(s, rm);
4602     tcg_op3 = read_fp_sreg(s, ra);
4603
4604     /* These are fused multiply-add, and must be done as one
4605      * floating point operation with no rounding between the
4606      * multiplication and addition steps.
4607      * NB that doing the negations here as separate steps is
4608      * correct : an input NaN should come out with its sign bit
4609      * flipped if it is a negated-input.
4610      */
4611     if (o1 == true) {
4612         gen_helper_vfp_negs(tcg_op3, tcg_op3);
4613     }
4614
4615     if (o0 != o1) {
4616         gen_helper_vfp_negs(tcg_op1, tcg_op1);
4617     }
4618
4619     gen_helper_vfp_muladds(tcg_res, tcg_op1, tcg_op2, tcg_op3, fpst);
4620
4621     write_fp_sreg(s, rd, tcg_res);
4622
4623     tcg_temp_free_ptr(fpst);
4624     tcg_temp_free_i32(tcg_op1);
4625     tcg_temp_free_i32(tcg_op2);
4626     tcg_temp_free_i32(tcg_op3);
4627     tcg_temp_free_i32(tcg_res);
4628 }
4629
4630 /* C3.6.27 Floating-point data-processing (3 source) - double precision */
4631 static void handle_fp_3src_double(DisasContext *s, bool o0, bool o1,
4632                                   int rd, int rn, int rm, int ra)
4633 {
4634     TCGv_i64 tcg_op1, tcg_op2, tcg_op3;
4635     TCGv_i64 tcg_res = tcg_temp_new_i64();
4636     TCGv_ptr fpst = get_fpstatus_ptr();
4637
4638     tcg_op1 = read_fp_dreg(s, rn);
4639     tcg_op2 = read_fp_dreg(s, rm);
4640     tcg_op3 = read_fp_dreg(s, ra);
4641
4642     /* These are fused multiply-add, and must be done as one
4643      * floating point operation with no rounding between the
4644      * multiplication and addition steps.
4645      * NB that doing the negations here as separate steps is
4646      * correct : an input NaN should come out with its sign bit
4647      * flipped if it is a negated-input.
4648      */
4649     if (o1 == true) {
4650         gen_helper_vfp_negd(tcg_op3, tcg_op3);
4651     }
4652
4653     if (o0 != o1) {
4654         gen_helper_vfp_negd(tcg_op1, tcg_op1);
4655     }
4656
4657     gen_helper_vfp_muladdd(tcg_res, tcg_op1, tcg_op2, tcg_op3, fpst);
4658
4659     write_fp_dreg(s, rd, tcg_res);
4660
4661     tcg_temp_free_ptr(fpst);
4662     tcg_temp_free_i64(tcg_op1);
4663     tcg_temp_free_i64(tcg_op2);
4664     tcg_temp_free_i64(tcg_op3);
4665     tcg_temp_free_i64(tcg_res);
4666 }
4667
4668 /* C3.6.27 Floating point data-processing (3 source)
4669  *   31  30  29 28       24 23  22  21  20  16  15  14  10 9    5 4    0
4670  * +---+---+---+-----------+------+----+------+----+------+------+------+
4671  * | M | 0 | S | 1 1 1 1 1 | type | o1 |  Rm  | o0 |  Ra  |  Rn  |  Rd  |
4672  * +---+---+---+-----------+------+----+------+----+------+------+------+
4673  */
4674 static void disas_fp_3src(DisasContext *s, uint32_t insn)
4675 {
4676     int type = extract32(insn, 22, 2);
4677     int rd = extract32(insn, 0, 5);
4678     int rn = extract32(insn, 5, 5);
4679     int ra = extract32(insn, 10, 5);
4680     int rm = extract32(insn, 16, 5);
4681     bool o0 = extract32(insn, 15, 1);
4682     bool o1 = extract32(insn, 21, 1);
4683
4684     switch (type) {
4685     case 0:
4686         if (!fp_access_check(s)) {
4687             return;
4688         }
4689         handle_fp_3src_single(s, o0, o1, rd, rn, rm, ra);
4690         break;
4691     case 1:
4692         if (!fp_access_check(s)) {
4693             return;
4694         }
4695         handle_fp_3src_double(s, o0, o1, rd, rn, rm, ra);
4696         break;
4697     default:
4698         unallocated_encoding(s);
4699     }
4700 }
4701
4702 /* C3.6.28 Floating point immediate
4703  *   31  30  29 28       24 23  22  21 20        13 12   10 9    5 4    0
4704  * +---+---+---+-----------+------+---+------------+-------+------+------+
4705  * | M | 0 | S | 1 1 1 1 0 | type | 1 |    imm8    | 1 0 0 | imm5 |  Rd  |
4706  * +---+---+---+-----------+------+---+------------+-------+------+------+
4707  */
4708 static void disas_fp_imm(DisasContext *s, uint32_t insn)
4709 {
4710     int rd = extract32(insn, 0, 5);
4711     int imm8 = extract32(insn, 13, 8);
4712     int is_double = extract32(insn, 22, 2);
4713     uint64_t imm;
4714     TCGv_i64 tcg_res;
4715
4716     if (is_double > 1) {
4717         unallocated_encoding(s);
4718         return;
4719     }
4720
4721     if (!fp_access_check(s)) {
4722         return;
4723     }
4724
4725     /* The imm8 encodes the sign bit, enough bits to represent
4726      * an exponent in the range 01....1xx to 10....0xx,
4727      * and the most significant 4 bits of the mantissa; see
4728      * VFPExpandImm() in the v8 ARM ARM.
4729      */
4730     if (is_double) {
4731         imm = (extract32(imm8, 7, 1) ? 0x8000 : 0) |
4732             (extract32(imm8, 6, 1) ? 0x3fc0 : 0x4000) |
4733             extract32(imm8, 0, 6);
4734         imm <<= 48;
4735     } else {
4736         imm = (extract32(imm8, 7, 1) ? 0x8000 : 0) |
4737             (extract32(imm8, 6, 1) ? 0x3e00 : 0x4000) |
4738             (extract32(imm8, 0, 6) << 3);
4739         imm <<= 16;
4740     }
4741
4742     tcg_res = tcg_const_i64(imm);
4743     write_fp_dreg(s, rd, tcg_res);
4744     tcg_temp_free_i64(tcg_res);
4745 }
4746
4747 /* Handle floating point <=> fixed point conversions. Note that we can
4748  * also deal with fp <=> integer conversions as a special case (scale == 64)
4749  * OPTME: consider handling that special case specially or at least skipping
4750  * the call to scalbn in the helpers for zero shifts.
4751  */
4752 static void handle_fpfpcvt(DisasContext *s, int rd, int rn, int opcode,
4753                            bool itof, int rmode, int scale, int sf, int type)
4754 {
4755     bool is_signed = !(opcode & 1);
4756     bool is_double = type;
4757     TCGv_ptr tcg_fpstatus;
4758     TCGv_i32 tcg_shift;
4759
4760     tcg_fpstatus = get_fpstatus_ptr();
4761
4762     tcg_shift = tcg_const_i32(64 - scale);
4763
4764     if (itof) {
4765         TCGv_i64 tcg_int = cpu_reg(s, rn);
4766         if (!sf) {
4767             TCGv_i64 tcg_extend = new_tmp_a64(s);
4768
4769             if (is_signed) {
4770                 tcg_gen_ext32s_i64(tcg_extend, tcg_int);
4771             } else {
4772                 tcg_gen_ext32u_i64(tcg_extend, tcg_int);
4773             }
4774
4775             tcg_int = tcg_extend;
4776         }
4777
4778         if (is_double) {
4779             TCGv_i64 tcg_double = tcg_temp_new_i64();
4780             if (is_signed) {
4781                 gen_helper_vfp_sqtod(tcg_double, tcg_int,
4782                                      tcg_shift, tcg_fpstatus);
4783             } else {
4784                 gen_helper_vfp_uqtod(tcg_double, tcg_int,
4785                                      tcg_shift, tcg_fpstatus);
4786             }
4787             write_fp_dreg(s, rd, tcg_double);
4788             tcg_temp_free_i64(tcg_double);
4789         } else {
4790             TCGv_i32 tcg_single = tcg_temp_new_i32();
4791             if (is_signed) {
4792                 gen_helper_vfp_sqtos(tcg_single, tcg_int,
4793                                      tcg_shift, tcg_fpstatus);
4794             } else {
4795                 gen_helper_vfp_uqtos(tcg_single, tcg_int,
4796                                      tcg_shift, tcg_fpstatus);
4797             }
4798             write_fp_sreg(s, rd, tcg_single);
4799             tcg_temp_free_i32(tcg_single);
4800         }
4801     } else {
4802         TCGv_i64 tcg_int = cpu_reg(s, rd);
4803         TCGv_i32 tcg_rmode;
4804
4805         if (extract32(opcode, 2, 1)) {
4806             /* There are too many rounding modes to all fit into rmode,
4807              * so FCVTA[US] is a special case.
4808              */
4809             rmode = FPROUNDING_TIEAWAY;
4810         }
4811
4812         tcg_rmode = tcg_const_i32(arm_rmode_to_sf(rmode));
4813
4814         gen_helper_set_rmode(tcg_rmode, tcg_rmode, cpu_env);
4815
4816         if (is_double) {
4817             TCGv_i64 tcg_double = read_fp_dreg(s, rn);
4818             if (is_signed) {
4819                 if (!sf) {
4820                     gen_helper_vfp_tosld(tcg_int, tcg_double,
4821                                          tcg_shift, tcg_fpstatus);
4822                 } else {
4823                     gen_helper_vfp_tosqd(tcg_int, tcg_double,
4824                                          tcg_shift, tcg_fpstatus);
4825                 }
4826             } else {
4827                 if (!sf) {
4828                     gen_helper_vfp_tould(tcg_int, tcg_double,
4829                                          tcg_shift, tcg_fpstatus);
4830                 } else {
4831                     gen_helper_vfp_touqd(tcg_int, tcg_double,
4832                                          tcg_shift, tcg_fpstatus);
4833                 }
4834             }
4835             tcg_temp_free_i64(tcg_double);
4836         } else {
4837             TCGv_i32 tcg_single = read_fp_sreg(s, rn);
4838             if (sf) {
4839                 if (is_signed) {
4840                     gen_helper_vfp_tosqs(tcg_int, tcg_single,
4841                                          tcg_shift, tcg_fpstatus);
4842                 } else {
4843                     gen_helper_vfp_touqs(tcg_int, tcg_single,
4844                                          tcg_shift, tcg_fpstatus);
4845                 }
4846             } else {
4847                 TCGv_i32 tcg_dest = tcg_temp_new_i32();
4848                 if (is_signed) {
4849                     gen_helper_vfp_tosls(tcg_dest, tcg_single,
4850                                          tcg_shift, tcg_fpstatus);
4851                 } else {
4852                     gen_helper_vfp_touls(tcg_dest, tcg_single,
4853                                          tcg_shift, tcg_fpstatus);
4854                 }
4855                 tcg_gen_extu_i32_i64(tcg_int, tcg_dest);
4856                 tcg_temp_free_i32(tcg_dest);
4857             }
4858             tcg_temp_free_i32(tcg_single);
4859         }
4860
4861         gen_helper_set_rmode(tcg_rmode, tcg_rmode, cpu_env);
4862         tcg_temp_free_i32(tcg_rmode);
4863
4864         if (!sf) {
4865             tcg_gen_ext32u_i64(tcg_int, tcg_int);
4866         }
4867     }
4868
4869     tcg_temp_free_ptr(tcg_fpstatus);
4870     tcg_temp_free_i32(tcg_shift);
4871 }
4872
4873 /* C3.6.29 Floating point <-> fixed point conversions
4874  *   31   30  29 28       24 23  22  21 20   19 18    16 15   10 9    5 4    0
4875  * +----+---+---+-----------+------+---+-------+--------+-------+------+------+
4876  * | sf | 0 | S | 1 1 1 1 0 | type | 0 | rmode | opcode | scale |  Rn  |  Rd  |
4877  * +----+---+---+-----------+------+---+-------+--------+-------+------+------+
4878  */
4879 static void disas_fp_fixed_conv(DisasContext *s, uint32_t insn)
4880 {
4881     int rd = extract32(insn, 0, 5);
4882     int rn = extract32(insn, 5, 5);
4883     int scale = extract32(insn, 10, 6);
4884     int opcode = extract32(insn, 16, 3);
4885     int rmode = extract32(insn, 19, 2);
4886     int type = extract32(insn, 22, 2);
4887     bool sbit = extract32(insn, 29, 1);
4888     bool sf = extract32(insn, 31, 1);
4889     bool itof;
4890
4891     if (sbit || (type > 1)
4892         || (!sf && scale < 32)) {
4893         unallocated_encoding(s);
4894         return;
4895     }
4896
4897     switch ((rmode << 3) | opcode) {
4898     case 0x2: /* SCVTF */
4899     case 0x3: /* UCVTF */
4900         itof = true;
4901         break;
4902     case 0x18: /* FCVTZS */
4903     case 0x19: /* FCVTZU */
4904         itof = false;
4905         break;
4906     default:
4907         unallocated_encoding(s);
4908         return;
4909     }
4910
4911     if (!fp_access_check(s)) {
4912         return;
4913     }
4914
4915     handle_fpfpcvt(s, rd, rn, opcode, itof, FPROUNDING_ZERO, scale, sf, type);
4916 }
4917
4918 static void handle_fmov(DisasContext *s, int rd, int rn, int type, bool itof)
4919 {
4920     /* FMOV: gpr to or from float, double, or top half of quad fp reg,
4921      * without conversion.
4922      */
4923
4924     if (itof) {
4925         TCGv_i64 tcg_rn = cpu_reg(s, rn);
4926
4927         switch (type) {
4928         case 0:
4929         {
4930             /* 32 bit */
4931             TCGv_i64 tmp = tcg_temp_new_i64();
4932             tcg_gen_ext32u_i64(tmp, tcg_rn);
4933             tcg_gen_st_i64(tmp, cpu_env, fp_reg_offset(s, rd, MO_64));
4934             tcg_gen_movi_i64(tmp, 0);
4935             tcg_gen_st_i64(tmp, cpu_env, fp_reg_hi_offset(s, rd));
4936             tcg_temp_free_i64(tmp);
4937             break;
4938         }
4939         case 1:
4940         {
4941             /* 64 bit */
4942             TCGv_i64 tmp = tcg_const_i64(0);
4943             tcg_gen_st_i64(tcg_rn, cpu_env, fp_reg_offset(s, rd, MO_64));
4944             tcg_gen_st_i64(tmp, cpu_env, fp_reg_hi_offset(s, rd));
4945             tcg_temp_free_i64(tmp);
4946             break;
4947         }
4948         case 2:
4949             /* 64 bit to top half. */
4950             tcg_gen_st_i64(tcg_rn, cpu_env, fp_reg_hi_offset(s, rd));
4951             break;
4952         }
4953     } else {
4954         TCGv_i64 tcg_rd = cpu_reg(s, rd);
4955
4956         switch (type) {
4957         case 0:
4958             /* 32 bit */
4959             tcg_gen_ld32u_i64(tcg_rd, cpu_env, fp_reg_offset(s, rn, MO_32));
4960             break;
4961         case 1:
4962             /* 64 bit */
4963             tcg_gen_ld_i64(tcg_rd, cpu_env, fp_reg_offset(s, rn, MO_64));
4964             break;
4965         case 2:
4966             /* 64 bits from top half */
4967             tcg_gen_ld_i64(tcg_rd, cpu_env, fp_reg_hi_offset(s, rn));
4968             break;
4969         }
4970     }
4971 }
4972
4973 /* C3.6.30 Floating point <-> integer conversions
4974  *   31   30  29 28       24 23  22  21 20   19 18 16 15         10 9  5 4  0
4975  * +----+---+---+-----------+------+---+-------+-----+-------------+----+----+
4976  * | sf | 0 | S | 1 1 1 1 0 | type | 1 | rmode | opc | 0 0 0 0 0 0 | Rn | Rd |
4977  * +----+---+---+-----------+------+---+-------+-----+-------------+----+----+
4978  */
4979 static void disas_fp_int_conv(DisasContext *s, uint32_t insn)
4980 {
4981     int rd = extract32(insn, 0, 5);
4982     int rn = extract32(insn, 5, 5);
4983     int opcode = extract32(insn, 16, 3);
4984     int rmode = extract32(insn, 19, 2);
4985     int type = extract32(insn, 22, 2);
4986     bool sbit = extract32(insn, 29, 1);
4987     bool sf = extract32(insn, 31, 1);
4988
4989     if (sbit) {
4990         unallocated_encoding(s);
4991         return;
4992     }
4993
4994     if (opcode > 5) {
4995         /* FMOV */
4996         bool itof = opcode & 1;
4997
4998         if (rmode >= 2) {
4999             unallocated_encoding(s);
5000             return;
5001         }
5002
5003         switch (sf << 3 | type << 1 | rmode) {
5004         case 0x0: /* 32 bit */
5005         case 0xa: /* 64 bit */
5006         case 0xd: /* 64 bit to top half of quad */
5007             break;
5008         default:
5009             /* all other sf/type/rmode combinations are invalid */
5010             unallocated_encoding(s);
5011             break;
5012         }
5013
5014         if (!fp_access_check(s)) {
5015             return;
5016         }
5017         handle_fmov(s, rd, rn, type, itof);
5018     } else {
5019         /* actual FP conversions */
5020         bool itof = extract32(opcode, 1, 1);
5021
5022         if (type > 1 || (rmode != 0 && opcode > 1)) {
5023             unallocated_encoding(s);
5024             return;
5025         }
5026
5027         if (!fp_access_check(s)) {
5028             return;
5029         }
5030         handle_fpfpcvt(s, rd, rn, opcode, itof, rmode, 64, sf, type);
5031     }
5032 }
5033
5034 /* FP-specific subcases of table C3-6 (SIMD and FP data processing)
5035  *   31  30  29 28     25 24                          0
5036  * +---+---+---+---------+-----------------------------+
5037  * |   | 0 |   | 1 1 1 1 |                             |
5038  * +---+---+---+---------+-----------------------------+
5039  */
5040 static void disas_data_proc_fp(DisasContext *s, uint32_t insn)
5041 {
5042     if (extract32(insn, 24, 1)) {
5043         /* Floating point data-processing (3 source) */
5044         disas_fp_3src(s, insn);
5045     } else if (extract32(insn, 21, 1) == 0) {
5046         /* Floating point to fixed point conversions */
5047         disas_fp_fixed_conv(s, insn);
5048     } else {
5049         switch (extract32(insn, 10, 2)) {
5050         case 1:
5051             /* Floating point conditional compare */
5052             disas_fp_ccomp(s, insn);
5053             break;
5054         case 2:
5055             /* Floating point data-processing (2 source) */
5056             disas_fp_2src(s, insn);
5057             break;
5058         case 3:
5059             /* Floating point conditional select */
5060             disas_fp_csel(s, insn);
5061             break;
5062         case 0:
5063             switch (ctz32(extract32(insn, 12, 4))) {
5064             case 0: /* [15:12] == xxx1 */
5065                 /* Floating point immediate */
5066                 disas_fp_imm(s, insn);
5067                 break;
5068             case 1: /* [15:12] == xx10 */
5069                 /* Floating point compare */
5070                 disas_fp_compare(s, insn);
5071                 break;
5072             case 2: /* [15:12] == x100 */
5073                 /* Floating point data-processing (1 source) */
5074                 disas_fp_1src(s, insn);
5075                 break;
5076             case 3: /* [15:12] == 1000 */
5077                 unallocated_encoding(s);
5078                 break;
5079             default: /* [15:12] == 0000 */
5080                 /* Floating point <-> integer conversions */
5081                 disas_fp_int_conv(s, insn);
5082                 break;
5083             }
5084             break;
5085         }
5086     }
5087 }
5088
5089 static void do_ext64(DisasContext *s, TCGv_i64 tcg_left, TCGv_i64 tcg_right,
5090                      int pos)
5091 {
5092     /* Extract 64 bits from the middle of two concatenated 64 bit
5093      * vector register slices left:right. The extracted bits start
5094      * at 'pos' bits into the right (least significant) side.
5095      * We return the result in tcg_right, and guarantee not to
5096      * trash tcg_left.
5097      */
5098     TCGv_i64 tcg_tmp = tcg_temp_new_i64();
5099     assert(pos > 0 && pos < 64);
5100
5101     tcg_gen_shri_i64(tcg_right, tcg_right, pos);
5102     tcg_gen_shli_i64(tcg_tmp, tcg_left, 64 - pos);
5103     tcg_gen_or_i64(tcg_right, tcg_right, tcg_tmp);
5104
5105     tcg_temp_free_i64(tcg_tmp);
5106 }
5107
5108 /* C3.6.1 EXT
5109  *   31  30 29         24 23 22  21 20  16 15  14  11 10  9    5 4    0
5110  * +---+---+-------------+-----+---+------+---+------+---+------+------+
5111  * | 0 | Q | 1 0 1 1 1 0 | op2 | 0 |  Rm  | 0 | imm4 | 0 |  Rn  |  Rd  |
5112  * +---+---+-------------+-----+---+------+---+------+---+------+------+
5113  */
5114 static void disas_simd_ext(DisasContext *s, uint32_t insn)
5115 {
5116     int is_q = extract32(insn, 30, 1);
5117     int op2 = extract32(insn, 22, 2);
5118     int imm4 = extract32(insn, 11, 4);
5119     int rm = extract32(insn, 16, 5);
5120     int rn = extract32(insn, 5, 5);
5121     int rd = extract32(insn, 0, 5);
5122     int pos = imm4 << 3;
5123     TCGv_i64 tcg_resl, tcg_resh;
5124
5125     if (op2 != 0 || (!is_q && extract32(imm4, 3, 1))) {
5126         unallocated_encoding(s);
5127         return;
5128     }
5129
5130     if (!fp_access_check(s)) {
5131         return;
5132     }
5133
5134     tcg_resh = tcg_temp_new_i64();
5135     tcg_resl = tcg_temp_new_i64();
5136
5137     /* Vd gets bits starting at pos bits into Vm:Vn. This is
5138      * either extracting 128 bits from a 128:128 concatenation, or
5139      * extracting 64 bits from a 64:64 concatenation.
5140      */
5141     if (!is_q) {
5142         read_vec_element(s, tcg_resl, rn, 0, MO_64);
5143         if (pos != 0) {
5144             read_vec_element(s, tcg_resh, rm, 0, MO_64);
5145             do_ext64(s, tcg_resh, tcg_resl, pos);
5146         }
5147         tcg_gen_movi_i64(tcg_resh, 0);
5148     } else {
5149         TCGv_i64 tcg_hh;
5150         typedef struct {
5151             int reg;
5152             int elt;
5153         } EltPosns;
5154         EltPosns eltposns[] = { {rn, 0}, {rn, 1}, {rm, 0}, {rm, 1} };
5155         EltPosns *elt = eltposns;
5156
5157         if (pos >= 64) {
5158             elt++;
5159             pos -= 64;
5160         }
5161
5162         read_vec_element(s, tcg_resl, elt->reg, elt->elt, MO_64);
5163         elt++;
5164         read_vec_element(s, tcg_resh, elt->reg, elt->elt, MO_64);
5165         elt++;
5166         if (pos != 0) {
5167             do_ext64(s, tcg_resh, tcg_resl, pos);
5168             tcg_hh = tcg_temp_new_i64();
5169             read_vec_element(s, tcg_hh, elt->reg, elt->elt, MO_64);
5170             do_ext64(s, tcg_hh, tcg_resh, pos);
5171             tcg_temp_free_i64(tcg_hh);
5172         }
5173     }
5174
5175     write_vec_element(s, tcg_resl, rd, 0, MO_64);
5176     tcg_temp_free_i64(tcg_resl);
5177     write_vec_element(s, tcg_resh, rd, 1, MO_64);
5178     tcg_temp_free_i64(tcg_resh);
5179 }
5180
5181 /* C3.6.2 TBL/TBX
5182  *   31  30 29         24 23 22  21 20  16 15  14 13  12  11 10 9    5 4    0
5183  * +---+---+-------------+-----+---+------+---+-----+----+-----+------+------+
5184  * | 0 | Q | 0 0 1 1 1 0 | op2 | 0 |  Rm  | 0 | len | op | 0 0 |  Rn  |  Rd  |
5185  * +---+---+-------------+-----+---+------+---+-----+----+-----+------+------+
5186  */
5187 static void disas_simd_tb(DisasContext *s, uint32_t insn)
5188 {
5189     int op2 = extract32(insn, 22, 2);
5190     int is_q = extract32(insn, 30, 1);
5191     int rm = extract32(insn, 16, 5);
5192     int rn = extract32(insn, 5, 5);
5193     int rd = extract32(insn, 0, 5);
5194     int is_tblx = extract32(insn, 12, 1);
5195     int len = extract32(insn, 13, 2);
5196     TCGv_i64 tcg_resl, tcg_resh, tcg_idx;
5197     TCGv_i32 tcg_regno, tcg_numregs;
5198
5199     if (op2 != 0) {
5200         unallocated_encoding(s);
5201         return;
5202     }
5203
5204     if (!fp_access_check(s)) {
5205         return;
5206     }
5207
5208     /* This does a table lookup: for every byte element in the input
5209      * we index into a table formed from up to four vector registers,
5210      * and then the output is the result of the lookups. Our helper
5211      * function does the lookup operation for a single 64 bit part of
5212      * the input.
5213      */
5214     tcg_resl = tcg_temp_new_i64();
5215     tcg_resh = tcg_temp_new_i64();
5216
5217     if (is_tblx) {
5218         read_vec_element(s, tcg_resl, rd, 0, MO_64);
5219     } else {
5220         tcg_gen_movi_i64(tcg_resl, 0);
5221     }
5222     if (is_tblx && is_q) {
5223         read_vec_element(s, tcg_resh, rd, 1, MO_64);
5224     } else {
5225         tcg_gen_movi_i64(tcg_resh, 0);
5226     }
5227
5228     tcg_idx = tcg_temp_new_i64();
5229     tcg_regno = tcg_const_i32(rn);
5230     tcg_numregs = tcg_const_i32(len + 1);
5231     read_vec_element(s, tcg_idx, rm, 0, MO_64);
5232     gen_helper_simd_tbl(tcg_resl, cpu_env, tcg_resl, tcg_idx,
5233                         tcg_regno, tcg_numregs);
5234     if (is_q) {
5235         read_vec_element(s, tcg_idx, rm, 1, MO_64);
5236         gen_helper_simd_tbl(tcg_resh, cpu_env, tcg_resh, tcg_idx,
5237                             tcg_regno, tcg_numregs);
5238     }
5239     tcg_temp_free_i64(tcg_idx);
5240     tcg_temp_free_i32(tcg_regno);
5241     tcg_temp_free_i32(tcg_numregs);
5242
5243     write_vec_element(s, tcg_resl, rd, 0, MO_64);
5244     tcg_temp_free_i64(tcg_resl);
5245     write_vec_element(s, tcg_resh, rd, 1, MO_64);
5246     tcg_temp_free_i64(tcg_resh);
5247 }
5248
5249 /* C3.6.3 ZIP/UZP/TRN
5250  *   31  30 29         24 23  22  21 20   16 15 14 12 11 10 9    5 4    0
5251  * +---+---+-------------+------+---+------+---+------------------+------+
5252  * | 0 | Q | 0 0 1 1 1 0 | size | 0 |  Rm  | 0 | opc | 1 0 |  Rn  |  Rd  |
5253  * +---+---+-------------+------+---+------+---+------------------+------+
5254  */
5255 static void disas_simd_zip_trn(DisasContext *s, uint32_t insn)
5256 {
5257     int rd = extract32(insn, 0, 5);
5258     int rn = extract32(insn, 5, 5);
5259     int rm = extract32(insn, 16, 5);
5260     int size = extract32(insn, 22, 2);
5261     /* opc field bits [1:0] indicate ZIP/UZP/TRN;
5262      * bit 2 indicates 1 vs 2 variant of the insn.
5263      */
5264     int opcode = extract32(insn, 12, 2);
5265     bool part = extract32(insn, 14, 1);
5266     bool is_q = extract32(insn, 30, 1);
5267     int esize = 8 << size;
5268     int i, ofs;
5269     int datasize = is_q ? 128 : 64;
5270     int elements = datasize / esize;
5271     TCGv_i64 tcg_res, tcg_resl, tcg_resh;
5272
5273     if (opcode == 0 || (size == 3 && !is_q)) {
5274         unallocated_encoding(s);
5275         return;
5276     }
5277
5278     if (!fp_access_check(s)) {
5279         return;
5280     }
5281
5282     tcg_resl = tcg_const_i64(0);
5283     tcg_resh = tcg_const_i64(0);
5284     tcg_res = tcg_temp_new_i64();
5285
5286     for (i = 0; i < elements; i++) {
5287         switch (opcode) {
5288         case 1: /* UZP1/2 */
5289         {
5290             int midpoint = elements / 2;
5291             if (i < midpoint) {
5292                 read_vec_element(s, tcg_res, rn, 2 * i + part, size);
5293             } else {
5294                 read_vec_element(s, tcg_res, rm,
5295                                  2 * (i - midpoint) + part, size);
5296             }
5297             break;
5298         }
5299         case 2: /* TRN1/2 */
5300             if (i & 1) {
5301                 read_vec_element(s, tcg_res, rm, (i & ~1) + part, size);
5302             } else {
5303                 read_vec_element(s, tcg_res, rn, (i & ~1) + part, size);
5304             }
5305             break;
5306         case 3: /* ZIP1/2 */
5307         {
5308             int base = part * elements / 2;
5309             if (i & 1) {
5310                 read_vec_element(s, tcg_res, rm, base + (i >> 1), size);
5311             } else {
5312                 read_vec_element(s, tcg_res, rn, base + (i >> 1), size);
5313             }
5314             break;
5315         }
5316         default:
5317             g_assert_not_reached();
5318         }
5319
5320         ofs = i * esize;
5321         if (ofs < 64) {
5322             tcg_gen_shli_i64(tcg_res, tcg_res, ofs);
5323             tcg_gen_or_i64(tcg_resl, tcg_resl, tcg_res);
5324         } else {
5325             tcg_gen_shli_i64(tcg_res, tcg_res, ofs - 64);
5326             tcg_gen_or_i64(tcg_resh, tcg_resh, tcg_res);
5327         }
5328     }
5329
5330     tcg_temp_free_i64(tcg_res);
5331
5332     write_vec_element(s, tcg_resl, rd, 0, MO_64);
5333     tcg_temp_free_i64(tcg_resl);
5334     write_vec_element(s, tcg_resh, rd, 1, MO_64);
5335     tcg_temp_free_i64(tcg_resh);
5336 }
5337
5338 static void do_minmaxop(DisasContext *s, TCGv_i32 tcg_elt1, TCGv_i32 tcg_elt2,
5339                         int opc, bool is_min, TCGv_ptr fpst)
5340 {
5341     /* Helper function for disas_simd_across_lanes: do a single precision
5342      * min/max operation on the specified two inputs,
5343      * and return the result in tcg_elt1.
5344      */
5345     if (opc == 0xc) {
5346         if (is_min) {
5347             gen_helper_vfp_minnums(tcg_elt1, tcg_elt1, tcg_elt2, fpst);
5348         } else {
5349             gen_helper_vfp_maxnums(tcg_elt1, tcg_elt1, tcg_elt2, fpst);
5350         }
5351     } else {
5352         assert(opc == 0xf);
5353         if (is_min) {
5354             gen_helper_vfp_mins(tcg_elt1, tcg_elt1, tcg_elt2, fpst);
5355         } else {
5356             gen_helper_vfp_maxs(tcg_elt1, tcg_elt1, tcg_elt2, fpst);
5357         }
5358     }
5359 }
5360
5361 /* C3.6.4 AdvSIMD across lanes
5362  *   31  30  29 28       24 23  22 21       17 16    12 11 10 9    5 4    0
5363  * +---+---+---+-----------+------+-----------+--------+-----+------+------+
5364  * | 0 | Q | U | 0 1 1 1 0 | size | 1 1 0 0 0 | opcode | 1 0 |  Rn  |  Rd  |
5365  * +---+---+---+-----------+------+-----------+--------+-----+------+------+
5366  */
5367 static void disas_simd_across_lanes(DisasContext *s, uint32_t insn)
5368 {
5369     int rd = extract32(insn, 0, 5);
5370     int rn = extract32(insn, 5, 5);
5371     int size = extract32(insn, 22, 2);
5372     int opcode = extract32(insn, 12, 5);
5373     bool is_q = extract32(insn, 30, 1);
5374     bool is_u = extract32(insn, 29, 1);
5375     bool is_fp = false;
5376     bool is_min = false;
5377     int esize;
5378     int elements;
5379     int i;
5380     TCGv_i64 tcg_res, tcg_elt;
5381
5382     switch (opcode) {
5383     case 0x1b: /* ADDV */
5384         if (is_u) {
5385             unallocated_encoding(s);
5386             return;
5387         }
5388         /* fall through */
5389     case 0x3: /* SADDLV, UADDLV */
5390     case 0xa: /* SMAXV, UMAXV */
5391     case 0x1a: /* SMINV, UMINV */
5392         if (size == 3 || (size == 2 && !is_q)) {
5393             unallocated_encoding(s);
5394             return;
5395         }
5396         break;
5397     case 0xc: /* FMAXNMV, FMINNMV */
5398     case 0xf: /* FMAXV, FMINV */
5399         if (!is_u || !is_q || extract32(size, 0, 1)) {
5400             unallocated_encoding(s);
5401             return;
5402         }
5403         /* Bit 1 of size field encodes min vs max, and actual size is always
5404          * 32 bits: adjust the size variable so following code can rely on it
5405          */
5406         is_min = extract32(size, 1, 1);
5407         is_fp = true;
5408         size = 2;
5409         break;
5410     default:
5411         unallocated_encoding(s);
5412         return;
5413     }
5414
5415     if (!fp_access_check(s)) {
5416         return;
5417     }
5418
5419     esize = 8 << size;
5420     elements = (is_q ? 128 : 64) / esize;
5421
5422     tcg_res = tcg_temp_new_i64();
5423     tcg_elt = tcg_temp_new_i64();
5424
5425     /* These instructions operate across all lanes of a vector
5426      * to produce a single result. We can guarantee that a 64
5427      * bit intermediate is sufficient:
5428      *  + for [US]ADDLV the maximum element size is 32 bits, and
5429      *    the result type is 64 bits
5430      *  + for FMAX*V, FMIN*V, ADDV the intermediate type is the
5431      *    same as the element size, which is 32 bits at most
5432      * For the integer operations we can choose to work at 64
5433      * or 32 bits and truncate at the end; for simplicity
5434      * we use 64 bits always. The floating point
5435      * ops do require 32 bit intermediates, though.
5436      */
5437     if (!is_fp) {
5438         read_vec_element(s, tcg_res, rn, 0, size | (is_u ? 0 : MO_SIGN));
5439
5440         for (i = 1; i < elements; i++) {
5441             read_vec_element(s, tcg_elt, rn, i, size | (is_u ? 0 : MO_SIGN));
5442
5443             switch (opcode) {
5444             case 0x03: /* SADDLV / UADDLV */
5445             case 0x1b: /* ADDV */
5446                 tcg_gen_add_i64(tcg_res, tcg_res, tcg_elt);
5447                 break;
5448             case 0x0a: /* SMAXV / UMAXV */
5449                 tcg_gen_movcond_i64(is_u ? TCG_COND_GEU : TCG_COND_GE,
5450                                     tcg_res,
5451                                     tcg_res, tcg_elt, tcg_res, tcg_elt);
5452                 break;
5453             case 0x1a: /* SMINV / UMINV */
5454                 tcg_gen_movcond_i64(is_u ? TCG_COND_LEU : TCG_COND_LE,
5455                                     tcg_res,
5456                                     tcg_res, tcg_elt, tcg_res, tcg_elt);
5457                 break;
5458                 break;
5459             default:
5460                 g_assert_not_reached();
5461             }
5462
5463         }
5464     } else {
5465         /* Floating point ops which work on 32 bit (single) intermediates.
5466          * Note that correct NaN propagation requires that we do these
5467          * operations in exactly the order specified by the pseudocode.
5468          */
5469         TCGv_i32 tcg_elt1 = tcg_temp_new_i32();
5470         TCGv_i32 tcg_elt2 = tcg_temp_new_i32();
5471         TCGv_i32 tcg_elt3 = tcg_temp_new_i32();
5472         TCGv_ptr fpst = get_fpstatus_ptr();
5473
5474         assert(esize == 32);
5475         assert(elements == 4);
5476
5477         read_vec_element(s, tcg_elt, rn, 0, MO_32);
5478         tcg_gen_trunc_i64_i32(tcg_elt1, tcg_elt);
5479         read_vec_element(s, tcg_elt, rn, 1, MO_32);
5480         tcg_gen_trunc_i64_i32(tcg_elt2, tcg_elt);
5481
5482         do_minmaxop(s, tcg_elt1, tcg_elt2, opcode, is_min, fpst);
5483
5484         read_vec_element(s, tcg_elt, rn, 2, MO_32);
5485         tcg_gen_trunc_i64_i32(tcg_elt2, tcg_elt);
5486         read_vec_element(s, tcg_elt, rn, 3, MO_32);
5487         tcg_gen_trunc_i64_i32(tcg_elt3, tcg_elt);
5488
5489         do_minmaxop(s, tcg_elt2, tcg_elt3, opcode, is_min, fpst);
5490
5491         do_minmaxop(s, tcg_elt1, tcg_elt2, opcode, is_min, fpst);
5492
5493         tcg_gen_extu_i32_i64(tcg_res, tcg_elt1);
5494         tcg_temp_free_i32(tcg_elt1);
5495         tcg_temp_free_i32(tcg_elt2);
5496         tcg_temp_free_i32(tcg_elt3);
5497         tcg_temp_free_ptr(fpst);
5498     }
5499
5500     tcg_temp_free_i64(tcg_elt);
5501
5502     /* Now truncate the result to the width required for the final output */
5503     if (opcode == 0x03) {
5504         /* SADDLV, UADDLV: result is 2*esize */
5505         size++;
5506     }
5507
5508     switch (size) {
5509     case 0:
5510         tcg_gen_ext8u_i64(tcg_res, tcg_res);
5511         break;
5512     case 1:
5513         tcg_gen_ext16u_i64(tcg_res, tcg_res);
5514         break;
5515     case 2:
5516         tcg_gen_ext32u_i64(tcg_res, tcg_res);
5517         break;
5518     case 3:
5519         break;
5520     default:
5521         g_assert_not_reached();
5522     }
5523
5524     write_fp_dreg(s, rd, tcg_res);
5525     tcg_temp_free_i64(tcg_res);
5526 }
5527
5528 /* C6.3.31 DUP (Element, Vector)
5529  *
5530  *  31  30   29              21 20    16 15        10  9    5 4    0
5531  * +---+---+-------------------+--------+-------------+------+------+
5532  * | 0 | Q | 0 0 1 1 1 0 0 0 0 |  imm5  | 0 0 0 0 0 1 |  Rn  |  Rd  |
5533  * +---+---+-------------------+--------+-------------+------+------+
5534  *
5535  * size: encoded in imm5 (see ARM ARM LowestSetBit())
5536  */
5537 static void handle_simd_dupe(DisasContext *s, int is_q, int rd, int rn,
5538                              int imm5)
5539 {
5540     int size = ctz32(imm5);
5541     int esize = 8 << size;
5542     int elements = (is_q ? 128 : 64) / esize;
5543     int index, i;
5544     TCGv_i64 tmp;
5545
5546     if (size > 3 || (size == 3 && !is_q)) {
5547         unallocated_encoding(s);
5548         return;
5549     }
5550
5551     if (!fp_access_check(s)) {
5552         return;
5553     }
5554
5555     index = imm5 >> (size + 1);
5556
5557     tmp = tcg_temp_new_i64();
5558     read_vec_element(s, tmp, rn, index, size);
5559
5560     for (i = 0; i < elements; i++) {
5561         write_vec_element(s, tmp, rd, i, size);
5562     }
5563
5564     if (!is_q) {
5565         clear_vec_high(s, rd);
5566     }
5567
5568     tcg_temp_free_i64(tmp);
5569 }
5570
5571 /* C6.3.31 DUP (element, scalar)
5572  *  31                   21 20    16 15        10  9    5 4    0
5573  * +-----------------------+--------+-------------+------+------+
5574  * | 0 1 0 1 1 1 1 0 0 0 0 |  imm5  | 0 0 0 0 0 1 |  Rn  |  Rd  |
5575  * +-----------------------+--------+-------------+------+------+
5576  */
5577 static void handle_simd_dupes(DisasContext *s, int rd, int rn,
5578                               int imm5)
5579 {
5580     int size = ctz32(imm5);
5581     int index;
5582     TCGv_i64 tmp;
5583
5584     if (size > 3) {
5585         unallocated_encoding(s);
5586         return;
5587     }
5588
5589     if (!fp_access_check(s)) {
5590         return;
5591     }
5592
5593     index = imm5 >> (size + 1);
5594
5595     /* This instruction just extracts the specified element and
5596      * zero-extends it into the bottom of the destination register.
5597      */
5598     tmp = tcg_temp_new_i64();
5599     read_vec_element(s, tmp, rn, index, size);
5600     write_fp_dreg(s, rd, tmp);
5601     tcg_temp_free_i64(tmp);
5602 }
5603
5604 /* C6.3.32 DUP (General)
5605  *
5606  *  31  30   29              21 20    16 15        10  9    5 4    0
5607  * +---+---+-------------------+--------+-------------+------+------+
5608  * | 0 | Q | 0 0 1 1 1 0 0 0 0 |  imm5  | 0 0 0 0 1 1 |  Rn  |  Rd  |
5609  * +---+---+-------------------+--------+-------------+------+------+
5610  *
5611  * size: encoded in imm5 (see ARM ARM LowestSetBit())
5612  */
5613 static void handle_simd_dupg(DisasContext *s, int is_q, int rd, int rn,
5614                              int imm5)
5615 {
5616     int size = ctz32(imm5);
5617     int esize = 8 << size;
5618     int elements = (is_q ? 128 : 64)/esize;
5619     int i = 0;
5620
5621     if (size > 3 || ((size == 3) && !is_q)) {
5622         unallocated_encoding(s);
5623         return;
5624     }
5625
5626     if (!fp_access_check(s)) {
5627         return;
5628     }
5629
5630     for (i = 0; i < elements; i++) {
5631         write_vec_element(s, cpu_reg(s, rn), rd, i, size);
5632     }
5633     if (!is_q) {
5634         clear_vec_high(s, rd);
5635     }
5636 }
5637
5638 /* C6.3.150 INS (Element)
5639  *
5640  *  31                   21 20    16 15  14    11  10 9    5 4    0
5641  * +-----------------------+--------+------------+---+------+------+
5642  * | 0 1 1 0 1 1 1 0 0 0 0 |  imm5  | 0 |  imm4  | 1 |  Rn  |  Rd  |
5643  * +-----------------------+--------+------------+---+------+------+
5644  *
5645  * size: encoded in imm5 (see ARM ARM LowestSetBit())
5646  * index: encoded in imm5<4:size+1>
5647  */
5648 static void handle_simd_inse(DisasContext *s, int rd, int rn,
5649                              int imm4, int imm5)
5650 {
5651     int size = ctz32(imm5);
5652     int src_index, dst_index;
5653     TCGv_i64 tmp;
5654
5655     if (size > 3) {
5656         unallocated_encoding(s);
5657         return;
5658     }
5659
5660     if (!fp_access_check(s)) {
5661         return;
5662     }
5663
5664     dst_index = extract32(imm5, 1+size, 5);
5665     src_index = extract32(imm4, size, 4);
5666
5667     tmp = tcg_temp_new_i64();
5668
5669     read_vec_element(s, tmp, rn, src_index, size);
5670     write_vec_element(s, tmp, rd, dst_index, size);
5671
5672     tcg_temp_free_i64(tmp);
5673 }
5674
5675
5676 /* C6.3.151 INS (General)
5677  *
5678  *  31                   21 20    16 15        10  9    5 4    0
5679  * +-----------------------+--------+-------------+------+------+
5680  * | 0 1 0 0 1 1 1 0 0 0 0 |  imm5  | 0 0 0 1 1 1 |  Rn  |  Rd  |
5681  * +-----------------------+--------+-------------+------+------+
5682  *
5683  * size: encoded in imm5 (see ARM ARM LowestSetBit())
5684  * index: encoded in imm5<4:size+1>
5685  */
5686 static void handle_simd_insg(DisasContext *s, int rd, int rn, int imm5)
5687 {
5688     int size = ctz32(imm5);
5689     int idx;
5690
5691     if (size > 3) {
5692         unallocated_encoding(s);
5693         return;
5694     }
5695
5696     if (!fp_access_check(s)) {
5697         return;
5698     }
5699
5700     idx = extract32(imm5, 1 + size, 4 - size);
5701     write_vec_element(s, cpu_reg(s, rn), rd, idx, size);
5702 }
5703
5704 /*
5705  * C6.3.321 UMOV (General)
5706  * C6.3.237 SMOV (General)
5707  *
5708  *  31  30   29              21 20    16 15    12   10 9    5 4    0
5709  * +---+---+-------------------+--------+-------------+------+------+
5710  * | 0 | Q | 0 0 1 1 1 0 0 0 0 |  imm5  | 0 0 1 U 1 1 |  Rn  |  Rd  |
5711  * +---+---+-------------------+--------+-------------+------+------+
5712  *
5713  * U: unsigned when set
5714  * size: encoded in imm5 (see ARM ARM LowestSetBit())
5715  */
5716 static void handle_simd_umov_smov(DisasContext *s, int is_q, int is_signed,
5717                                   int rn, int rd, int imm5)
5718 {
5719     int size = ctz32(imm5);
5720     int element;
5721     TCGv_i64 tcg_rd;
5722
5723     /* Check for UnallocatedEncodings */
5724     if (is_signed) {
5725         if (size > 2 || (size == 2 && !is_q)) {
5726             unallocated_encoding(s);
5727             return;
5728         }
5729     } else {
5730         if (size > 3
5731             || (size < 3 && is_q)
5732             || (size == 3 && !is_q)) {
5733             unallocated_encoding(s);
5734             return;
5735         }
5736     }
5737
5738     if (!fp_access_check(s)) {
5739         return;
5740     }
5741
5742     element = extract32(imm5, 1+size, 4);
5743
5744     tcg_rd = cpu_reg(s, rd);
5745     read_vec_element(s, tcg_rd, rn, element, size | (is_signed ? MO_SIGN : 0));
5746     if (is_signed && !is_q) {
5747         tcg_gen_ext32u_i64(tcg_rd, tcg_rd);
5748     }
5749 }
5750
5751 /* C3.6.5 AdvSIMD copy
5752  *   31  30  29  28             21 20  16 15  14  11 10  9    5 4    0
5753  * +---+---+----+-----------------+------+---+------+---+------+------+
5754  * | 0 | Q | op | 0 1 1 1 0 0 0 0 | imm5 | 0 | imm4 | 1 |  Rn  |  Rd  |
5755  * +---+---+----+-----------------+------+---+------+---+------+------+
5756  */
5757 static void disas_simd_copy(DisasContext *s, uint32_t insn)
5758 {
5759     int rd = extract32(insn, 0, 5);
5760     int rn = extract32(insn, 5, 5);
5761     int imm4 = extract32(insn, 11, 4);
5762     int op = extract32(insn, 29, 1);
5763     int is_q = extract32(insn, 30, 1);
5764     int imm5 = extract32(insn, 16, 5);
5765
5766     if (op) {
5767         if (is_q) {
5768             /* INS (element) */
5769             handle_simd_inse(s, rd, rn, imm4, imm5);
5770         } else {
5771             unallocated_encoding(s);
5772         }
5773     } else {
5774         switch (imm4) {
5775         case 0:
5776             /* DUP (element - vector) */
5777             handle_simd_dupe(s, is_q, rd, rn, imm5);
5778             break;
5779         case 1:
5780             /* DUP (general) */
5781             handle_simd_dupg(s, is_q, rd, rn, imm5);
5782             break;
5783         case 3:
5784             if (is_q) {
5785                 /* INS (general) */
5786                 handle_simd_insg(s, rd, rn, imm5);
5787             } else {
5788                 unallocated_encoding(s);
5789             }
5790             break;
5791         case 5:
5792         case 7:
5793             /* UMOV/SMOV (is_q indicates 32/64; imm4 indicates signedness) */
5794             handle_simd_umov_smov(s, is_q, (imm4 == 5), rn, rd, imm5);
5795             break;
5796         default:
5797             unallocated_encoding(s);
5798             break;
5799         }
5800     }
5801 }
5802
5803 /* C3.6.6 AdvSIMD modified immediate
5804  *  31  30   29  28                 19 18 16 15   12  11  10  9     5 4    0
5805  * +---+---+----+---------------------+-----+-------+----+---+-------+------+
5806  * | 0 | Q | op | 0 1 1 1 1 0 0 0 0 0 | abc | cmode | o2 | 1 | defgh |  Rd  |
5807  * +---+---+----+---------------------+-----+-------+----+---+-------+------+
5808  *
5809  * There are a number of operations that can be carried out here:
5810  *   MOVI - move (shifted) imm into register
5811  *   MVNI - move inverted (shifted) imm into register
5812  *   ORR  - bitwise OR of (shifted) imm with register
5813  *   BIC  - bitwise clear of (shifted) imm with register
5814  */
5815 static void disas_simd_mod_imm(DisasContext *s, uint32_t insn)
5816 {
5817     int rd = extract32(insn, 0, 5);
5818     int cmode = extract32(insn, 12, 4);
5819     int cmode_3_1 = extract32(cmode, 1, 3);
5820     int cmode_0 = extract32(cmode, 0, 1);
5821     int o2 = extract32(insn, 11, 1);
5822     uint64_t abcdefgh = extract32(insn, 5, 5) | (extract32(insn, 16, 3) << 5);
5823     bool is_neg = extract32(insn, 29, 1);
5824     bool is_q = extract32(insn, 30, 1);
5825     uint64_t imm = 0;
5826     TCGv_i64 tcg_rd, tcg_imm;
5827     int i;
5828
5829     if (o2 != 0 || ((cmode == 0xf) && is_neg && !is_q)) {
5830         unallocated_encoding(s);
5831         return;
5832     }
5833
5834     if (!fp_access_check(s)) {
5835         return;
5836     }
5837
5838     /* See AdvSIMDExpandImm() in ARM ARM */
5839     switch (cmode_3_1) {
5840     case 0: /* Replicate(Zeros(24):imm8, 2) */
5841     case 1: /* Replicate(Zeros(16):imm8:Zeros(8), 2) */
5842     case 2: /* Replicate(Zeros(8):imm8:Zeros(16), 2) */
5843     case 3: /* Replicate(imm8:Zeros(24), 2) */
5844     {
5845         int shift = cmode_3_1 * 8;
5846         imm = bitfield_replicate(abcdefgh << shift, 32);
5847         break;
5848     }
5849     case 4: /* Replicate(Zeros(8):imm8, 4) */
5850     case 5: /* Replicate(imm8:Zeros(8), 4) */
5851     {
5852         int shift = (cmode_3_1 & 0x1) * 8;
5853         imm = bitfield_replicate(abcdefgh << shift, 16);
5854         break;
5855     }
5856     case 6:
5857         if (cmode_0) {
5858             /* Replicate(Zeros(8):imm8:Ones(16), 2) */
5859             imm = (abcdefgh << 16) | 0xffff;
5860         } else {
5861             /* Replicate(Zeros(16):imm8:Ones(8), 2) */
5862             imm = (abcdefgh << 8) | 0xff;
5863         }
5864         imm = bitfield_replicate(imm, 32);
5865         break;
5866     case 7:
5867         if (!cmode_0 && !is_neg) {
5868             imm = bitfield_replicate(abcdefgh, 8);
5869         } else if (!cmode_0 && is_neg) {
5870             int i;
5871             imm = 0;
5872             for (i = 0; i < 8; i++) {
5873                 if ((abcdefgh) & (1 << i)) {
5874                     imm |= 0xffULL << (i * 8);
5875                 }
5876             }
5877         } else if (cmode_0) {
5878             if (is_neg) {
5879                 imm = (abcdefgh & 0x3f) << 48;
5880                 if (abcdefgh & 0x80) {
5881                     imm |= 0x8000000000000000ULL;
5882                 }
5883                 if (abcdefgh & 0x40) {
5884                     imm |= 0x3fc0000000000000ULL;
5885                 } else {
5886                     imm |= 0x4000000000000000ULL;
5887                 }
5888             } else {
5889                 imm = (abcdefgh & 0x3f) << 19;
5890                 if (abcdefgh & 0x80) {
5891                     imm |= 0x80000000;
5892                 }
5893                 if (abcdefgh & 0x40) {
5894                     imm |= 0x3e000000;
5895                 } else {
5896                     imm |= 0x40000000;
5897                 }
5898                 imm |= (imm << 32);
5899             }
5900         }
5901         break;
5902     }
5903
5904     if (cmode_3_1 != 7 && is_neg) {
5905         imm = ~imm;
5906     }
5907
5908     tcg_imm = tcg_const_i64(imm);
5909     tcg_rd = new_tmp_a64(s);
5910
5911     for (i = 0; i < 2; i++) {
5912         int foffs = i ? fp_reg_hi_offset(s, rd) : fp_reg_offset(s, rd, MO_64);
5913
5914         if (i == 1 && !is_q) {
5915             /* non-quad ops clear high half of vector */
5916             tcg_gen_movi_i64(tcg_rd, 0);
5917         } else if ((cmode & 0x9) == 0x1 || (cmode & 0xd) == 0x9) {
5918             tcg_gen_ld_i64(tcg_rd, cpu_env, foffs);
5919             if (is_neg) {
5920                 /* AND (BIC) */
5921                 tcg_gen_and_i64(tcg_rd, tcg_rd, tcg_imm);
5922             } else {
5923                 /* ORR */
5924                 tcg_gen_or_i64(tcg_rd, tcg_rd, tcg_imm);
5925             }
5926         } else {
5927             /* MOVI */
5928             tcg_gen_mov_i64(tcg_rd, tcg_imm);
5929         }
5930         tcg_gen_st_i64(tcg_rd, cpu_env, foffs);
5931     }
5932
5933     tcg_temp_free_i64(tcg_imm);
5934 }
5935
5936 /* C3.6.7 AdvSIMD scalar copy
5937  *  31 30  29  28             21 20  16 15  14  11 10  9    5 4    0
5938  * +-----+----+-----------------+------+---+------+---+------+------+
5939  * | 0 1 | op | 1 1 1 1 0 0 0 0 | imm5 | 0 | imm4 | 1 |  Rn  |  Rd  |
5940  * +-----+----+-----------------+------+---+------+---+------+------+
5941  */
5942 static void disas_simd_scalar_copy(DisasContext *s, uint32_t insn)
5943 {
5944     int rd = extract32(insn, 0, 5);
5945     int rn = extract32(insn, 5, 5);
5946     int imm4 = extract32(insn, 11, 4);
5947     int imm5 = extract32(insn, 16, 5);
5948     int op = extract32(insn, 29, 1);
5949
5950     if (op != 0 || imm4 != 0) {
5951         unallocated_encoding(s);
5952         return;
5953     }
5954
5955     /* DUP (element, scalar) */
5956     handle_simd_dupes(s, rd, rn, imm5);
5957 }
5958
5959 /* C3.6.8 AdvSIMD scalar pairwise
5960  *  31 30  29 28       24 23  22 21       17 16    12 11 10 9    5 4    0
5961  * +-----+---+-----------+------+-----------+--------+-----+------+------+
5962  * | 0 1 | U | 1 1 1 1 0 | size | 1 1 0 0 0 | opcode | 1 0 |  Rn  |  Rd  |
5963  * +-----+---+-----------+------+-----------+--------+-----+------+------+
5964  */
5965 static void disas_simd_scalar_pairwise(DisasContext *s, uint32_t insn)
5966 {
5967     int u = extract32(insn, 29, 1);
5968     int size = extract32(insn, 22, 2);
5969     int opcode = extract32(insn, 12, 5);
5970     int rn = extract32(insn, 5, 5);
5971     int rd = extract32(insn, 0, 5);
5972     TCGv_ptr fpst;
5973
5974     /* For some ops (the FP ones), size[1] is part of the encoding.
5975      * For ADDP strictly it is not but size[1] is always 1 for valid
5976      * encodings.
5977      */
5978     opcode |= (extract32(size, 1, 1) << 5);
5979
5980     switch (opcode) {
5981     case 0x3b: /* ADDP */
5982         if (u || size != 3) {
5983             unallocated_encoding(s);
5984             return;
5985         }
5986         if (!fp_access_check(s)) {
5987             return;
5988         }
5989
5990         TCGV_UNUSED_PTR(fpst);
5991         break;
5992     case 0xc: /* FMAXNMP */
5993     case 0xd: /* FADDP */
5994     case 0xf: /* FMAXP */
5995     case 0x2c: /* FMINNMP */
5996     case 0x2f: /* FMINP */
5997         /* FP op, size[0] is 32 or 64 bit */
5998         if (!u) {
5999             unallocated_encoding(s);
6000             return;
6001         }
6002         if (!fp_access_check(s)) {
6003             return;
6004         }
6005
6006         size = extract32(size, 0, 1) ? 3 : 2;
6007         fpst = get_fpstatus_ptr();
6008         break;
6009     default:
6010         unallocated_encoding(s);
6011         return;
6012     }
6013
6014     if (size == 3) {
6015         TCGv_i64 tcg_op1 = tcg_temp_new_i64();
6016         TCGv_i64 tcg_op2 = tcg_temp_new_i64();
6017         TCGv_i64 tcg_res = tcg_temp_new_i64();
6018
6019         read_vec_element(s, tcg_op1, rn, 0, MO_64);
6020         read_vec_element(s, tcg_op2, rn, 1, MO_64);
6021
6022         switch (opcode) {
6023         case 0x3b: /* ADDP */
6024             tcg_gen_add_i64(tcg_res, tcg_op1, tcg_op2);
6025             break;
6026         case 0xc: /* FMAXNMP */
6027             gen_helper_vfp_maxnumd(tcg_res, tcg_op1, tcg_op2, fpst);
6028             break;
6029         case 0xd: /* FADDP */
6030             gen_helper_vfp_addd(tcg_res, tcg_op1, tcg_op2, fpst);
6031             break;
6032         case 0xf: /* FMAXP */
6033             gen_helper_vfp_maxd(tcg_res, tcg_op1, tcg_op2, fpst);
6034             break;
6035         case 0x2c: /* FMINNMP */
6036             gen_helper_vfp_minnumd(tcg_res, tcg_op1, tcg_op2, fpst);
6037             break;
6038         case 0x2f: /* FMINP */
6039             gen_helper_vfp_mind(tcg_res, tcg_op1, tcg_op2, fpst);
6040             break;
6041         default:
6042             g_assert_not_reached();
6043         }
6044
6045         write_fp_dreg(s, rd, tcg_res);
6046
6047         tcg_temp_free_i64(tcg_op1);
6048         tcg_temp_free_i64(tcg_op2);
6049         tcg_temp_free_i64(tcg_res);
6050     } else {
6051         TCGv_i32 tcg_op1 = tcg_temp_new_i32();
6052         TCGv_i32 tcg_op2 = tcg_temp_new_i32();
6053         TCGv_i32 tcg_res = tcg_temp_new_i32();
6054
6055         read_vec_element_i32(s, tcg_op1, rn, 0, MO_32);
6056         read_vec_element_i32(s, tcg_op2, rn, 1, MO_32);
6057
6058         switch (opcode) {
6059         case 0xc: /* FMAXNMP */
6060             gen_helper_vfp_maxnums(tcg_res, tcg_op1, tcg_op2, fpst);
6061             break;
6062         case 0xd: /* FADDP */
6063             gen_helper_vfp_adds(tcg_res, tcg_op1, tcg_op2, fpst);
6064             break;
6065         case 0xf: /* FMAXP */
6066             gen_helper_vfp_maxs(tcg_res, tcg_op1, tcg_op2, fpst);
6067             break;
6068         case 0x2c: /* FMINNMP */
6069             gen_helper_vfp_minnums(tcg_res, tcg_op1, tcg_op2, fpst);
6070             break;
6071         case 0x2f: /* FMINP */
6072             gen_helper_vfp_mins(tcg_res, tcg_op1, tcg_op2, fpst);
6073             break;
6074         default:
6075             g_assert_not_reached();
6076         }
6077
6078         write_fp_sreg(s, rd, tcg_res);
6079
6080         tcg_temp_free_i32(tcg_op1);
6081         tcg_temp_free_i32(tcg_op2);
6082         tcg_temp_free_i32(tcg_res);
6083     }
6084
6085     if (!TCGV_IS_UNUSED_PTR(fpst)) {
6086         tcg_temp_free_ptr(fpst);
6087     }
6088 }
6089
6090 /*
6091  * Common SSHR[RA]/USHR[RA] - Shift right (optional rounding/accumulate)
6092  *
6093  * This code is handles the common shifting code and is used by both
6094  * the vector and scalar code.
6095  */
6096 static void handle_shri_with_rndacc(TCGv_i64 tcg_res, TCGv_i64 tcg_src,
6097                                     TCGv_i64 tcg_rnd, bool accumulate,
6098                                     bool is_u, int size, int shift)
6099 {
6100     bool extended_result = false;
6101     bool round = !TCGV_IS_UNUSED_I64(tcg_rnd);
6102     int ext_lshift = 0;
6103     TCGv_i64 tcg_src_hi;
6104
6105     if (round && size == 3) {
6106         extended_result = true;
6107         ext_lshift = 64 - shift;
6108         tcg_src_hi = tcg_temp_new_i64();
6109     } else if (shift == 64) {
6110         if (!accumulate && is_u) {
6111             /* result is zero */
6112             tcg_gen_movi_i64(tcg_res, 0);
6113             return;
6114         }
6115     }
6116
6117     /* Deal with the rounding step */
6118     if (round) {
6119         if (extended_result) {
6120             TCGv_i64 tcg_zero = tcg_const_i64(0);
6121             if (!is_u) {
6122                 /* take care of sign extending tcg_res */
6123                 tcg_gen_sari_i64(tcg_src_hi, tcg_src, 63);
6124                 tcg_gen_add2_i64(tcg_src, tcg_src_hi,
6125                                  tcg_src, tcg_src_hi,
6126                                  tcg_rnd, tcg_zero);
6127             } else {
6128                 tcg_gen_add2_i64(tcg_src, tcg_src_hi,
6129                                  tcg_src, tcg_zero,
6130                                  tcg_rnd, tcg_zero);
6131             }
6132             tcg_temp_free_i64(tcg_zero);
6133         } else {
6134             tcg_gen_add_i64(tcg_src, tcg_src, tcg_rnd);
6135         }
6136     }
6137
6138     /* Now do the shift right */
6139     if (round && extended_result) {
6140         /* extended case, >64 bit precision required */
6141         if (ext_lshift == 0) {
6142             /* special case, only high bits matter */
6143             tcg_gen_mov_i64(tcg_src, tcg_src_hi);
6144         } else {
6145             tcg_gen_shri_i64(tcg_src, tcg_src, shift);
6146             tcg_gen_shli_i64(tcg_src_hi, tcg_src_hi, ext_lshift);
6147             tcg_gen_or_i64(tcg_src, tcg_src, tcg_src_hi);
6148         }
6149     } else {
6150         if (is_u) {
6151             if (shift == 64) {
6152                 /* essentially shifting in 64 zeros */
6153                 tcg_gen_movi_i64(tcg_src, 0);
6154             } else {
6155                 tcg_gen_shri_i64(tcg_src, tcg_src, shift);
6156             }
6157         } else {
6158             if (shift == 64) {
6159                 /* effectively extending the sign-bit */
6160                 tcg_gen_sari_i64(tcg_src, tcg_src, 63);
6161             } else {
6162                 tcg_gen_sari_i64(tcg_src, tcg_src, shift);
6163             }
6164         }
6165     }
6166
6167     if (accumulate) {
6168         tcg_gen_add_i64(tcg_res, tcg_res, tcg_src);
6169     } else {
6170         tcg_gen_mov_i64(tcg_res, tcg_src);
6171     }
6172
6173     if (extended_result) {
6174         tcg_temp_free_i64(tcg_src_hi);
6175     }
6176 }
6177
6178 /* Common SHL/SLI - Shift left with an optional insert */
6179 static void handle_shli_with_ins(TCGv_i64 tcg_res, TCGv_i64 tcg_src,
6180                                  bool insert, int shift)
6181 {
6182     if (insert) { /* SLI */
6183         tcg_gen_deposit_i64(tcg_res, tcg_res, tcg_src, shift, 64 - shift);
6184     } else { /* SHL */
6185         tcg_gen_shli_i64(tcg_res, tcg_src, shift);
6186     }
6187 }
6188
6189 /* SRI: shift right with insert */
6190 static void handle_shri_with_ins(TCGv_i64 tcg_res, TCGv_i64 tcg_src,
6191                                  int size, int shift)
6192 {
6193     int esize = 8 << size;
6194
6195     /* shift count same as element size is valid but does nothing;
6196      * special case to avoid potential shift by 64.
6197      */
6198     if (shift != esize) {
6199         tcg_gen_shri_i64(tcg_src, tcg_src, shift);
6200         tcg_gen_deposit_i64(tcg_res, tcg_res, tcg_src, 0, esize - shift);
6201     }
6202 }
6203
6204 /* SSHR[RA]/USHR[RA] - Scalar shift right (optional rounding/accumulate) */
6205 static void handle_scalar_simd_shri(DisasContext *s,
6206                                     bool is_u, int immh, int immb,
6207                                     int opcode, int rn, int rd)
6208 {
6209     const int size = 3;
6210     int immhb = immh << 3 | immb;
6211     int shift = 2 * (8 << size) - immhb;
6212     bool accumulate = false;
6213     bool round = false;
6214     bool insert = false;
6215     TCGv_i64 tcg_rn;
6216     TCGv_i64 tcg_rd;
6217     TCGv_i64 tcg_round;
6218
6219     if (!extract32(immh, 3, 1)) {
6220         unallocated_encoding(s);
6221         return;
6222     }
6223
6224     if (!fp_access_check(s)) {
6225         return;
6226     }
6227
6228     switch (opcode) {
6229     case 0x02: /* SSRA / USRA (accumulate) */
6230         accumulate = true;
6231         break;
6232     case 0x04: /* SRSHR / URSHR (rounding) */
6233         round = true;
6234         break;
6235     case 0x06: /* SRSRA / URSRA (accum + rounding) */
6236         accumulate = round = true;
6237         break;
6238     case 0x08: /* SRI */
6239         insert = true;
6240         break;
6241     }
6242
6243     if (round) {
6244         uint64_t round_const = 1ULL << (shift - 1);
6245         tcg_round = tcg_const_i64(round_const);
6246     } else {
6247         TCGV_UNUSED_I64(tcg_round);
6248     }
6249
6250     tcg_rn = read_fp_dreg(s, rn);
6251     tcg_rd = (accumulate || insert) ? read_fp_dreg(s, rd) : tcg_temp_new_i64();
6252
6253     if (insert) {
6254         handle_shri_with_ins(tcg_rd, tcg_rn, size, shift);
6255     } else {
6256         handle_shri_with_rndacc(tcg_rd, tcg_rn, tcg_round,
6257                                 accumulate, is_u, size, shift);
6258     }
6259
6260     write_fp_dreg(s, rd, tcg_rd);
6261
6262     tcg_temp_free_i64(tcg_rn);
6263     tcg_temp_free_i64(tcg_rd);
6264     if (round) {
6265         tcg_temp_free_i64(tcg_round);
6266     }
6267 }
6268
6269 /* SHL/SLI - Scalar shift left */
6270 static void handle_scalar_simd_shli(DisasContext *s, bool insert,
6271                                     int immh, int immb, int opcode,
6272                                     int rn, int rd)
6273 {
6274     int size = 32 - clz32(immh) - 1;
6275     int immhb = immh << 3 | immb;
6276     int shift = immhb - (8 << size);
6277     TCGv_i64 tcg_rn = new_tmp_a64(s);
6278     TCGv_i64 tcg_rd = new_tmp_a64(s);
6279
6280     if (!extract32(immh, 3, 1)) {
6281         unallocated_encoding(s);
6282         return;
6283     }
6284
6285     if (!fp_access_check(s)) {
6286         return;
6287     }
6288
6289     tcg_rn = read_fp_dreg(s, rn);
6290     tcg_rd = insert ? read_fp_dreg(s, rd) : tcg_temp_new_i64();
6291
6292     handle_shli_with_ins(tcg_rd, tcg_rn, insert, shift);
6293
6294     write_fp_dreg(s, rd, tcg_rd);
6295
6296     tcg_temp_free_i64(tcg_rn);
6297     tcg_temp_free_i64(tcg_rd);
6298 }
6299
6300 /* SQSHRN/SQSHRUN - Saturating (signed/unsigned) shift right with
6301  * (signed/unsigned) narrowing */
6302 static void handle_vec_simd_sqshrn(DisasContext *s, bool is_scalar, bool is_q,
6303                                    bool is_u_shift, bool is_u_narrow,
6304                                    int immh, int immb, int opcode,
6305                                    int rn, int rd)
6306 {
6307     int immhb = immh << 3 | immb;
6308     int size = 32 - clz32(immh) - 1;
6309     int esize = 8 << size;
6310     int shift = (2 * esize) - immhb;
6311     int elements = is_scalar ? 1 : (64 / esize);
6312     bool round = extract32(opcode, 0, 1);
6313     TCGMemOp ldop = (size + 1) | (is_u_shift ? 0 : MO_SIGN);
6314     TCGv_i64 tcg_rn, tcg_rd, tcg_round;
6315     TCGv_i32 tcg_rd_narrowed;
6316     TCGv_i64 tcg_final;
6317
6318     static NeonGenNarrowEnvFn * const signed_narrow_fns[4][2] = {
6319         { gen_helper_neon_narrow_sat_s8,
6320           gen_helper_neon_unarrow_sat8 },
6321         { gen_helper_neon_narrow_sat_s16,
6322           gen_helper_neon_unarrow_sat16 },
6323         { gen_helper_neon_narrow_sat_s32,
6324           gen_helper_neon_unarrow_sat32 },
6325         { NULL, NULL },
6326     };
6327     static NeonGenNarrowEnvFn * const unsigned_narrow_fns[4] = {
6328         gen_helper_neon_narrow_sat_u8,
6329         gen_helper_neon_narrow_sat_u16,
6330         gen_helper_neon_narrow_sat_u32,
6331         NULL
6332     };
6333     NeonGenNarrowEnvFn *narrowfn;
6334
6335     int i;
6336
6337     assert(size < 4);
6338
6339     if (extract32(immh, 3, 1)) {
6340         unallocated_encoding(s);
6341         return;
6342     }
6343
6344     if (!fp_access_check(s)) {
6345         return;
6346     }
6347
6348     if (is_u_shift) {
6349         narrowfn = unsigned_narrow_fns[size];
6350     } else {
6351         narrowfn = signed_narrow_fns[size][is_u_narrow ? 1 : 0];
6352     }
6353
6354     tcg_rn = tcg_temp_new_i64();
6355     tcg_rd = tcg_temp_new_i64();
6356     tcg_rd_narrowed = tcg_temp_new_i32();
6357     tcg_final = tcg_const_i64(0);
6358
6359     if (round) {
6360         uint64_t round_const = 1ULL << (shift - 1);
6361         tcg_round = tcg_const_i64(round_const);
6362     } else {
6363         TCGV_UNUSED_I64(tcg_round);
6364     }
6365
6366     for (i = 0; i < elements; i++) {
6367         read_vec_element(s, tcg_rn, rn, i, ldop);
6368         handle_shri_with_rndacc(tcg_rd, tcg_rn, tcg_round,
6369                                 false, is_u_shift, size+1, shift);
6370         narrowfn(tcg_rd_narrowed, cpu_env, tcg_rd);
6371         tcg_gen_extu_i32_i64(tcg_rd, tcg_rd_narrowed);
6372         tcg_gen_deposit_i64(tcg_final, tcg_final, tcg_rd, esize * i, esize);
6373     }
6374
6375     if (!is_q) {
6376         clear_vec_high(s, rd);
6377         write_vec_element(s, tcg_final, rd, 0, MO_64);
6378     } else {
6379         write_vec_element(s, tcg_final, rd, 1, MO_64);
6380     }
6381
6382     if (round) {
6383         tcg_temp_free_i64(tcg_round);
6384     }
6385     tcg_temp_free_i64(tcg_rn);
6386     tcg_temp_free_i64(tcg_rd);
6387     tcg_temp_free_i32(tcg_rd_narrowed);
6388     tcg_temp_free_i64(tcg_final);
6389     return;
6390 }
6391
6392 /* SQSHLU, UQSHL, SQSHL: saturating left shifts */
6393 static void handle_simd_qshl(DisasContext *s, bool scalar, bool is_q,
6394                              bool src_unsigned, bool dst_unsigned,
6395                              int immh, int immb, int rn, int rd)
6396 {
6397     int immhb = immh << 3 | immb;
6398     int size = 32 - clz32(immh) - 1;
6399     int shift = immhb - (8 << size);
6400     int pass;
6401
6402     assert(immh != 0);
6403     assert(!(scalar && is_q));
6404
6405     if (!scalar) {
6406         if (!is_q && extract32(immh, 3, 1)) {
6407             unallocated_encoding(s);
6408             return;
6409         }
6410
6411         /* Since we use the variable-shift helpers we must
6412          * replicate the shift count into each element of
6413          * the tcg_shift value.
6414          */
6415         switch (size) {
6416         case 0:
6417             shift |= shift << 8;
6418             /* fall through */
6419         case 1:
6420             shift |= shift << 16;
6421             break;
6422         case 2:
6423         case 3:
6424             break;
6425         default:
6426             g_assert_not_reached();
6427         }
6428     }
6429
6430     if (!fp_access_check(s)) {
6431         return;
6432     }
6433
6434     if (size == 3) {
6435         TCGv_i64 tcg_shift = tcg_const_i64(shift);
6436         static NeonGenTwo64OpEnvFn * const fns[2][2] = {
6437             { gen_helper_neon_qshl_s64, gen_helper_neon_qshlu_s64 },
6438             { NULL, gen_helper_neon_qshl_u64 },
6439         };
6440         NeonGenTwo64OpEnvFn *genfn = fns[src_unsigned][dst_unsigned];
6441         int maxpass = is_q ? 2 : 1;
6442
6443         for (pass = 0; pass < maxpass; pass++) {
6444             TCGv_i64 tcg_op = tcg_temp_new_i64();
6445
6446             read_vec_element(s, tcg_op, rn, pass, MO_64);
6447             genfn(tcg_op, cpu_env, tcg_op, tcg_shift);
6448             write_vec_element(s, tcg_op, rd, pass, MO_64);
6449
6450             tcg_temp_free_i64(tcg_op);
6451         }
6452         tcg_temp_free_i64(tcg_shift);
6453
6454         if (!is_q) {
6455             clear_vec_high(s, rd);
6456         }
6457     } else {
6458         TCGv_i32 tcg_shift = tcg_const_i32(shift);
6459         static NeonGenTwoOpEnvFn * const fns[2][2][3] = {
6460             {
6461                 { gen_helper_neon_qshl_s8,
6462                   gen_helper_neon_qshl_s16,
6463                   gen_helper_neon_qshl_s32 },
6464                 { gen_helper_neon_qshlu_s8,
6465                   gen_helper_neon_qshlu_s16,
6466                   gen_helper_neon_qshlu_s32 }
6467             }, {
6468                 { NULL, NULL, NULL },
6469                 { gen_helper_neon_qshl_u8,
6470                   gen_helper_neon_qshl_u16,
6471                   gen_helper_neon_qshl_u32 }
6472             }
6473         };
6474         NeonGenTwoOpEnvFn *genfn = fns[src_unsigned][dst_unsigned][size];
6475         TCGMemOp memop = scalar ? size : MO_32;
6476         int maxpass = scalar ? 1 : is_q ? 4 : 2;
6477
6478         for (pass = 0; pass < maxpass; pass++) {
6479             TCGv_i32 tcg_op = tcg_temp_new_i32();
6480
6481             read_vec_element_i32(s, tcg_op, rn, pass, memop);
6482             genfn(tcg_op, cpu_env, tcg_op, tcg_shift);
6483             if (scalar) {
6484                 switch (size) {
6485                 case 0:
6486                     tcg_gen_ext8u_i32(tcg_op, tcg_op);
6487                     break;
6488                 case 1:
6489                     tcg_gen_ext16u_i32(tcg_op, tcg_op);
6490                     break;
6491                 case 2:
6492                     break;
6493                 default:
6494                     g_assert_not_reached();
6495                 }
6496                 write_fp_sreg(s, rd, tcg_op);
6497             } else {
6498                 write_vec_element_i32(s, tcg_op, rd, pass, MO_32);
6499             }
6500
6501             tcg_temp_free_i32(tcg_op);
6502         }
6503         tcg_temp_free_i32(tcg_shift);
6504
6505         if (!is_q && !scalar) {
6506             clear_vec_high(s, rd);
6507         }
6508     }
6509 }
6510
6511 /* Common vector code for handling integer to FP conversion */
6512 static void handle_simd_intfp_conv(DisasContext *s, int rd, int rn,
6513                                    int elements, int is_signed,
6514                                    int fracbits, int size)
6515 {
6516     bool is_double = size == 3 ? true : false;
6517     TCGv_ptr tcg_fpst = get_fpstatus_ptr();
6518     TCGv_i32 tcg_shift = tcg_const_i32(fracbits);
6519     TCGv_i64 tcg_int = tcg_temp_new_i64();
6520     TCGMemOp mop = size | (is_signed ? MO_SIGN : 0);
6521     int pass;
6522
6523     for (pass = 0; pass < elements; pass++) {
6524         read_vec_element(s, tcg_int, rn, pass, mop);
6525
6526         if (is_double) {
6527             TCGv_i64 tcg_double = tcg_temp_new_i64();
6528             if (is_signed) {
6529                 gen_helper_vfp_sqtod(tcg_double, tcg_int,
6530                                      tcg_shift, tcg_fpst);
6531             } else {
6532                 gen_helper_vfp_uqtod(tcg_double, tcg_int,
6533                                      tcg_shift, tcg_fpst);
6534             }
6535             if (elements == 1) {
6536                 write_fp_dreg(s, rd, tcg_double);
6537             } else {
6538                 write_vec_element(s, tcg_double, rd, pass, MO_64);
6539             }
6540             tcg_temp_free_i64(tcg_double);
6541         } else {
6542             TCGv_i32 tcg_single = tcg_temp_new_i32();
6543             if (is_signed) {
6544                 gen_helper_vfp_sqtos(tcg_single, tcg_int,
6545                                      tcg_shift, tcg_fpst);
6546             } else {
6547                 gen_helper_vfp_uqtos(tcg_single, tcg_int,
6548                                      tcg_shift, tcg_fpst);
6549             }
6550             if (elements == 1) {
6551                 write_fp_sreg(s, rd, tcg_single);
6552             } else {
6553                 write_vec_element_i32(s, tcg_single, rd, pass, MO_32);
6554             }
6555             tcg_temp_free_i32(tcg_single);
6556         }
6557     }
6558
6559     if (!is_double && elements == 2) {
6560         clear_vec_high(s, rd);
6561     }
6562
6563     tcg_temp_free_i64(tcg_int);
6564     tcg_temp_free_ptr(tcg_fpst);
6565     tcg_temp_free_i32(tcg_shift);
6566 }
6567
6568 /* UCVTF/SCVTF - Integer to FP conversion */
6569 static void handle_simd_shift_intfp_conv(DisasContext *s, bool is_scalar,
6570                                          bool is_q, bool is_u,
6571                                          int immh, int immb, int opcode,
6572                                          int rn, int rd)
6573 {
6574     bool is_double = extract32(immh, 3, 1);
6575     int size = is_double ? MO_64 : MO_32;
6576     int elements;
6577     int immhb = immh << 3 | immb;
6578     int fracbits = (is_double ? 128 : 64) - immhb;
6579
6580     if (!extract32(immh, 2, 2)) {
6581         unallocated_encoding(s);
6582         return;
6583     }
6584
6585     if (is_scalar) {
6586         elements = 1;
6587     } else {
6588         elements = is_double ? 2 : is_q ? 4 : 2;
6589         if (is_double && !is_q) {
6590             unallocated_encoding(s);
6591             return;
6592         }
6593     }
6594
6595     if (!fp_access_check(s)) {
6596         return;
6597     }
6598
6599     /* immh == 0 would be a failure of the decode logic */
6600     g_assert(immh);
6601
6602     handle_simd_intfp_conv(s, rd, rn, elements, !is_u, fracbits, size);
6603 }
6604
6605 /* FCVTZS, FVCVTZU - FP to fixedpoint conversion */
6606 static void handle_simd_shift_fpint_conv(DisasContext *s, bool is_scalar,
6607                                          bool is_q, bool is_u,
6608                                          int immh, int immb, int rn, int rd)
6609 {
6610     bool is_double = extract32(immh, 3, 1);
6611     int immhb = immh << 3 | immb;
6612     int fracbits = (is_double ? 128 : 64) - immhb;
6613     int pass;
6614     TCGv_ptr tcg_fpstatus;
6615     TCGv_i32 tcg_rmode, tcg_shift;
6616
6617     if (!extract32(immh, 2, 2)) {
6618         unallocated_encoding(s);
6619         return;
6620     }
6621
6622     if (!is_scalar && !is_q && is_double) {
6623         unallocated_encoding(s);
6624         return;
6625     }
6626
6627     if (!fp_access_check(s)) {
6628         return;
6629     }
6630
6631     assert(!(is_scalar && is_q));
6632
6633     tcg_rmode = tcg_const_i32(arm_rmode_to_sf(FPROUNDING_ZERO));
6634     gen_helper_set_rmode(tcg_rmode, tcg_rmode, cpu_env);
6635     tcg_fpstatus = get_fpstatus_ptr();
6636     tcg_shift = tcg_const_i32(fracbits);
6637
6638     if (is_double) {
6639         int maxpass = is_scalar ? 1 : 2;
6640
6641         for (pass = 0; pass < maxpass; pass++) {
6642             TCGv_i64 tcg_op = tcg_temp_new_i64();
6643
6644             read_vec_element(s, tcg_op, rn, pass, MO_64);
6645             if (is_u) {
6646                 gen_helper_vfp_touqd(tcg_op, tcg_op, tcg_shift, tcg_fpstatus);
6647             } else {
6648                 gen_helper_vfp_tosqd(tcg_op, tcg_op, tcg_shift, tcg_fpstatus);
6649             }
6650             write_vec_element(s, tcg_op, rd, pass, MO_64);
6651             tcg_temp_free_i64(tcg_op);
6652         }
6653         if (!is_q) {
6654             clear_vec_high(s, rd);
6655         }
6656     } else {
6657         int maxpass = is_scalar ? 1 : is_q ? 4 : 2;
6658         for (pass = 0; pass < maxpass; pass++) {
6659             TCGv_i32 tcg_op = tcg_temp_new_i32();
6660
6661             read_vec_element_i32(s, tcg_op, rn, pass, MO_32);
6662             if (is_u) {
6663                 gen_helper_vfp_touls(tcg_op, tcg_op, tcg_shift, tcg_fpstatus);
6664             } else {
6665                 gen_helper_vfp_tosls(tcg_op, tcg_op, tcg_shift, tcg_fpstatus);
6666             }
6667             if (is_scalar) {
6668                 write_fp_sreg(s, rd, tcg_op);
6669             } else {
6670                 write_vec_element_i32(s, tcg_op, rd, pass, MO_32);
6671             }
6672             tcg_temp_free_i32(tcg_op);
6673         }
6674         if (!is_q && !is_scalar) {
6675             clear_vec_high(s, rd);
6676         }
6677     }
6678
6679     tcg_temp_free_ptr(tcg_fpstatus);
6680     tcg_temp_free_i32(tcg_shift);
6681     gen_helper_set_rmode(tcg_rmode, tcg_rmode, cpu_env);
6682     tcg_temp_free_i32(tcg_rmode);
6683 }
6684
6685 /* C3.6.9 AdvSIMD scalar shift by immediate
6686  *  31 30  29 28         23 22  19 18  16 15    11  10 9    5 4    0
6687  * +-----+---+-------------+------+------+--------+---+------+------+
6688  * | 0 1 | U | 1 1 1 1 1 0 | immh | immb | opcode | 1 |  Rn  |  Rd  |
6689  * +-----+---+-------------+------+------+--------+---+------+------+
6690  *
6691  * This is the scalar version so it works on a fixed sized registers
6692  */
6693 static void disas_simd_scalar_shift_imm(DisasContext *s, uint32_t insn)
6694 {
6695     int rd = extract32(insn, 0, 5);
6696     int rn = extract32(insn, 5, 5);
6697     int opcode = extract32(insn, 11, 5);
6698     int immb = extract32(insn, 16, 3);
6699     int immh = extract32(insn, 19, 4);
6700     bool is_u = extract32(insn, 29, 1);
6701
6702     if (immh == 0) {
6703         unallocated_encoding(s);
6704         return;
6705     }
6706
6707     switch (opcode) {
6708     case 0x08: /* SRI */
6709         if (!is_u) {
6710             unallocated_encoding(s);
6711             return;
6712         }
6713         /* fall through */
6714     case 0x00: /* SSHR / USHR */
6715     case 0x02: /* SSRA / USRA */
6716     case 0x04: /* SRSHR / URSHR */
6717     case 0x06: /* SRSRA / URSRA */
6718         handle_scalar_simd_shri(s, is_u, immh, immb, opcode, rn, rd);
6719         break;
6720     case 0x0a: /* SHL / SLI */
6721         handle_scalar_simd_shli(s, is_u, immh, immb, opcode, rn, rd);
6722         break;
6723     case 0x1c: /* SCVTF, UCVTF */
6724         handle_simd_shift_intfp_conv(s, true, false, is_u, immh, immb,
6725                                      opcode, rn, rd);
6726         break;
6727     case 0x10: /* SQSHRUN, SQSHRUN2 */
6728     case 0x11: /* SQRSHRUN, SQRSHRUN2 */
6729         if (!is_u) {
6730             unallocated_encoding(s);
6731             return;
6732         }
6733         handle_vec_simd_sqshrn(s, true, false, false, true,
6734                                immh, immb, opcode, rn, rd);
6735         break;
6736     case 0x12: /* SQSHRN, SQSHRN2, UQSHRN */
6737     case 0x13: /* SQRSHRN, SQRSHRN2, UQRSHRN, UQRSHRN2 */
6738         handle_vec_simd_sqshrn(s, true, false, is_u, is_u,
6739                                immh, immb, opcode, rn, rd);
6740         break;
6741     case 0xc: /* SQSHLU */
6742         if (!is_u) {
6743             unallocated_encoding(s);
6744             return;
6745         }
6746         handle_simd_qshl(s, true, false, false, true, immh, immb, rn, rd);
6747         break;
6748     case 0xe: /* SQSHL, UQSHL */
6749         handle_simd_qshl(s, true, false, is_u, is_u, immh, immb, rn, rd);
6750         break;
6751     case 0x1f: /* FCVTZS, FCVTZU */
6752         handle_simd_shift_fpint_conv(s, true, false, is_u, immh, immb, rn, rd);
6753         break;
6754     default:
6755         unallocated_encoding(s);
6756         break;
6757     }
6758 }
6759
6760 /* C3.6.10 AdvSIMD scalar three different
6761  *  31 30  29 28       24 23  22  21 20  16 15    12 11 10 9    5 4    0
6762  * +-----+---+-----------+------+---+------+--------+-----+------+------+
6763  * | 0 1 | U | 1 1 1 1 0 | size | 1 |  Rm  | opcode | 0 0 |  Rn  |  Rd  |
6764  * +-----+---+-----------+------+---+------+--------+-----+------+------+
6765  */
6766 static void disas_simd_scalar_three_reg_diff(DisasContext *s, uint32_t insn)
6767 {
6768     bool is_u = extract32(insn, 29, 1);
6769     int size = extract32(insn, 22, 2);
6770     int opcode = extract32(insn, 12, 4);
6771     int rm = extract32(insn, 16, 5);
6772     int rn = extract32(insn, 5, 5);
6773     int rd = extract32(insn, 0, 5);
6774
6775     if (is_u) {
6776         unallocated_encoding(s);
6777         return;
6778     }
6779
6780     switch (opcode) {
6781     case 0x9: /* SQDMLAL, SQDMLAL2 */
6782     case 0xb: /* SQDMLSL, SQDMLSL2 */
6783     case 0xd: /* SQDMULL, SQDMULL2 */
6784         if (size == 0 || size == 3) {
6785             unallocated_encoding(s);
6786             return;
6787         }
6788         break;
6789     default:
6790         unallocated_encoding(s);
6791         return;
6792     }
6793
6794     if (!fp_access_check(s)) {
6795         return;
6796     }
6797
6798     if (size == 2) {
6799         TCGv_i64 tcg_op1 = tcg_temp_new_i64();
6800         TCGv_i64 tcg_op2 = tcg_temp_new_i64();
6801         TCGv_i64 tcg_res = tcg_temp_new_i64();
6802
6803         read_vec_element(s, tcg_op1, rn, 0, MO_32 | MO_SIGN);
6804         read_vec_element(s, tcg_op2, rm, 0, MO_32 | MO_SIGN);
6805
6806         tcg_gen_mul_i64(tcg_res, tcg_op1, tcg_op2);
6807         gen_helper_neon_addl_saturate_s64(tcg_res, cpu_env, tcg_res, tcg_res);
6808
6809         switch (opcode) {
6810         case 0xd: /* SQDMULL, SQDMULL2 */
6811             break;
6812         case 0xb: /* SQDMLSL, SQDMLSL2 */
6813             tcg_gen_neg_i64(tcg_res, tcg_res);
6814             /* fall through */
6815         case 0x9: /* SQDMLAL, SQDMLAL2 */
6816             read_vec_element(s, tcg_op1, rd, 0, MO_64);
6817             gen_helper_neon_addl_saturate_s64(tcg_res, cpu_env,
6818                                               tcg_res, tcg_op1);
6819             break;
6820         default:
6821             g_assert_not_reached();
6822         }
6823
6824         write_fp_dreg(s, rd, tcg_res);
6825
6826         tcg_temp_free_i64(tcg_op1);
6827         tcg_temp_free_i64(tcg_op2);
6828         tcg_temp_free_i64(tcg_res);
6829     } else {
6830         TCGv_i32 tcg_op1 = tcg_temp_new_i32();
6831         TCGv_i32 tcg_op2 = tcg_temp_new_i32();
6832         TCGv_i64 tcg_res = tcg_temp_new_i64();
6833
6834         read_vec_element_i32(s, tcg_op1, rn, 0, MO_16);
6835         read_vec_element_i32(s, tcg_op2, rm, 0, MO_16);
6836
6837         gen_helper_neon_mull_s16(tcg_res, tcg_op1, tcg_op2);
6838         gen_helper_neon_addl_saturate_s32(tcg_res, cpu_env, tcg_res, tcg_res);
6839
6840         switch (opcode) {
6841         case 0xd: /* SQDMULL, SQDMULL2 */
6842             break;
6843         case 0xb: /* SQDMLSL, SQDMLSL2 */
6844             gen_helper_neon_negl_u32(tcg_res, tcg_res);
6845             /* fall through */
6846         case 0x9: /* SQDMLAL, SQDMLAL2 */
6847         {
6848             TCGv_i64 tcg_op3 = tcg_temp_new_i64();
6849             read_vec_element(s, tcg_op3, rd, 0, MO_32);
6850             gen_helper_neon_addl_saturate_s32(tcg_res, cpu_env,
6851                                               tcg_res, tcg_op3);
6852             tcg_temp_free_i64(tcg_op3);
6853             break;
6854         }
6855         default:
6856             g_assert_not_reached();
6857         }
6858
6859         tcg_gen_ext32u_i64(tcg_res, tcg_res);
6860         write_fp_dreg(s, rd, tcg_res);
6861
6862         tcg_temp_free_i32(tcg_op1);
6863         tcg_temp_free_i32(tcg_op2);
6864         tcg_temp_free_i64(tcg_res);
6865     }
6866 }
6867
6868 static void handle_3same_64(DisasContext *s, int opcode, bool u,
6869                             TCGv_i64 tcg_rd, TCGv_i64 tcg_rn, TCGv_i64 tcg_rm)
6870 {
6871     /* Handle 64x64->64 opcodes which are shared between the scalar
6872      * and vector 3-same groups. We cover every opcode where size == 3
6873      * is valid in either the three-reg-same (integer, not pairwise)
6874      * or scalar-three-reg-same groups. (Some opcodes are not yet
6875      * implemented.)
6876      */
6877     TCGCond cond;
6878
6879     switch (opcode) {
6880     case 0x1: /* SQADD */
6881         if (u) {
6882             gen_helper_neon_qadd_u64(tcg_rd, cpu_env, tcg_rn, tcg_rm);
6883         } else {
6884             gen_helper_neon_qadd_s64(tcg_rd, cpu_env, tcg_rn, tcg_rm);
6885         }
6886         break;
6887     case 0x5: /* SQSUB */
6888         if (u) {
6889             gen_helper_neon_qsub_u64(tcg_rd, cpu_env, tcg_rn, tcg_rm);
6890         } else {
6891             gen_helper_neon_qsub_s64(tcg_rd, cpu_env, tcg_rn, tcg_rm);
6892         }
6893         break;
6894     case 0x6: /* CMGT, CMHI */
6895         /* 64 bit integer comparison, result = test ? (2^64 - 1) : 0.
6896          * We implement this using setcond (test) and then negating.
6897          */
6898         cond = u ? TCG_COND_GTU : TCG_COND_GT;
6899     do_cmop:
6900         tcg_gen_setcond_i64(cond, tcg_rd, tcg_rn, tcg_rm);
6901         tcg_gen_neg_i64(tcg_rd, tcg_rd);
6902         break;
6903     case 0x7: /* CMGE, CMHS */
6904         cond = u ? TCG_COND_GEU : TCG_COND_GE;
6905         goto do_cmop;
6906     case 0x11: /* CMTST, CMEQ */
6907         if (u) {
6908             cond = TCG_COND_EQ;
6909             goto do_cmop;
6910         }
6911         /* CMTST : test is "if (X & Y != 0)". */
6912         tcg_gen_and_i64(tcg_rd, tcg_rn, tcg_rm);
6913         tcg_gen_setcondi_i64(TCG_COND_NE, tcg_rd, tcg_rd, 0);
6914         tcg_gen_neg_i64(tcg_rd, tcg_rd);
6915         break;
6916     case 0x8: /* SSHL, USHL */
6917         if (u) {
6918             gen_helper_neon_shl_u64(tcg_rd, tcg_rn, tcg_rm);
6919         } else {
6920             gen_helper_neon_shl_s64(tcg_rd, tcg_rn, tcg_rm);
6921         }
6922         break;
6923     case 0x9: /* SQSHL, UQSHL */
6924         if (u) {
6925             gen_helper_neon_qshl_u64(tcg_rd, cpu_env, tcg_rn, tcg_rm);
6926         } else {
6927             gen_helper_neon_qshl_s64(tcg_rd, cpu_env, tcg_rn, tcg_rm);
6928         }
6929         break;
6930     case 0xa: /* SRSHL, URSHL */
6931         if (u) {
6932             gen_helper_neon_rshl_u64(tcg_rd, tcg_rn, tcg_rm);
6933         } else {
6934             gen_helper_neon_rshl_s64(tcg_rd, tcg_rn, tcg_rm);
6935         }
6936         break;
6937     case 0xb: /* SQRSHL, UQRSHL */
6938         if (u) {
6939             gen_helper_neon_qrshl_u64(tcg_rd, cpu_env, tcg_rn, tcg_rm);
6940         } else {
6941             gen_helper_neon_qrshl_s64(tcg_rd, cpu_env, tcg_rn, tcg_rm);
6942         }
6943         break;
6944     case 0x10: /* ADD, SUB */
6945         if (u) {
6946             tcg_gen_sub_i64(tcg_rd, tcg_rn, tcg_rm);
6947         } else {
6948             tcg_gen_add_i64(tcg_rd, tcg_rn, tcg_rm);
6949         }
6950         break;
6951     default:
6952         g_assert_not_reached();
6953     }
6954 }
6955
6956 /* Handle the 3-same-operands float operations; shared by the scalar
6957  * and vector encodings. The caller must filter out any encodings
6958  * not allocated for the encoding it is dealing with.
6959  */
6960 static void handle_3same_float(DisasContext *s, int size, int elements,
6961                                int fpopcode, int rd, int rn, int rm)
6962 {
6963     int pass;
6964     TCGv_ptr fpst = get_fpstatus_ptr();
6965
6966     for (pass = 0; pass < elements; pass++) {
6967         if (size) {
6968             /* Double */
6969             TCGv_i64 tcg_op1 = tcg_temp_new_i64();
6970             TCGv_i64 tcg_op2 = tcg_temp_new_i64();
6971             TCGv_i64 tcg_res = tcg_temp_new_i64();
6972
6973             read_vec_element(s, tcg_op1, rn, pass, MO_64);
6974             read_vec_element(s, tcg_op2, rm, pass, MO_64);
6975
6976             switch (fpopcode) {
6977             case 0x39: /* FMLS */
6978                 /* As usual for ARM, separate negation for fused multiply-add */
6979                 gen_helper_vfp_negd(tcg_op1, tcg_op1);
6980                 /* fall through */
6981             case 0x19: /* FMLA */
6982                 read_vec_element(s, tcg_res, rd, pass, MO_64);
6983                 gen_helper_vfp_muladdd(tcg_res, tcg_op1, tcg_op2,
6984                                        tcg_res, fpst);
6985                 break;
6986             case 0x18: /* FMAXNM */
6987                 gen_helper_vfp_maxnumd(tcg_res, tcg_op1, tcg_op2, fpst);
6988                 break;
6989             case 0x1a: /* FADD */
6990                 gen_helper_vfp_addd(tcg_res, tcg_op1, tcg_op2, fpst);
6991                 break;
6992             case 0x1b: /* FMULX */
6993                 gen_helper_vfp_mulxd(tcg_res, tcg_op1, tcg_op2, fpst);
6994                 break;
6995             case 0x1c: /* FCMEQ */
6996                 gen_helper_neon_ceq_f64(tcg_res, tcg_op1, tcg_op2, fpst);
6997                 break;
6998             case 0x1e: /* FMAX */
6999                 gen_helper_vfp_maxd(tcg_res, tcg_op1, tcg_op2, fpst);
7000                 break;
7001             case 0x1f: /* FRECPS */
7002                 gen_helper_recpsf_f64(tcg_res, tcg_op1, tcg_op2, fpst);
7003                 break;
7004             case 0x38: /* FMINNM */
7005                 gen_helper_vfp_minnumd(tcg_res, tcg_op1, tcg_op2, fpst);
7006                 break;
7007             case 0x3a: /* FSUB */
7008                 gen_helper_vfp_subd(tcg_res, tcg_op1, tcg_op2, fpst);
7009                 break;
7010             case 0x3e: /* FMIN */
7011                 gen_helper_vfp_mind(tcg_res, tcg_op1, tcg_op2, fpst);
7012                 break;
7013             case 0x3f: /* FRSQRTS */
7014                 gen_helper_rsqrtsf_f64(tcg_res, tcg_op1, tcg_op2, fpst);
7015                 break;
7016             case 0x5b: /* FMUL */
7017                 gen_helper_vfp_muld(tcg_res, tcg_op1, tcg_op2, fpst);
7018                 break;
7019             case 0x5c: /* FCMGE */
7020                 gen_helper_neon_cge_f64(tcg_res, tcg_op1, tcg_op2, fpst);
7021                 break;
7022             case 0x5d: /* FACGE */
7023                 gen_helper_neon_acge_f64(tcg_res, tcg_op1, tcg_op2, fpst);
7024                 break;
7025             case 0x5f: /* FDIV */
7026                 gen_helper_vfp_divd(tcg_res, tcg_op1, tcg_op2, fpst);
7027                 break;
7028             case 0x7a: /* FABD */
7029                 gen_helper_vfp_subd(tcg_res, tcg_op1, tcg_op2, fpst);
7030                 gen_helper_vfp_absd(tcg_res, tcg_res);
7031                 break;
7032             case 0x7c: /* FCMGT */
7033                 gen_helper_neon_cgt_f64(tcg_res, tcg_op1, tcg_op2, fpst);
7034                 break;
7035             case 0x7d: /* FACGT */
7036                 gen_helper_neon_acgt_f64(tcg_res, tcg_op1, tcg_op2, fpst);
7037                 break;
7038             default:
7039                 g_assert_not_reached();
7040             }
7041
7042             write_vec_element(s, tcg_res, rd, pass, MO_64);
7043
7044             tcg_temp_free_i64(tcg_res);
7045             tcg_temp_free_i64(tcg_op1);
7046             tcg_temp_free_i64(tcg_op2);
7047         } else {
7048             /* Single */
7049             TCGv_i32 tcg_op1 = tcg_temp_new_i32();
7050             TCGv_i32 tcg_op2 = tcg_temp_new_i32();
7051             TCGv_i32 tcg_res = tcg_temp_new_i32();
7052
7053             read_vec_element_i32(s, tcg_op1, rn, pass, MO_32);
7054             read_vec_element_i32(s, tcg_op2, rm, pass, MO_32);
7055
7056             switch (fpopcode) {
7057             case 0x39: /* FMLS */
7058                 /* As usual for ARM, separate negation for fused multiply-add */
7059                 gen_helper_vfp_negs(tcg_op1, tcg_op1);
7060                 /* fall through */
7061             case 0x19: /* FMLA */
7062                 read_vec_element_i32(s, tcg_res, rd, pass, MO_32);
7063                 gen_helper_vfp_muladds(tcg_res, tcg_op1, tcg_op2,
7064                                        tcg_res, fpst);
7065                 break;
7066             case 0x1a: /* FADD */
7067                 gen_helper_vfp_adds(tcg_res, tcg_op1, tcg_op2, fpst);
7068                 break;
7069             case 0x1b: /* FMULX */
7070                 gen_helper_vfp_mulxs(tcg_res, tcg_op1, tcg_op2, fpst);
7071                 break;
7072             case 0x1c: /* FCMEQ */
7073                 gen_helper_neon_ceq_f32(tcg_res, tcg_op1, tcg_op2, fpst);
7074                 break;
7075             case 0x1e: /* FMAX */
7076                 gen_helper_vfp_maxs(tcg_res, tcg_op1, tcg_op2, fpst);
7077                 break;
7078             case 0x1f: /* FRECPS */
7079                 gen_helper_recpsf_f32(tcg_res, tcg_op1, tcg_op2, fpst);
7080                 break;
7081             case 0x18: /* FMAXNM */
7082                 gen_helper_vfp_maxnums(tcg_res, tcg_op1, tcg_op2, fpst);
7083                 break;
7084             case 0x38: /* FMINNM */
7085                 gen_helper_vfp_minnums(tcg_res, tcg_op1, tcg_op2, fpst);
7086                 break;
7087             case 0x3a: /* FSUB */
7088                 gen_helper_vfp_subs(tcg_res, tcg_op1, tcg_op2, fpst);
7089                 break;
7090             case 0x3e: /* FMIN */
7091                 gen_helper_vfp_mins(tcg_res, tcg_op1, tcg_op2, fpst);
7092                 break;
7093             case 0x3f: /* FRSQRTS */
7094                 gen_helper_rsqrtsf_f32(tcg_res, tcg_op1, tcg_op2, fpst);
7095                 break;
7096             case 0x5b: /* FMUL */
7097                 gen_helper_vfp_muls(tcg_res, tcg_op1, tcg_op2, fpst);
7098                 break;
7099             case 0x5c: /* FCMGE */
7100                 gen_helper_neon_cge_f32(tcg_res, tcg_op1, tcg_op2, fpst);
7101                 break;
7102             case 0x5d: /* FACGE */
7103                 gen_helper_neon_acge_f32(tcg_res, tcg_op1, tcg_op2, fpst);
7104                 break;
7105             case 0x5f: /* FDIV */
7106                 gen_helper_vfp_divs(tcg_res, tcg_op1, tcg_op2, fpst);
7107                 break;
7108             case 0x7a: /* FABD */
7109                 gen_helper_vfp_subs(tcg_res, tcg_op1, tcg_op2, fpst);
7110                 gen_helper_vfp_abss(tcg_res, tcg_res);
7111                 break;
7112             case 0x7c: /* FCMGT */
7113                 gen_helper_neon_cgt_f32(tcg_res, tcg_op1, tcg_op2, fpst);
7114                 break;
7115             case 0x7d: /* FACGT */
7116                 gen_helper_neon_acgt_f32(tcg_res, tcg_op1, tcg_op2, fpst);
7117                 break;
7118             default:
7119                 g_assert_not_reached();
7120             }
7121
7122             if (elements == 1) {
7123                 /* scalar single so clear high part */
7124                 TCGv_i64 tcg_tmp = tcg_temp_new_i64();
7125
7126                 tcg_gen_extu_i32_i64(tcg_tmp, tcg_res);
7127                 write_vec_element(s, tcg_tmp, rd, pass, MO_64);
7128                 tcg_temp_free_i64(tcg_tmp);
7129             } else {
7130                 write_vec_element_i32(s, tcg_res, rd, pass, MO_32);
7131             }
7132
7133             tcg_temp_free_i32(tcg_res);
7134             tcg_temp_free_i32(tcg_op1);
7135             tcg_temp_free_i32(tcg_op2);
7136         }
7137     }
7138
7139     tcg_temp_free_ptr(fpst);
7140
7141     if ((elements << size) < 4) {
7142         /* scalar, or non-quad vector op */
7143         clear_vec_high(s, rd);
7144     }
7145 }
7146
7147 /* C3.6.11 AdvSIMD scalar three same
7148  *  31 30  29 28       24 23  22  21 20  16 15    11  10 9    5 4    0
7149  * +-----+---+-----------+------+---+------+--------+---+------+------+
7150  * | 0 1 | U | 1 1 1 1 0 | size | 1 |  Rm  | opcode | 1 |  Rn  |  Rd  |
7151  * +-----+---+-----------+------+---+------+--------+---+------+------+
7152  */
7153 static void disas_simd_scalar_three_reg_same(DisasContext *s, uint32_t insn)
7154 {
7155     int rd = extract32(insn, 0, 5);
7156     int rn = extract32(insn, 5, 5);
7157     int opcode = extract32(insn, 11, 5);
7158     int rm = extract32(insn, 16, 5);
7159     int size = extract32(insn, 22, 2);
7160     bool u = extract32(insn, 29, 1);
7161     TCGv_i64 tcg_rd;
7162
7163     if (opcode >= 0x18) {
7164         /* Floating point: U, size[1] and opcode indicate operation */
7165         int fpopcode = opcode | (extract32(size, 1, 1) << 5) | (u << 6);
7166         switch (fpopcode) {
7167         case 0x1b: /* FMULX */
7168         case 0x1f: /* FRECPS */
7169         case 0x3f: /* FRSQRTS */
7170         case 0x5d: /* FACGE */
7171         case 0x7d: /* FACGT */
7172         case 0x1c: /* FCMEQ */
7173         case 0x5c: /* FCMGE */
7174         case 0x7c: /* FCMGT */
7175         case 0x7a: /* FABD */
7176             break;
7177         default:
7178             unallocated_encoding(s);
7179             return;
7180         }
7181
7182         if (!fp_access_check(s)) {
7183             return;
7184         }
7185
7186         handle_3same_float(s, extract32(size, 0, 1), 1, fpopcode, rd, rn, rm);
7187         return;
7188     }
7189
7190     switch (opcode) {
7191     case 0x1: /* SQADD, UQADD */
7192     case 0x5: /* SQSUB, UQSUB */
7193     case 0x9: /* SQSHL, UQSHL */
7194     case 0xb: /* SQRSHL, UQRSHL */
7195         break;
7196     case 0x8: /* SSHL, USHL */
7197     case 0xa: /* SRSHL, URSHL */
7198     case 0x6: /* CMGT, CMHI */
7199     case 0x7: /* CMGE, CMHS */
7200     case 0x11: /* CMTST, CMEQ */
7201     case 0x10: /* ADD, SUB (vector) */
7202         if (size != 3) {
7203             unallocated_encoding(s);
7204             return;
7205         }
7206         break;
7207     case 0x16: /* SQDMULH, SQRDMULH (vector) */
7208         if (size != 1 && size != 2) {
7209             unallocated_encoding(s);
7210             return;
7211         }
7212         break;
7213     default:
7214         unallocated_encoding(s);
7215         return;
7216     }
7217
7218     if (!fp_access_check(s)) {
7219         return;
7220     }
7221
7222     tcg_rd = tcg_temp_new_i64();
7223
7224     if (size == 3) {
7225         TCGv_i64 tcg_rn = read_fp_dreg(s, rn);
7226         TCGv_i64 tcg_rm = read_fp_dreg(s, rm);
7227
7228         handle_3same_64(s, opcode, u, tcg_rd, tcg_rn, tcg_rm);
7229         tcg_temp_free_i64(tcg_rn);
7230         tcg_temp_free_i64(tcg_rm);
7231     } else {
7232         /* Do a single operation on the lowest element in the vector.
7233          * We use the standard Neon helpers and rely on 0 OP 0 == 0 with
7234          * no side effects for all these operations.
7235          * OPTME: special-purpose helpers would avoid doing some
7236          * unnecessary work in the helper for the 8 and 16 bit cases.
7237          */
7238         NeonGenTwoOpEnvFn *genenvfn;
7239         TCGv_i32 tcg_rn = tcg_temp_new_i32();
7240         TCGv_i32 tcg_rm = tcg_temp_new_i32();
7241         TCGv_i32 tcg_rd32 = tcg_temp_new_i32();
7242
7243         read_vec_element_i32(s, tcg_rn, rn, 0, size);
7244         read_vec_element_i32(s, tcg_rm, rm, 0, size);
7245
7246         switch (opcode) {
7247         case 0x1: /* SQADD, UQADD */
7248         {
7249             static NeonGenTwoOpEnvFn * const fns[3][2] = {
7250                 { gen_helper_neon_qadd_s8, gen_helper_neon_qadd_u8 },
7251                 { gen_helper_neon_qadd_s16, gen_helper_neon_qadd_u16 },
7252                 { gen_helper_neon_qadd_s32, gen_helper_neon_qadd_u32 },
7253             };
7254             genenvfn = fns[size][u];
7255             break;
7256         }
7257         case 0x5: /* SQSUB, UQSUB */
7258         {
7259             static NeonGenTwoOpEnvFn * const fns[3][2] = {
7260                 { gen_helper_neon_qsub_s8, gen_helper_neon_qsub_u8 },
7261                 { gen_helper_neon_qsub_s16, gen_helper_neon_qsub_u16 },
7262                 { gen_helper_neon_qsub_s32, gen_helper_neon_qsub_u32 },
7263             };
7264             genenvfn = fns[size][u];
7265             break;
7266         }
7267         case 0x9: /* SQSHL, UQSHL */
7268         {
7269             static NeonGenTwoOpEnvFn * const fns[3][2] = {
7270                 { gen_helper_neon_qshl_s8, gen_helper_neon_qshl_u8 },
7271                 { gen_helper_neon_qshl_s16, gen_helper_neon_qshl_u16 },
7272                 { gen_helper_neon_qshl_s32, gen_helper_neon_qshl_u32 },
7273             };
7274             genenvfn = fns[size][u];
7275             break;
7276         }
7277         case 0xb: /* SQRSHL, UQRSHL */
7278         {
7279             static NeonGenTwoOpEnvFn * const fns[3][2] = {
7280                 { gen_helper_neon_qrshl_s8, gen_helper_neon_qrshl_u8 },
7281                 { gen_helper_neon_qrshl_s16, gen_helper_neon_qrshl_u16 },
7282                 { gen_helper_neon_qrshl_s32, gen_helper_neon_qrshl_u32 },
7283             };
7284             genenvfn = fns[size][u];
7285             break;
7286         }
7287         case 0x16: /* SQDMULH, SQRDMULH */
7288         {
7289             static NeonGenTwoOpEnvFn * const fns[2][2] = {
7290                 { gen_helper_neon_qdmulh_s16, gen_helper_neon_qrdmulh_s16 },
7291                 { gen_helper_neon_qdmulh_s32, gen_helper_neon_qrdmulh_s32 },
7292             };
7293             assert(size == 1 || size == 2);
7294             genenvfn = fns[size - 1][u];
7295             break;
7296         }
7297         default:
7298             g_assert_not_reached();
7299         }
7300
7301         genenvfn(tcg_rd32, cpu_env, tcg_rn, tcg_rm);
7302         tcg_gen_extu_i32_i64(tcg_rd, tcg_rd32);
7303         tcg_temp_free_i32(tcg_rd32);
7304         tcg_temp_free_i32(tcg_rn);
7305         tcg_temp_free_i32(tcg_rm);
7306     }
7307
7308     write_fp_dreg(s, rd, tcg_rd);
7309
7310     tcg_temp_free_i64(tcg_rd);
7311 }
7312
7313 static void handle_2misc_64(DisasContext *s, int opcode, bool u,
7314                             TCGv_i64 tcg_rd, TCGv_i64 tcg_rn,
7315                             TCGv_i32 tcg_rmode, TCGv_ptr tcg_fpstatus)
7316 {
7317     /* Handle 64->64 opcodes which are shared between the scalar and
7318      * vector 2-reg-misc groups. We cover every integer opcode where size == 3
7319      * is valid in either group and also the double-precision fp ops.
7320      * The caller only need provide tcg_rmode and tcg_fpstatus if the op
7321      * requires them.
7322      */
7323     TCGCond cond;
7324
7325     switch (opcode) {
7326     case 0x4: /* CLS, CLZ */
7327         if (u) {
7328             gen_helper_clz64(tcg_rd, tcg_rn);
7329         } else {
7330             gen_helper_cls64(tcg_rd, tcg_rn);
7331         }
7332         break;
7333     case 0x5: /* NOT */
7334         /* This opcode is shared with CNT and RBIT but we have earlier
7335          * enforced that size == 3 if and only if this is the NOT insn.
7336          */
7337         tcg_gen_not_i64(tcg_rd, tcg_rn);
7338         break;
7339     case 0x7: /* SQABS, SQNEG */
7340         if (u) {
7341             gen_helper_neon_qneg_s64(tcg_rd, cpu_env, tcg_rn);
7342         } else {
7343             gen_helper_neon_qabs_s64(tcg_rd, cpu_env, tcg_rn);
7344         }
7345         break;
7346     case 0xa: /* CMLT */
7347         /* 64 bit integer comparison against zero, result is
7348          * test ? (2^64 - 1) : 0. We implement via setcond(!test) and
7349          * subtracting 1.
7350          */
7351         cond = TCG_COND_LT;
7352     do_cmop:
7353         tcg_gen_setcondi_i64(cond, tcg_rd, tcg_rn, 0);
7354         tcg_gen_neg_i64(tcg_rd, tcg_rd);
7355         break;
7356     case 0x8: /* CMGT, CMGE */
7357         cond = u ? TCG_COND_GE : TCG_COND_GT;
7358         goto do_cmop;
7359     case 0x9: /* CMEQ, CMLE */
7360         cond = u ? TCG_COND_LE : TCG_COND_EQ;
7361         goto do_cmop;
7362     case 0xb: /* ABS, NEG */
7363         if (u) {
7364             tcg_gen_neg_i64(tcg_rd, tcg_rn);
7365         } else {
7366             TCGv_i64 tcg_zero = tcg_const_i64(0);
7367             tcg_gen_neg_i64(tcg_rd, tcg_rn);
7368             tcg_gen_movcond_i64(TCG_COND_GT, tcg_rd, tcg_rn, tcg_zero,
7369                                 tcg_rn, tcg_rd);
7370             tcg_temp_free_i64(tcg_zero);
7371         }
7372         break;
7373     case 0x2f: /* FABS */
7374         gen_helper_vfp_absd(tcg_rd, tcg_rn);
7375         break;
7376     case 0x6f: /* FNEG */
7377         gen_helper_vfp_negd(tcg_rd, tcg_rn);
7378         break;
7379     case 0x7f: /* FSQRT */
7380         gen_helper_vfp_sqrtd(tcg_rd, tcg_rn, cpu_env);
7381         break;
7382     case 0x1a: /* FCVTNS */
7383     case 0x1b: /* FCVTMS */
7384     case 0x1c: /* FCVTAS */
7385     case 0x3a: /* FCVTPS */
7386     case 0x3b: /* FCVTZS */
7387     {
7388         TCGv_i32 tcg_shift = tcg_const_i32(0);
7389         gen_helper_vfp_tosqd(tcg_rd, tcg_rn, tcg_shift, tcg_fpstatus);
7390         tcg_temp_free_i32(tcg_shift);
7391         break;
7392     }
7393     case 0x5a: /* FCVTNU */
7394     case 0x5b: /* FCVTMU */
7395     case 0x5c: /* FCVTAU */
7396     case 0x7a: /* FCVTPU */
7397     case 0x7b: /* FCVTZU */
7398     {
7399         TCGv_i32 tcg_shift = tcg_const_i32(0);
7400         gen_helper_vfp_touqd(tcg_rd, tcg_rn, tcg_shift, tcg_fpstatus);
7401         tcg_temp_free_i32(tcg_shift);
7402         break;
7403     }
7404     case 0x18: /* FRINTN */
7405     case 0x19: /* FRINTM */
7406     case 0x38: /* FRINTP */
7407     case 0x39: /* FRINTZ */
7408     case 0x58: /* FRINTA */
7409     case 0x79: /* FRINTI */
7410         gen_helper_rintd(tcg_rd, tcg_rn, tcg_fpstatus);
7411         break;
7412     case 0x59: /* FRINTX */
7413         gen_helper_rintd_exact(tcg_rd, tcg_rn, tcg_fpstatus);
7414         break;
7415     default:
7416         g_assert_not_reached();
7417     }
7418 }
7419
7420 static void handle_2misc_fcmp_zero(DisasContext *s, int opcode,
7421                                    bool is_scalar, bool is_u, bool is_q,
7422                                    int size, int rn, int rd)
7423 {
7424     bool is_double = (size == 3);
7425     TCGv_ptr fpst;
7426
7427     if (!fp_access_check(s)) {
7428         return;
7429     }
7430
7431     fpst = get_fpstatus_ptr();
7432
7433     if (is_double) {
7434         TCGv_i64 tcg_op = tcg_temp_new_i64();
7435         TCGv_i64 tcg_zero = tcg_const_i64(0);
7436         TCGv_i64 tcg_res = tcg_temp_new_i64();
7437         NeonGenTwoDoubleOPFn *genfn;
7438         bool swap = false;
7439         int pass;
7440
7441         switch (opcode) {
7442         case 0x2e: /* FCMLT (zero) */
7443             swap = true;
7444             /* fallthrough */
7445         case 0x2c: /* FCMGT (zero) */
7446             genfn = gen_helper_neon_cgt_f64;
7447             break;
7448         case 0x2d: /* FCMEQ (zero) */
7449             genfn = gen_helper_neon_ceq_f64;
7450             break;
7451         case 0x6d: /* FCMLE (zero) */
7452             swap = true;
7453             /* fall through */
7454         case 0x6c: /* FCMGE (zero) */
7455             genfn = gen_helper_neon_cge_f64;
7456             break;
7457         default:
7458             g_assert_not_reached();
7459         }
7460
7461         for (pass = 0; pass < (is_scalar ? 1 : 2); pass++) {
7462             read_vec_element(s, tcg_op, rn, pass, MO_64);
7463             if (swap) {
7464                 genfn(tcg_res, tcg_zero, tcg_op, fpst);
7465             } else {
7466                 genfn(tcg_res, tcg_op, tcg_zero, fpst);
7467             }
7468             write_vec_element(s, tcg_res, rd, pass, MO_64);
7469         }
7470         if (is_scalar) {
7471             clear_vec_high(s, rd);
7472         }
7473
7474         tcg_temp_free_i64(tcg_res);
7475         tcg_temp_free_i64(tcg_zero);
7476         tcg_temp_free_i64(tcg_op);
7477     } else {
7478         TCGv_i32 tcg_op = tcg_temp_new_i32();
7479         TCGv_i32 tcg_zero = tcg_const_i32(0);
7480         TCGv_i32 tcg_res = tcg_temp_new_i32();
7481         NeonGenTwoSingleOPFn *genfn;
7482         bool swap = false;
7483         int pass, maxpasses;
7484
7485         switch (opcode) {
7486         case 0x2e: /* FCMLT (zero) */
7487             swap = true;
7488             /* fall through */
7489         case 0x2c: /* FCMGT (zero) */
7490             genfn = gen_helper_neon_cgt_f32;
7491             break;
7492         case 0x2d: /* FCMEQ (zero) */
7493             genfn = gen_helper_neon_ceq_f32;
7494             break;
7495         case 0x6d: /* FCMLE (zero) */
7496             swap = true;
7497             /* fall through */
7498         case 0x6c: /* FCMGE (zero) */
7499             genfn = gen_helper_neon_cge_f32;
7500             break;
7501         default:
7502             g_assert_not_reached();
7503         }
7504
7505         if (is_scalar) {
7506             maxpasses = 1;
7507         } else {
7508             maxpasses = is_q ? 4 : 2;
7509         }
7510
7511         for (pass = 0; pass < maxpasses; pass++) {
7512             read_vec_element_i32(s, tcg_op, rn, pass, MO_32);
7513             if (swap) {
7514                 genfn(tcg_res, tcg_zero, tcg_op, fpst);
7515             } else {
7516                 genfn(tcg_res, tcg_op, tcg_zero, fpst);
7517             }
7518             if (is_scalar) {
7519                 write_fp_sreg(s, rd, tcg_res);
7520             } else {
7521                 write_vec_element_i32(s, tcg_res, rd, pass, MO_32);
7522             }
7523         }
7524         tcg_temp_free_i32(tcg_res);
7525         tcg_temp_free_i32(tcg_zero);
7526         tcg_temp_free_i32(tcg_op);
7527         if (!is_q && !is_scalar) {
7528             clear_vec_high(s, rd);
7529         }
7530     }
7531
7532     tcg_temp_free_ptr(fpst);
7533 }
7534
7535 static void handle_2misc_reciprocal(DisasContext *s, int opcode,
7536                                     bool is_scalar, bool is_u, bool is_q,
7537                                     int size, int rn, int rd)
7538 {
7539     bool is_double = (size == 3);
7540     TCGv_ptr fpst = get_fpstatus_ptr();
7541
7542     if (is_double) {
7543         TCGv_i64 tcg_op = tcg_temp_new_i64();
7544         TCGv_i64 tcg_res = tcg_temp_new_i64();
7545         int pass;
7546
7547         for (pass = 0; pass < (is_scalar ? 1 : 2); pass++) {
7548             read_vec_element(s, tcg_op, rn, pass, MO_64);
7549             switch (opcode) {
7550             case 0x3d: /* FRECPE */
7551                 gen_helper_recpe_f64(tcg_res, tcg_op, fpst);
7552                 break;
7553             case 0x3f: /* FRECPX */
7554                 gen_helper_frecpx_f64(tcg_res, tcg_op, fpst);
7555                 break;
7556             case 0x7d: /* FRSQRTE */
7557                 gen_helper_rsqrte_f64(tcg_res, tcg_op, fpst);
7558                 break;
7559             default:
7560                 g_assert_not_reached();
7561             }
7562             write_vec_element(s, tcg_res, rd, pass, MO_64);
7563         }
7564         if (is_scalar) {
7565             clear_vec_high(s, rd);
7566         }
7567
7568         tcg_temp_free_i64(tcg_res);
7569         tcg_temp_free_i64(tcg_op);
7570     } else {
7571         TCGv_i32 tcg_op = tcg_temp_new_i32();
7572         TCGv_i32 tcg_res = tcg_temp_new_i32();
7573         int pass, maxpasses;
7574
7575         if (is_scalar) {
7576             maxpasses = 1;
7577         } else {
7578             maxpasses = is_q ? 4 : 2;
7579         }
7580
7581         for (pass = 0; pass < maxpasses; pass++) {
7582             read_vec_element_i32(s, tcg_op, rn, pass, MO_32);
7583
7584             switch (opcode) {
7585             case 0x3c: /* URECPE */
7586                 gen_helper_recpe_u32(tcg_res, tcg_op, fpst);
7587                 break;
7588             case 0x3d: /* FRECPE */
7589                 gen_helper_recpe_f32(tcg_res, tcg_op, fpst);
7590                 break;
7591             case 0x3f: /* FRECPX */
7592                 gen_helper_frecpx_f32(tcg_res, tcg_op, fpst);
7593                 break;
7594             case 0x7d: /* FRSQRTE */
7595                 gen_helper_rsqrte_f32(tcg_res, tcg_op, fpst);
7596                 break;
7597             default:
7598                 g_assert_not_reached();
7599             }
7600
7601             if (is_scalar) {
7602                 write_fp_sreg(s, rd, tcg_res);
7603             } else {
7604                 write_vec_element_i32(s, tcg_res, rd, pass, MO_32);
7605             }
7606         }
7607         tcg_temp_free_i32(tcg_res);
7608         tcg_temp_free_i32(tcg_op);
7609         if (!is_q && !is_scalar) {
7610             clear_vec_high(s, rd);
7611         }
7612     }
7613     tcg_temp_free_ptr(fpst);
7614 }
7615
7616 static void handle_2misc_narrow(DisasContext *s, bool scalar,
7617                                 int opcode, bool u, bool is_q,
7618                                 int size, int rn, int rd)
7619 {
7620     /* Handle 2-reg-misc ops which are narrowing (so each 2*size element
7621      * in the source becomes a size element in the destination).
7622      */
7623     int pass;
7624     TCGv_i32 tcg_res[2];
7625     int destelt = is_q ? 2 : 0;
7626     int passes = scalar ? 1 : 2;
7627
7628     if (scalar) {
7629         tcg_res[1] = tcg_const_i32(0);
7630     }
7631
7632     for (pass = 0; pass < passes; pass++) {
7633         TCGv_i64 tcg_op = tcg_temp_new_i64();
7634         NeonGenNarrowFn *genfn = NULL;
7635         NeonGenNarrowEnvFn *genenvfn = NULL;
7636
7637         if (scalar) {
7638             read_vec_element(s, tcg_op, rn, pass, size + 1);
7639         } else {
7640             read_vec_element(s, tcg_op, rn, pass, MO_64);
7641         }
7642         tcg_res[pass] = tcg_temp_new_i32();
7643
7644         switch (opcode) {
7645         case 0x12: /* XTN, SQXTUN */
7646         {
7647             static NeonGenNarrowFn * const xtnfns[3] = {
7648                 gen_helper_neon_narrow_u8,
7649                 gen_helper_neon_narrow_u16,
7650                 tcg_gen_trunc_i64_i32,
7651             };
7652             static NeonGenNarrowEnvFn * const sqxtunfns[3] = {
7653                 gen_helper_neon_unarrow_sat8,
7654                 gen_helper_neon_unarrow_sat16,
7655                 gen_helper_neon_unarrow_sat32,
7656             };
7657             if (u) {
7658                 genenvfn = sqxtunfns[size];
7659             } else {
7660                 genfn = xtnfns[size];
7661             }
7662             break;
7663         }
7664         case 0x14: /* SQXTN, UQXTN */
7665         {
7666             static NeonGenNarrowEnvFn * const fns[3][2] = {
7667                 { gen_helper_neon_narrow_sat_s8,
7668                   gen_helper_neon_narrow_sat_u8 },
7669                 { gen_helper_neon_narrow_sat_s16,
7670                   gen_helper_neon_narrow_sat_u16 },
7671                 { gen_helper_neon_narrow_sat_s32,
7672                   gen_helper_neon_narrow_sat_u32 },
7673             };
7674             genenvfn = fns[size][u];
7675             break;
7676         }
7677         case 0x16: /* FCVTN, FCVTN2 */
7678             /* 32 bit to 16 bit or 64 bit to 32 bit float conversion */
7679             if (size == 2) {
7680                 gen_helper_vfp_fcvtsd(tcg_res[pass], tcg_op, cpu_env);
7681             } else {
7682                 TCGv_i32 tcg_lo = tcg_temp_new_i32();
7683                 TCGv_i32 tcg_hi = tcg_temp_new_i32();
7684                 tcg_gen_trunc_i64_i32(tcg_lo, tcg_op);
7685                 gen_helper_vfp_fcvt_f32_to_f16(tcg_lo, tcg_lo, cpu_env);
7686                 tcg_gen_shri_i64(tcg_op, tcg_op, 32);
7687                 tcg_gen_trunc_i64_i32(tcg_hi, tcg_op);
7688                 gen_helper_vfp_fcvt_f32_to_f16(tcg_hi, tcg_hi, cpu_env);
7689                 tcg_gen_deposit_i32(tcg_res[pass], tcg_lo, tcg_hi, 16, 16);
7690                 tcg_temp_free_i32(tcg_lo);
7691                 tcg_temp_free_i32(tcg_hi);
7692             }
7693             break;
7694         case 0x56:  /* FCVTXN, FCVTXN2 */
7695             /* 64 bit to 32 bit float conversion
7696              * with von Neumann rounding (round to odd)
7697              */
7698             assert(size == 2);
7699             gen_helper_fcvtx_f64_to_f32(tcg_res[pass], tcg_op, cpu_env);
7700             break;
7701         default:
7702             g_assert_not_reached();
7703         }
7704
7705         if (genfn) {
7706             genfn(tcg_res[pass], tcg_op);
7707         } else if (genenvfn) {
7708             genenvfn(tcg_res[pass], cpu_env, tcg_op);
7709         }
7710
7711         tcg_temp_free_i64(tcg_op);
7712     }
7713
7714     for (pass = 0; pass < 2; pass++) {
7715         write_vec_element_i32(s, tcg_res[pass], rd, destelt + pass, MO_32);
7716         tcg_temp_free_i32(tcg_res[pass]);
7717     }
7718     if (!is_q) {
7719         clear_vec_high(s, rd);
7720     }
7721 }
7722
7723 /* Remaining saturating accumulating ops */
7724 static void handle_2misc_satacc(DisasContext *s, bool is_scalar, bool is_u,
7725                                 bool is_q, int size, int rn, int rd)
7726 {
7727     bool is_double = (size == 3);
7728
7729     if (is_double) {
7730         TCGv_i64 tcg_rn = tcg_temp_new_i64();
7731         TCGv_i64 tcg_rd = tcg_temp_new_i64();
7732         int pass;
7733
7734         for (pass = 0; pass < (is_scalar ? 1 : 2); pass++) {
7735             read_vec_element(s, tcg_rn, rn, pass, MO_64);
7736             read_vec_element(s, tcg_rd, rd, pass, MO_64);
7737
7738             if (is_u) { /* USQADD */
7739                 gen_helper_neon_uqadd_s64(tcg_rd, cpu_env, tcg_rn, tcg_rd);
7740             } else { /* SUQADD */
7741                 gen_helper_neon_sqadd_u64(tcg_rd, cpu_env, tcg_rn, tcg_rd);
7742             }
7743             write_vec_element(s, tcg_rd, rd, pass, MO_64);
7744         }
7745         if (is_scalar) {
7746             clear_vec_high(s, rd);
7747         }
7748
7749         tcg_temp_free_i64(tcg_rd);
7750         tcg_temp_free_i64(tcg_rn);
7751     } else {
7752         TCGv_i32 tcg_rn = tcg_temp_new_i32();
7753         TCGv_i32 tcg_rd = tcg_temp_new_i32();
7754         int pass, maxpasses;
7755
7756         if (is_scalar) {
7757             maxpasses = 1;
7758         } else {
7759             maxpasses = is_q ? 4 : 2;
7760         }
7761
7762         for (pass = 0; pass < maxpasses; pass++) {
7763             if (is_scalar) {
7764                 read_vec_element_i32(s, tcg_rn, rn, pass, size);
7765                 read_vec_element_i32(s, tcg_rd, rd, pass, size);
7766             } else {
7767                 read_vec_element_i32(s, tcg_rn, rn, pass, MO_32);
7768                 read_vec_element_i32(s, tcg_rd, rd, pass, MO_32);
7769             }
7770
7771             if (is_u) { /* USQADD */
7772                 switch (size) {
7773                 case 0:
7774                     gen_helper_neon_uqadd_s8(tcg_rd, cpu_env, tcg_rn, tcg_rd);
7775                     break;
7776                 case 1:
7777                     gen_helper_neon_uqadd_s16(tcg_rd, cpu_env, tcg_rn, tcg_rd);
7778                     break;
7779                 case 2:
7780                     gen_helper_neon_uqadd_s32(tcg_rd, cpu_env, tcg_rn, tcg_rd);
7781                     break;
7782                 default:
7783                     g_assert_not_reached();
7784                 }
7785             } else { /* SUQADD */
7786                 switch (size) {
7787                 case 0:
7788                     gen_helper_neon_sqadd_u8(tcg_rd, cpu_env, tcg_rn, tcg_rd);
7789                     break;
7790                 case 1:
7791                     gen_helper_neon_sqadd_u16(tcg_rd, cpu_env, tcg_rn, tcg_rd);
7792                     break;
7793                 case 2:
7794                     gen_helper_neon_sqadd_u32(tcg_rd, cpu_env, tcg_rn, tcg_rd);
7795                     break;
7796                 default:
7797                     g_assert_not_reached();
7798                 }
7799             }
7800
7801             if (is_scalar) {
7802                 TCGv_i64 tcg_zero = tcg_const_i64(0);
7803                 write_vec_element(s, tcg_zero, rd, 0, MO_64);
7804                 tcg_temp_free_i64(tcg_zero);
7805             }
7806             write_vec_element_i32(s, tcg_rd, rd, pass, MO_32);
7807         }
7808
7809         if (!is_q) {
7810             clear_vec_high(s, rd);
7811         }
7812
7813         tcg_temp_free_i32(tcg_rd);
7814         tcg_temp_free_i32(tcg_rn);
7815     }
7816 }
7817
7818 /* C3.6.12 AdvSIMD scalar two reg misc
7819  *  31 30  29 28       24 23  22 21       17 16    12 11 10 9    5 4    0
7820  * +-----+---+-----------+------+-----------+--------+-----+------+------+
7821  * | 0 1 | U | 1 1 1 1 0 | size | 1 0 0 0 0 | opcode | 1 0 |  Rn  |  Rd  |
7822  * +-----+---+-----------+------+-----------+--------+-----+------+------+
7823  */
7824 static void disas_simd_scalar_two_reg_misc(DisasContext *s, uint32_t insn)
7825 {
7826     int rd = extract32(insn, 0, 5);
7827     int rn = extract32(insn, 5, 5);
7828     int opcode = extract32(insn, 12, 5);
7829     int size = extract32(insn, 22, 2);
7830     bool u = extract32(insn, 29, 1);
7831     bool is_fcvt = false;
7832     int rmode;
7833     TCGv_i32 tcg_rmode;
7834     TCGv_ptr tcg_fpstatus;
7835
7836     switch (opcode) {
7837     case 0x3: /* USQADD / SUQADD*/
7838         if (!fp_access_check(s)) {
7839             return;
7840         }
7841         handle_2misc_satacc(s, true, u, false, size, rn, rd);
7842         return;
7843     case 0x7: /* SQABS / SQNEG */
7844         break;
7845     case 0xa: /* CMLT */
7846         if (u) {
7847             unallocated_encoding(s);
7848             return;
7849         }
7850         /* fall through */
7851     case 0x8: /* CMGT, CMGE */
7852     case 0x9: /* CMEQ, CMLE */
7853     case 0xb: /* ABS, NEG */
7854         if (size != 3) {
7855             unallocated_encoding(s);
7856             return;
7857         }
7858         break;
7859     case 0x12: /* SQXTUN */
7860         if (!u) {
7861             unallocated_encoding(s);
7862             return;
7863         }
7864         /* fall through */
7865     case 0x14: /* SQXTN, UQXTN */
7866         if (size == 3) {
7867             unallocated_encoding(s);
7868             return;
7869         }
7870         if (!fp_access_check(s)) {
7871             return;
7872         }
7873         handle_2misc_narrow(s, true, opcode, u, false, size, rn, rd);
7874         return;
7875     case 0xc ... 0xf:
7876     case 0x16 ... 0x1d:
7877     case 0x1f:
7878         /* Floating point: U, size[1] and opcode indicate operation;
7879          * size[0] indicates single or double precision.
7880          */
7881         opcode |= (extract32(size, 1, 1) << 5) | (u << 6);
7882         size = extract32(size, 0, 1) ? 3 : 2;
7883         switch (opcode) {
7884         case 0x2c: /* FCMGT (zero) */
7885         case 0x2d: /* FCMEQ (zero) */
7886         case 0x2e: /* FCMLT (zero) */
7887         case 0x6c: /* FCMGE (zero) */
7888         case 0x6d: /* FCMLE (zero) */
7889             handle_2misc_fcmp_zero(s, opcode, true, u, true, size, rn, rd);
7890             return;
7891         case 0x1d: /* SCVTF */
7892         case 0x5d: /* UCVTF */
7893         {
7894             bool is_signed = (opcode == 0x1d);
7895             if (!fp_access_check(s)) {
7896                 return;
7897             }
7898             handle_simd_intfp_conv(s, rd, rn, 1, is_signed, 0, size);
7899             return;
7900         }
7901         case 0x3d: /* FRECPE */
7902         case 0x3f: /* FRECPX */
7903         case 0x7d: /* FRSQRTE */
7904             if (!fp_access_check(s)) {
7905                 return;
7906             }
7907             handle_2misc_reciprocal(s, opcode, true, u, true, size, rn, rd);
7908             return;
7909         case 0x1a: /* FCVTNS */
7910         case 0x1b: /* FCVTMS */
7911         case 0x3a: /* FCVTPS */
7912         case 0x3b: /* FCVTZS */
7913         case 0x5a: /* FCVTNU */
7914         case 0x5b: /* FCVTMU */
7915         case 0x7a: /* FCVTPU */
7916         case 0x7b: /* FCVTZU */
7917             is_fcvt = true;
7918             rmode = extract32(opcode, 5, 1) | (extract32(opcode, 0, 1) << 1);
7919             break;
7920         case 0x1c: /* FCVTAS */
7921         case 0x5c: /* FCVTAU */
7922             /* TIEAWAY doesn't fit in the usual rounding mode encoding */
7923             is_fcvt = true;
7924             rmode = FPROUNDING_TIEAWAY;
7925             break;
7926         case 0x56: /* FCVTXN, FCVTXN2 */
7927             if (size == 2) {
7928                 unallocated_encoding(s);
7929                 return;
7930             }
7931             if (!fp_access_check(s)) {
7932                 return;
7933             }
7934             handle_2misc_narrow(s, true, opcode, u, false, size - 1, rn, rd);
7935             return;
7936         default:
7937             unallocated_encoding(s);
7938             return;
7939         }
7940         break;
7941     default:
7942         unallocated_encoding(s);
7943         return;
7944     }
7945
7946     if (!fp_access_check(s)) {
7947         return;
7948     }
7949
7950     if (is_fcvt) {
7951         tcg_rmode = tcg_const_i32(arm_rmode_to_sf(rmode));
7952         gen_helper_set_rmode(tcg_rmode, tcg_rmode, cpu_env);
7953         tcg_fpstatus = get_fpstatus_ptr();
7954     } else {
7955         TCGV_UNUSED_I32(tcg_rmode);
7956         TCGV_UNUSED_PTR(tcg_fpstatus);
7957     }
7958
7959     if (size == 3) {
7960         TCGv_i64 tcg_rn = read_fp_dreg(s, rn);
7961         TCGv_i64 tcg_rd = tcg_temp_new_i64();
7962
7963         handle_2misc_64(s, opcode, u, tcg_rd, tcg_rn, tcg_rmode, tcg_fpstatus);
7964         write_fp_dreg(s, rd, tcg_rd);
7965         tcg_temp_free_i64(tcg_rd);
7966         tcg_temp_free_i64(tcg_rn);
7967     } else {
7968         TCGv_i32 tcg_rn = tcg_temp_new_i32();
7969         TCGv_i32 tcg_rd = tcg_temp_new_i32();
7970
7971         read_vec_element_i32(s, tcg_rn, rn, 0, size);
7972
7973         switch (opcode) {
7974         case 0x7: /* SQABS, SQNEG */
7975         {
7976             NeonGenOneOpEnvFn *genfn;
7977             static NeonGenOneOpEnvFn * const fns[3][2] = {
7978                 { gen_helper_neon_qabs_s8, gen_helper_neon_qneg_s8 },
7979                 { gen_helper_neon_qabs_s16, gen_helper_neon_qneg_s16 },
7980                 { gen_helper_neon_qabs_s32, gen_helper_neon_qneg_s32 },
7981             };
7982             genfn = fns[size][u];
7983             genfn(tcg_rd, cpu_env, tcg_rn);
7984             break;
7985         }
7986         case 0x1a: /* FCVTNS */
7987         case 0x1b: /* FCVTMS */
7988         case 0x1c: /* FCVTAS */
7989         case 0x3a: /* FCVTPS */
7990         case 0x3b: /* FCVTZS */
7991         {
7992             TCGv_i32 tcg_shift = tcg_const_i32(0);
7993             gen_helper_vfp_tosls(tcg_rd, tcg_rn, tcg_shift, tcg_fpstatus);
7994             tcg_temp_free_i32(tcg_shift);
7995             break;
7996         }
7997         case 0x5a: /* FCVTNU */
7998         case 0x5b: /* FCVTMU */
7999         case 0x5c: /* FCVTAU */
8000         case 0x7a: /* FCVTPU */
8001         case 0x7b: /* FCVTZU */
8002         {
8003             TCGv_i32 tcg_shift = tcg_const_i32(0);
8004             gen_helper_vfp_touls(tcg_rd, tcg_rn, tcg_shift, tcg_fpstatus);
8005             tcg_temp_free_i32(tcg_shift);
8006             break;
8007         }
8008         default:
8009             g_assert_not_reached();
8010         }
8011
8012         write_fp_sreg(s, rd, tcg_rd);
8013         tcg_temp_free_i32(tcg_rd);
8014         tcg_temp_free_i32(tcg_rn);
8015     }
8016
8017     if (is_fcvt) {
8018         gen_helper_set_rmode(tcg_rmode, tcg_rmode, cpu_env);
8019         tcg_temp_free_i32(tcg_rmode);
8020         tcg_temp_free_ptr(tcg_fpstatus);
8021     }
8022 }
8023
8024 /* SSHR[RA]/USHR[RA] - Vector shift right (optional rounding/accumulate) */
8025 static void handle_vec_simd_shri(DisasContext *s, bool is_q, bool is_u,
8026                                  int immh, int immb, int opcode, int rn, int rd)
8027 {
8028     int size = 32 - clz32(immh) - 1;
8029     int immhb = immh << 3 | immb;
8030     int shift = 2 * (8 << size) - immhb;
8031     bool accumulate = false;
8032     bool round = false;
8033     bool insert = false;
8034     int dsize = is_q ? 128 : 64;
8035     int esize = 8 << size;
8036     int elements = dsize/esize;
8037     TCGMemOp memop = size | (is_u ? 0 : MO_SIGN);
8038     TCGv_i64 tcg_rn = new_tmp_a64(s);
8039     TCGv_i64 tcg_rd = new_tmp_a64(s);
8040     TCGv_i64 tcg_round;
8041     int i;
8042
8043     if (extract32(immh, 3, 1) && !is_q) {
8044         unallocated_encoding(s);
8045         return;
8046     }
8047
8048     if (size > 3 && !is_q) {
8049         unallocated_encoding(s);
8050         return;
8051     }
8052
8053     if (!fp_access_check(s)) {
8054         return;
8055     }
8056
8057     switch (opcode) {
8058     case 0x02: /* SSRA / USRA (accumulate) */
8059         accumulate = true;
8060         break;
8061     case 0x04: /* SRSHR / URSHR (rounding) */
8062         round = true;
8063         break;
8064     case 0x06: /* SRSRA / URSRA (accum + rounding) */
8065         accumulate = round = true;
8066         break;
8067     case 0x08: /* SRI */
8068         insert = true;
8069         break;
8070     }
8071
8072     if (round) {
8073         uint64_t round_const = 1ULL << (shift - 1);
8074         tcg_round = tcg_const_i64(round_const);
8075     } else {
8076         TCGV_UNUSED_I64(tcg_round);
8077     }
8078
8079     for (i = 0; i < elements; i++) {
8080         read_vec_element(s, tcg_rn, rn, i, memop);
8081         if (accumulate || insert) {
8082             read_vec_element(s, tcg_rd, rd, i, memop);
8083         }
8084
8085         if (insert) {
8086             handle_shri_with_ins(tcg_rd, tcg_rn, size, shift);
8087         } else {
8088             handle_shri_with_rndacc(tcg_rd, tcg_rn, tcg_round,
8089                                     accumulate, is_u, size, shift);
8090         }
8091
8092         write_vec_element(s, tcg_rd, rd, i, size);
8093     }
8094
8095     if (!is_q) {
8096         clear_vec_high(s, rd);
8097     }
8098
8099     if (round) {
8100         tcg_temp_free_i64(tcg_round);
8101     }
8102 }
8103
8104 /* SHL/SLI - Vector shift left */
8105 static void handle_vec_simd_shli(DisasContext *s, bool is_q, bool insert,
8106                                 int immh, int immb, int opcode, int rn, int rd)
8107 {
8108     int size = 32 - clz32(immh) - 1;
8109     int immhb = immh << 3 | immb;
8110     int shift = immhb - (8 << size);
8111     int dsize = is_q ? 128 : 64;
8112     int esize = 8 << size;
8113     int elements = dsize/esize;
8114     TCGv_i64 tcg_rn = new_tmp_a64(s);
8115     TCGv_i64 tcg_rd = new_tmp_a64(s);
8116     int i;
8117
8118     if (extract32(immh, 3, 1) && !is_q) {
8119         unallocated_encoding(s);
8120         return;
8121     }
8122
8123     if (size > 3 && !is_q) {
8124         unallocated_encoding(s);
8125         return;
8126     }
8127
8128     if (!fp_access_check(s)) {
8129         return;
8130     }
8131
8132     for (i = 0; i < elements; i++) {
8133         read_vec_element(s, tcg_rn, rn, i, size);
8134         if (insert) {
8135             read_vec_element(s, tcg_rd, rd, i, size);
8136         }
8137
8138         handle_shli_with_ins(tcg_rd, tcg_rn, insert, shift);
8139
8140         write_vec_element(s, tcg_rd, rd, i, size);
8141     }
8142
8143     if (!is_q) {
8144         clear_vec_high(s, rd);
8145     }
8146 }
8147
8148 /* USHLL/SHLL - Vector shift left with widening */
8149 static void handle_vec_simd_wshli(DisasContext *s, bool is_q, bool is_u,
8150                                  int immh, int immb, int opcode, int rn, int rd)
8151 {
8152     int size = 32 - clz32(immh) - 1;
8153     int immhb = immh << 3 | immb;
8154     int shift = immhb - (8 << size);
8155     int dsize = 64;
8156     int esize = 8 << size;
8157     int elements = dsize/esize;
8158     TCGv_i64 tcg_rn = new_tmp_a64(s);
8159     TCGv_i64 tcg_rd = new_tmp_a64(s);
8160     int i;
8161
8162     if (size >= 3) {
8163         unallocated_encoding(s);
8164         return;
8165     }
8166
8167     if (!fp_access_check(s)) {
8168         return;
8169     }
8170
8171     /* For the LL variants the store is larger than the load,
8172      * so if rd == rn we would overwrite parts of our input.
8173      * So load everything right now and use shifts in the main loop.
8174      */
8175     read_vec_element(s, tcg_rn, rn, is_q ? 1 : 0, MO_64);
8176
8177     for (i = 0; i < elements; i++) {
8178         tcg_gen_shri_i64(tcg_rd, tcg_rn, i * esize);
8179         ext_and_shift_reg(tcg_rd, tcg_rd, size | (!is_u << 2), 0);
8180         tcg_gen_shli_i64(tcg_rd, tcg_rd, shift);
8181         write_vec_element(s, tcg_rd, rd, i, size + 1);
8182     }
8183 }
8184
8185 /* SHRN/RSHRN - Shift right with narrowing (and potential rounding) */
8186 static void handle_vec_simd_shrn(DisasContext *s, bool is_q,
8187                                  int immh, int immb, int opcode, int rn, int rd)
8188 {
8189     int immhb = immh << 3 | immb;
8190     int size = 32 - clz32(immh) - 1;
8191     int dsize = 64;
8192     int esize = 8 << size;
8193     int elements = dsize/esize;
8194     int shift = (2 * esize) - immhb;
8195     bool round = extract32(opcode, 0, 1);
8196     TCGv_i64 tcg_rn, tcg_rd, tcg_final;
8197     TCGv_i64 tcg_round;
8198     int i;
8199
8200     if (extract32(immh, 3, 1)) {
8201         unallocated_encoding(s);
8202         return;
8203     }
8204
8205     if (!fp_access_check(s)) {
8206         return;
8207     }
8208
8209     tcg_rn = tcg_temp_new_i64();
8210     tcg_rd = tcg_temp_new_i64();
8211     tcg_final = tcg_temp_new_i64();
8212     read_vec_element(s, tcg_final, rd, is_q ? 1 : 0, MO_64);
8213
8214     if (round) {
8215         uint64_t round_const = 1ULL << (shift - 1);
8216         tcg_round = tcg_const_i64(round_const);
8217     } else {
8218         TCGV_UNUSED_I64(tcg_round);
8219     }
8220
8221     for (i = 0; i < elements; i++) {
8222         read_vec_element(s, tcg_rn, rn, i, size+1);
8223         handle_shri_with_rndacc(tcg_rd, tcg_rn, tcg_round,
8224                                 false, true, size+1, shift);
8225
8226         tcg_gen_deposit_i64(tcg_final, tcg_final, tcg_rd, esize * i, esize);
8227     }
8228
8229     if (!is_q) {
8230         clear_vec_high(s, rd);
8231         write_vec_element(s, tcg_final, rd, 0, MO_64);
8232     } else {
8233         write_vec_element(s, tcg_final, rd, 1, MO_64);
8234     }
8235
8236     if (round) {
8237         tcg_temp_free_i64(tcg_round);
8238     }
8239     tcg_temp_free_i64(tcg_rn);
8240     tcg_temp_free_i64(tcg_rd);
8241     tcg_temp_free_i64(tcg_final);
8242     return;
8243 }
8244
8245
8246 /* C3.6.14 AdvSIMD shift by immediate
8247  *  31  30   29 28         23 22  19 18  16 15    11  10 9    5 4    0
8248  * +---+---+---+-------------+------+------+--------+---+------+------+
8249  * | 0 | Q | U | 0 1 1 1 1 0 | immh | immb | opcode | 1 |  Rn  |  Rd  |
8250  * +---+---+---+-------------+------+------+--------+---+------+------+
8251  */
8252 static void disas_simd_shift_imm(DisasContext *s, uint32_t insn)
8253 {
8254     int rd = extract32(insn, 0, 5);
8255     int rn = extract32(insn, 5, 5);
8256     int opcode = extract32(insn, 11, 5);
8257     int immb = extract32(insn, 16, 3);
8258     int immh = extract32(insn, 19, 4);
8259     bool is_u = extract32(insn, 29, 1);
8260     bool is_q = extract32(insn, 30, 1);
8261
8262     switch (opcode) {
8263     case 0x08: /* SRI */
8264         if (!is_u) {
8265             unallocated_encoding(s);
8266             return;
8267         }
8268         /* fall through */
8269     case 0x00: /* SSHR / USHR */
8270     case 0x02: /* SSRA / USRA (accumulate) */
8271     case 0x04: /* SRSHR / URSHR (rounding) */
8272     case 0x06: /* SRSRA / URSRA (accum + rounding) */
8273         handle_vec_simd_shri(s, is_q, is_u, immh, immb, opcode, rn, rd);
8274         break;
8275     case 0x0a: /* SHL / SLI */
8276         handle_vec_simd_shli(s, is_q, is_u, immh, immb, opcode, rn, rd);
8277         break;
8278     case 0x10: /* SHRN */
8279     case 0x11: /* RSHRN / SQRSHRUN */
8280         if (is_u) {
8281             handle_vec_simd_sqshrn(s, false, is_q, false, true, immh, immb,
8282                                    opcode, rn, rd);
8283         } else {
8284             handle_vec_simd_shrn(s, is_q, immh, immb, opcode, rn, rd);
8285         }
8286         break;
8287     case 0x12: /* SQSHRN / UQSHRN */
8288     case 0x13: /* SQRSHRN / UQRSHRN */
8289         handle_vec_simd_sqshrn(s, false, is_q, is_u, is_u, immh, immb,
8290                                opcode, rn, rd);
8291         break;
8292     case 0x14: /* SSHLL / USHLL */
8293         handle_vec_simd_wshli(s, is_q, is_u, immh, immb, opcode, rn, rd);
8294         break;
8295     case 0x1c: /* SCVTF / UCVTF */
8296         handle_simd_shift_intfp_conv(s, false, is_q, is_u, immh, immb,
8297                                      opcode, rn, rd);
8298         break;
8299     case 0xc: /* SQSHLU */
8300         if (!is_u) {
8301             unallocated_encoding(s);
8302             return;
8303         }
8304         handle_simd_qshl(s, false, is_q, false, true, immh, immb, rn, rd);
8305         break;
8306     case 0xe: /* SQSHL, UQSHL */
8307         handle_simd_qshl(s, false, is_q, is_u, is_u, immh, immb, rn, rd);
8308         break;
8309     case 0x1f: /* FCVTZS/ FCVTZU */
8310         handle_simd_shift_fpint_conv(s, false, is_q, is_u, immh, immb, rn, rd);
8311         return;
8312     default:
8313         unallocated_encoding(s);
8314         return;
8315     }
8316 }
8317
8318 /* Generate code to do a "long" addition or subtraction, ie one done in
8319  * TCGv_i64 on vector lanes twice the width specified by size.
8320  */
8321 static void gen_neon_addl(int size, bool is_sub, TCGv_i64 tcg_res,
8322                           TCGv_i64 tcg_op1, TCGv_i64 tcg_op2)
8323 {
8324     static NeonGenTwo64OpFn * const fns[3][2] = {
8325         { gen_helper_neon_addl_u16, gen_helper_neon_subl_u16 },
8326         { gen_helper_neon_addl_u32, gen_helper_neon_subl_u32 },
8327         { tcg_gen_add_i64, tcg_gen_sub_i64 },
8328     };
8329     NeonGenTwo64OpFn *genfn;
8330     assert(size < 3);
8331
8332     genfn = fns[size][is_sub];
8333     genfn(tcg_res, tcg_op1, tcg_op2);
8334 }
8335
8336 static void handle_3rd_widening(DisasContext *s, int is_q, int is_u, int size,
8337                                 int opcode, int rd, int rn, int rm)
8338 {
8339     /* 3-reg-different widening insns: 64 x 64 -> 128 */
8340     TCGv_i64 tcg_res[2];
8341     int pass, accop;
8342
8343     tcg_res[0] = tcg_temp_new_i64();
8344     tcg_res[1] = tcg_temp_new_i64();
8345
8346     /* Does this op do an adding accumulate, a subtracting accumulate,
8347      * or no accumulate at all?
8348      */
8349     switch (opcode) {
8350     case 5:
8351     case 8:
8352     case 9:
8353         accop = 1;
8354         break;
8355     case 10:
8356     case 11:
8357         accop = -1;
8358         break;
8359     default:
8360         accop = 0;
8361         break;
8362     }
8363
8364     if (accop != 0) {
8365         read_vec_element(s, tcg_res[0], rd, 0, MO_64);
8366         read_vec_element(s, tcg_res[1], rd, 1, MO_64);
8367     }
8368
8369     /* size == 2 means two 32x32->64 operations; this is worth special
8370      * casing because we can generally handle it inline.
8371      */
8372     if (size == 2) {
8373         for (pass = 0; pass < 2; pass++) {
8374             TCGv_i64 tcg_op1 = tcg_temp_new_i64();
8375             TCGv_i64 tcg_op2 = tcg_temp_new_i64();
8376             TCGv_i64 tcg_passres;
8377             TCGMemOp memop = MO_32 | (is_u ? 0 : MO_SIGN);
8378
8379             int elt = pass + is_q * 2;
8380
8381             read_vec_element(s, tcg_op1, rn, elt, memop);
8382             read_vec_element(s, tcg_op2, rm, elt, memop);
8383
8384             if (accop == 0) {
8385                 tcg_passres = tcg_res[pass];
8386             } else {
8387                 tcg_passres = tcg_temp_new_i64();
8388             }
8389
8390             switch (opcode) {
8391             case 0: /* SADDL, SADDL2, UADDL, UADDL2 */
8392                 tcg_gen_add_i64(tcg_passres, tcg_op1, tcg_op2);
8393                 break;
8394             case 2: /* SSUBL, SSUBL2, USUBL, USUBL2 */
8395                 tcg_gen_sub_i64(tcg_passres, tcg_op1, tcg_op2);
8396                 break;
8397             case 5: /* SABAL, SABAL2, UABAL, UABAL2 */
8398             case 7: /* SABDL, SABDL2, UABDL, UABDL2 */
8399             {
8400                 TCGv_i64 tcg_tmp1 = tcg_temp_new_i64();
8401                 TCGv_i64 tcg_tmp2 = tcg_temp_new_i64();
8402
8403                 tcg_gen_sub_i64(tcg_tmp1, tcg_op1, tcg_op2);
8404                 tcg_gen_sub_i64(tcg_tmp2, tcg_op2, tcg_op1);
8405                 tcg_gen_movcond_i64(is_u ? TCG_COND_GEU : TCG_COND_GE,
8406                                     tcg_passres,
8407                                     tcg_op1, tcg_op2, tcg_tmp1, tcg_tmp2);
8408                 tcg_temp_free_i64(tcg_tmp1);
8409                 tcg_temp_free_i64(tcg_tmp2);
8410                 break;
8411             }
8412             case 8: /* SMLAL, SMLAL2, UMLAL, UMLAL2 */
8413             case 10: /* SMLSL, SMLSL2, UMLSL, UMLSL2 */
8414             case 12: /* UMULL, UMULL2, SMULL, SMULL2 */
8415                 tcg_gen_mul_i64(tcg_passres, tcg_op1, tcg_op2);
8416                 break;
8417             case 9: /* SQDMLAL, SQDMLAL2 */
8418             case 11: /* SQDMLSL, SQDMLSL2 */
8419             case 13: /* SQDMULL, SQDMULL2 */
8420                 tcg_gen_mul_i64(tcg_passres, tcg_op1, tcg_op2);
8421                 gen_helper_neon_addl_saturate_s64(tcg_passres, cpu_env,
8422                                                   tcg_passres, tcg_passres);
8423                 break;
8424             default:
8425                 g_assert_not_reached();
8426             }
8427
8428             if (opcode == 9 || opcode == 11) {
8429                 /* saturating accumulate ops */
8430                 if (accop < 0) {
8431                     tcg_gen_neg_i64(tcg_passres, tcg_passres);
8432                 }
8433                 gen_helper_neon_addl_saturate_s64(tcg_res[pass], cpu_env,
8434                                                   tcg_res[pass], tcg_passres);
8435             } else if (accop > 0) {
8436                 tcg_gen_add_i64(tcg_res[pass], tcg_res[pass], tcg_passres);
8437             } else if (accop < 0) {
8438                 tcg_gen_sub_i64(tcg_res[pass], tcg_res[pass], tcg_passres);
8439             }
8440
8441             if (accop != 0) {
8442                 tcg_temp_free_i64(tcg_passres);
8443             }
8444
8445             tcg_temp_free_i64(tcg_op1);
8446             tcg_temp_free_i64(tcg_op2);
8447         }
8448     } else {
8449         /* size 0 or 1, generally helper functions */
8450         for (pass = 0; pass < 2; pass++) {
8451             TCGv_i32 tcg_op1 = tcg_temp_new_i32();
8452             TCGv_i32 tcg_op2 = tcg_temp_new_i32();
8453             TCGv_i64 tcg_passres;
8454             int elt = pass + is_q * 2;
8455
8456             read_vec_element_i32(s, tcg_op1, rn, elt, MO_32);
8457             read_vec_element_i32(s, tcg_op2, rm, elt, MO_32);
8458
8459             if (accop == 0) {
8460                 tcg_passres = tcg_res[pass];
8461             } else {
8462                 tcg_passres = tcg_temp_new_i64();
8463             }
8464
8465             switch (opcode) {
8466             case 0: /* SADDL, SADDL2, UADDL, UADDL2 */
8467             case 2: /* SSUBL, SSUBL2, USUBL, USUBL2 */
8468             {
8469                 TCGv_i64 tcg_op2_64 = tcg_temp_new_i64();
8470                 static NeonGenWidenFn * const widenfns[2][2] = {
8471                     { gen_helper_neon_widen_s8, gen_helper_neon_widen_u8 },
8472                     { gen_helper_neon_widen_s16, gen_helper_neon_widen_u16 },
8473                 };
8474                 NeonGenWidenFn *widenfn = widenfns[size][is_u];
8475
8476                 widenfn(tcg_op2_64, tcg_op2);
8477                 widenfn(tcg_passres, tcg_op1);
8478                 gen_neon_addl(size, (opcode == 2), tcg_passres,
8479                               tcg_passres, tcg_op2_64);
8480                 tcg_temp_free_i64(tcg_op2_64);
8481                 break;
8482             }
8483             case 5: /* SABAL, SABAL2, UABAL, UABAL2 */
8484             case 7: /* SABDL, SABDL2, UABDL, UABDL2 */
8485                 if (size == 0) {
8486                     if (is_u) {
8487                         gen_helper_neon_abdl_u16(tcg_passres, tcg_op1, tcg_op2);
8488                     } else {
8489                         gen_helper_neon_abdl_s16(tcg_passres, tcg_op1, tcg_op2);
8490                     }
8491                 } else {
8492                     if (is_u) {
8493                         gen_helper_neon_abdl_u32(tcg_passres, tcg_op1, tcg_op2);
8494                     } else {
8495                         gen_helper_neon_abdl_s32(tcg_passres, tcg_op1, tcg_op2);
8496                     }
8497                 }
8498                 break;
8499             case 8: /* SMLAL, SMLAL2, UMLAL, UMLAL2 */
8500             case 10: /* SMLSL, SMLSL2, UMLSL, UMLSL2 */
8501             case 12: /* UMULL, UMULL2, SMULL, SMULL2 */
8502                 if (size == 0) {
8503                     if (is_u) {
8504                         gen_helper_neon_mull_u8(tcg_passres, tcg_op1, tcg_op2);
8505                     } else {
8506                         gen_helper_neon_mull_s8(tcg_passres, tcg_op1, tcg_op2);
8507                     }
8508                 } else {
8509                     if (is_u) {
8510                         gen_helper_neon_mull_u16(tcg_passres, tcg_op1, tcg_op2);
8511                     } else {
8512                         gen_helper_neon_mull_s16(tcg_passres, tcg_op1, tcg_op2);
8513                     }
8514                 }
8515                 break;
8516             case 9: /* SQDMLAL, SQDMLAL2 */
8517             case 11: /* SQDMLSL, SQDMLSL2 */
8518             case 13: /* SQDMULL, SQDMULL2 */
8519                 assert(size == 1);
8520                 gen_helper_neon_mull_s16(tcg_passres, tcg_op1, tcg_op2);
8521                 gen_helper_neon_addl_saturate_s32(tcg_passres, cpu_env,
8522                                                   tcg_passres, tcg_passres);
8523                 break;
8524             case 14: /* PMULL */
8525                 assert(size == 0);
8526                 gen_helper_neon_mull_p8(tcg_passres, tcg_op1, tcg_op2);
8527                 break;
8528             default:
8529                 g_assert_not_reached();
8530             }
8531             tcg_temp_free_i32(tcg_op1);
8532             tcg_temp_free_i32(tcg_op2);
8533
8534             if (accop != 0) {
8535                 if (opcode == 9 || opcode == 11) {
8536                     /* saturating accumulate ops */
8537                     if (accop < 0) {
8538                         gen_helper_neon_negl_u32(tcg_passres, tcg_passres);
8539                     }
8540                     gen_helper_neon_addl_saturate_s32(tcg_res[pass], cpu_env,
8541                                                       tcg_res[pass],
8542                                                       tcg_passres);
8543                 } else {
8544                     gen_neon_addl(size, (accop < 0), tcg_res[pass],
8545                                   tcg_res[pass], tcg_passres);
8546                 }
8547                 tcg_temp_free_i64(tcg_passres);
8548             }
8549         }
8550     }
8551
8552     write_vec_element(s, tcg_res[0], rd, 0, MO_64);
8553     write_vec_element(s, tcg_res[1], rd, 1, MO_64);
8554     tcg_temp_free_i64(tcg_res[0]);
8555     tcg_temp_free_i64(tcg_res[1]);
8556 }
8557
8558 static void handle_3rd_wide(DisasContext *s, int is_q, int is_u, int size,
8559                             int opcode, int rd, int rn, int rm)
8560 {
8561     TCGv_i64 tcg_res[2];
8562     int part = is_q ? 2 : 0;
8563     int pass;
8564
8565     for (pass = 0; pass < 2; pass++) {
8566         TCGv_i64 tcg_op1 = tcg_temp_new_i64();
8567         TCGv_i32 tcg_op2 = tcg_temp_new_i32();
8568         TCGv_i64 tcg_op2_wide = tcg_temp_new_i64();
8569         static NeonGenWidenFn * const widenfns[3][2] = {
8570             { gen_helper_neon_widen_s8, gen_helper_neon_widen_u8 },
8571             { gen_helper_neon_widen_s16, gen_helper_neon_widen_u16 },
8572             { tcg_gen_ext_i32_i64, tcg_gen_extu_i32_i64 },
8573         };
8574         NeonGenWidenFn *widenfn = widenfns[size][is_u];
8575
8576         read_vec_element(s, tcg_op1, rn, pass, MO_64);
8577         read_vec_element_i32(s, tcg_op2, rm, part + pass, MO_32);
8578         widenfn(tcg_op2_wide, tcg_op2);
8579         tcg_temp_free_i32(tcg_op2);
8580         tcg_res[pass] = tcg_temp_new_i64();
8581         gen_neon_addl(size, (opcode == 3),
8582                       tcg_res[pass], tcg_op1, tcg_op2_wide);
8583         tcg_temp_free_i64(tcg_op1);
8584         tcg_temp_free_i64(tcg_op2_wide);
8585     }
8586
8587     for (pass = 0; pass < 2; pass++) {
8588         write_vec_element(s, tcg_res[pass], rd, pass, MO_64);
8589         tcg_temp_free_i64(tcg_res[pass]);
8590     }
8591 }
8592
8593 static void do_narrow_high_u32(TCGv_i32 res, TCGv_i64 in)
8594 {
8595     tcg_gen_shri_i64(in, in, 32);
8596     tcg_gen_trunc_i64_i32(res, in);
8597 }
8598
8599 static void do_narrow_round_high_u32(TCGv_i32 res, TCGv_i64 in)
8600 {
8601     tcg_gen_addi_i64(in, in, 1U << 31);
8602     do_narrow_high_u32(res, in);
8603 }
8604
8605 static void handle_3rd_narrowing(DisasContext *s, int is_q, int is_u, int size,
8606                                  int opcode, int rd, int rn, int rm)
8607 {
8608     TCGv_i32 tcg_res[2];
8609     int part = is_q ? 2 : 0;
8610     int pass;
8611
8612     for (pass = 0; pass < 2; pass++) {
8613         TCGv_i64 tcg_op1 = tcg_temp_new_i64();
8614         TCGv_i64 tcg_op2 = tcg_temp_new_i64();
8615         TCGv_i64 tcg_wideres = tcg_temp_new_i64();
8616         static NeonGenNarrowFn * const narrowfns[3][2] = {
8617             { gen_helper_neon_narrow_high_u8,
8618               gen_helper_neon_narrow_round_high_u8 },
8619             { gen_helper_neon_narrow_high_u16,
8620               gen_helper_neon_narrow_round_high_u16 },
8621             { do_narrow_high_u32, do_narrow_round_high_u32 },
8622         };
8623         NeonGenNarrowFn *gennarrow = narrowfns[size][is_u];
8624
8625         read_vec_element(s, tcg_op1, rn, pass, MO_64);
8626         read_vec_element(s, tcg_op2, rm, pass, MO_64);
8627
8628         gen_neon_addl(size, (opcode == 6), tcg_wideres, tcg_op1, tcg_op2);
8629
8630         tcg_temp_free_i64(tcg_op1);
8631         tcg_temp_free_i64(tcg_op2);
8632
8633         tcg_res[pass] = tcg_temp_new_i32();
8634         gennarrow(tcg_res[pass], tcg_wideres);
8635         tcg_temp_free_i64(tcg_wideres);
8636     }
8637
8638     for (pass = 0; pass < 2; pass++) {
8639         write_vec_element_i32(s, tcg_res[pass], rd, pass + part, MO_32);
8640         tcg_temp_free_i32(tcg_res[pass]);
8641     }
8642     if (!is_q) {
8643         clear_vec_high(s, rd);
8644     }
8645 }
8646
8647 static void handle_pmull_64(DisasContext *s, int is_q, int rd, int rn, int rm)
8648 {
8649     /* PMULL of 64 x 64 -> 128 is an odd special case because it
8650      * is the only three-reg-diff instruction which produces a
8651      * 128-bit wide result from a single operation. However since
8652      * it's possible to calculate the two halves more or less
8653      * separately we just use two helper calls.
8654      */
8655     TCGv_i64 tcg_op1 = tcg_temp_new_i64();
8656     TCGv_i64 tcg_op2 = tcg_temp_new_i64();
8657     TCGv_i64 tcg_res = tcg_temp_new_i64();
8658
8659     read_vec_element(s, tcg_op1, rn, is_q, MO_64);
8660     read_vec_element(s, tcg_op2, rm, is_q, MO_64);
8661     gen_helper_neon_pmull_64_lo(tcg_res, tcg_op1, tcg_op2);
8662     write_vec_element(s, tcg_res, rd, 0, MO_64);
8663     gen_helper_neon_pmull_64_hi(tcg_res, tcg_op1, tcg_op2);
8664     write_vec_element(s, tcg_res, rd, 1, MO_64);
8665
8666     tcg_temp_free_i64(tcg_op1);
8667     tcg_temp_free_i64(tcg_op2);
8668     tcg_temp_free_i64(tcg_res);
8669 }
8670
8671 /* C3.6.15 AdvSIMD three different
8672  *   31  30  29 28       24 23  22  21 20  16 15    12 11 10 9    5 4    0
8673  * +---+---+---+-----------+------+---+------+--------+-----+------+------+
8674  * | 0 | Q | U | 0 1 1 1 0 | size | 1 |  Rm  | opcode | 0 0 |  Rn  |  Rd  |
8675  * +---+---+---+-----------+------+---+------+--------+-----+------+------+
8676  */
8677 static void disas_simd_three_reg_diff(DisasContext *s, uint32_t insn)
8678 {
8679     /* Instructions in this group fall into three basic classes
8680      * (in each case with the operation working on each element in
8681      * the input vectors):
8682      * (1) widening 64 x 64 -> 128 (with possibly Vd as an extra
8683      *     128 bit input)
8684      * (2) wide 64 x 128 -> 128
8685      * (3) narrowing 128 x 128 -> 64
8686      * Here we do initial decode, catch unallocated cases and
8687      * dispatch to separate functions for each class.
8688      */
8689     int is_q = extract32(insn, 30, 1);
8690     int is_u = extract32(insn, 29, 1);
8691     int size = extract32(insn, 22, 2);
8692     int opcode = extract32(insn, 12, 4);
8693     int rm = extract32(insn, 16, 5);
8694     int rn = extract32(insn, 5, 5);
8695     int rd = extract32(insn, 0, 5);
8696
8697     switch (opcode) {
8698     case 1: /* SADDW, SADDW2, UADDW, UADDW2 */
8699     case 3: /* SSUBW, SSUBW2, USUBW, USUBW2 */
8700         /* 64 x 128 -> 128 */
8701         if (size == 3) {
8702             unallocated_encoding(s);
8703             return;
8704         }
8705         if (!fp_access_check(s)) {
8706             return;
8707         }
8708         handle_3rd_wide(s, is_q, is_u, size, opcode, rd, rn, rm);
8709         break;
8710     case 4: /* ADDHN, ADDHN2, RADDHN, RADDHN2 */
8711     case 6: /* SUBHN, SUBHN2, RSUBHN, RSUBHN2 */
8712         /* 128 x 128 -> 64 */
8713         if (size == 3) {
8714             unallocated_encoding(s);
8715             return;
8716         }
8717         if (!fp_access_check(s)) {
8718             return;
8719         }
8720         handle_3rd_narrowing(s, is_q, is_u, size, opcode, rd, rn, rm);
8721         break;
8722     case 14: /* PMULL, PMULL2 */
8723         if (is_u || size == 1 || size == 2) {
8724             unallocated_encoding(s);
8725             return;
8726         }
8727         if (size == 3) {
8728             if (!arm_dc_feature(s, ARM_FEATURE_V8_PMULL)) {
8729                 unallocated_encoding(s);
8730                 return;
8731             }
8732             if (!fp_access_check(s)) {
8733                 return;
8734             }
8735             handle_pmull_64(s, is_q, rd, rn, rm);
8736             return;
8737         }
8738         goto is_widening;
8739     case 9: /* SQDMLAL, SQDMLAL2 */
8740     case 11: /* SQDMLSL, SQDMLSL2 */
8741     case 13: /* SQDMULL, SQDMULL2 */
8742         if (is_u || size == 0) {
8743             unallocated_encoding(s);
8744             return;
8745         }
8746         /* fall through */
8747     case 0: /* SADDL, SADDL2, UADDL, UADDL2 */
8748     case 2: /* SSUBL, SSUBL2, USUBL, USUBL2 */
8749     case 5: /* SABAL, SABAL2, UABAL, UABAL2 */
8750     case 7: /* SABDL, SABDL2, UABDL, UABDL2 */
8751     case 8: /* SMLAL, SMLAL2, UMLAL, UMLAL2 */
8752     case 10: /* SMLSL, SMLSL2, UMLSL, UMLSL2 */
8753     case 12: /* SMULL, SMULL2, UMULL, UMULL2 */
8754         /* 64 x 64 -> 128 */
8755         if (size == 3) {
8756             unallocated_encoding(s);
8757             return;
8758         }
8759     is_widening:
8760         if (!fp_access_check(s)) {
8761             return;
8762         }
8763
8764         handle_3rd_widening(s, is_q, is_u, size, opcode, rd, rn, rm);
8765         break;
8766     default:
8767         /* opcode 15 not allocated */
8768         unallocated_encoding(s);
8769         break;
8770     }
8771 }
8772
8773 /* Logic op (opcode == 3) subgroup of C3.6.16. */
8774 static void disas_simd_3same_logic(DisasContext *s, uint32_t insn)
8775 {
8776     int rd = extract32(insn, 0, 5);
8777     int rn = extract32(insn, 5, 5);
8778     int rm = extract32(insn, 16, 5);
8779     int size = extract32(insn, 22, 2);
8780     bool is_u = extract32(insn, 29, 1);
8781     bool is_q = extract32(insn, 30, 1);
8782     TCGv_i64 tcg_op1, tcg_op2, tcg_res[2];
8783     int pass;
8784
8785     if (!fp_access_check(s)) {
8786         return;
8787     }
8788
8789     tcg_op1 = tcg_temp_new_i64();
8790     tcg_op2 = tcg_temp_new_i64();
8791     tcg_res[0] = tcg_temp_new_i64();
8792     tcg_res[1] = tcg_temp_new_i64();
8793
8794     for (pass = 0; pass < (is_q ? 2 : 1); pass++) {
8795         read_vec_element(s, tcg_op1, rn, pass, MO_64);
8796         read_vec_element(s, tcg_op2, rm, pass, MO_64);
8797
8798         if (!is_u) {
8799             switch (size) {
8800             case 0: /* AND */
8801                 tcg_gen_and_i64(tcg_res[pass], tcg_op1, tcg_op2);
8802                 break;
8803             case 1: /* BIC */
8804                 tcg_gen_andc_i64(tcg_res[pass], tcg_op1, tcg_op2);
8805                 break;
8806             case 2: /* ORR */
8807                 tcg_gen_or_i64(tcg_res[pass], tcg_op1, tcg_op2);
8808                 break;
8809             case 3: /* ORN */
8810                 tcg_gen_orc_i64(tcg_res[pass], tcg_op1, tcg_op2);
8811                 break;
8812             }
8813         } else {
8814             if (size != 0) {
8815                 /* B* ops need res loaded to operate on */
8816                 read_vec_element(s, tcg_res[pass], rd, pass, MO_64);
8817             }
8818
8819             switch (size) {
8820             case 0: /* EOR */
8821                 tcg_gen_xor_i64(tcg_res[pass], tcg_op1, tcg_op2);
8822                 break;
8823             case 1: /* BSL bitwise select */
8824                 tcg_gen_xor_i64(tcg_op1, tcg_op1, tcg_op2);
8825                 tcg_gen_and_i64(tcg_op1, tcg_op1, tcg_res[pass]);
8826                 tcg_gen_xor_i64(tcg_res[pass], tcg_op2, tcg_op1);
8827                 break;
8828             case 2: /* BIT, bitwise insert if true */
8829                 tcg_gen_xor_i64(tcg_op1, tcg_op1, tcg_res[pass]);
8830                 tcg_gen_and_i64(tcg_op1, tcg_op1, tcg_op2);
8831                 tcg_gen_xor_i64(tcg_res[pass], tcg_res[pass], tcg_op1);
8832                 break;
8833             case 3: /* BIF, bitwise insert if false */
8834                 tcg_gen_xor_i64(tcg_op1, tcg_op1, tcg_res[pass]);
8835                 tcg_gen_andc_i64(tcg_op1, tcg_op1, tcg_op2);
8836                 tcg_gen_xor_i64(tcg_res[pass], tcg_res[pass], tcg_op1);
8837                 break;
8838             }
8839         }
8840     }
8841
8842     write_vec_element(s, tcg_res[0], rd, 0, MO_64);
8843     if (!is_q) {
8844         tcg_gen_movi_i64(tcg_res[1], 0);
8845     }
8846     write_vec_element(s, tcg_res[1], rd, 1, MO_64);
8847
8848     tcg_temp_free_i64(tcg_op1);
8849     tcg_temp_free_i64(tcg_op2);
8850     tcg_temp_free_i64(tcg_res[0]);
8851     tcg_temp_free_i64(tcg_res[1]);
8852 }
8853
8854 /* Helper functions for 32 bit comparisons */
8855 static void gen_max_s32(TCGv_i32 res, TCGv_i32 op1, TCGv_i32 op2)
8856 {
8857     tcg_gen_movcond_i32(TCG_COND_GE, res, op1, op2, op1, op2);
8858 }
8859
8860 static void gen_max_u32(TCGv_i32 res, TCGv_i32 op1, TCGv_i32 op2)
8861 {
8862     tcg_gen_movcond_i32(TCG_COND_GEU, res, op1, op2, op1, op2);
8863 }
8864
8865 static void gen_min_s32(TCGv_i32 res, TCGv_i32 op1, TCGv_i32 op2)
8866 {
8867     tcg_gen_movcond_i32(TCG_COND_LE, res, op1, op2, op1, op2);
8868 }
8869
8870 static void gen_min_u32(TCGv_i32 res, TCGv_i32 op1, TCGv_i32 op2)
8871 {
8872     tcg_gen_movcond_i32(TCG_COND_LEU, res, op1, op2, op1, op2);
8873 }
8874
8875 /* Pairwise op subgroup of C3.6.16.
8876  *
8877  * This is called directly or via the handle_3same_float for float pairwise
8878  * operations where the opcode and size are calculated differently.
8879  */
8880 static void handle_simd_3same_pair(DisasContext *s, int is_q, int u, int opcode,
8881                                    int size, int rn, int rm, int rd)
8882 {
8883     TCGv_ptr fpst;
8884     int pass;
8885
8886     /* Floating point operations need fpst */
8887     if (opcode >= 0x58) {
8888         fpst = get_fpstatus_ptr();
8889     } else {
8890         TCGV_UNUSED_PTR(fpst);
8891     }
8892
8893     if (!fp_access_check(s)) {
8894         return;
8895     }
8896
8897     /* These operations work on the concatenated rm:rn, with each pair of
8898      * adjacent elements being operated on to produce an element in the result.
8899      */
8900     if (size == 3) {
8901         TCGv_i64 tcg_res[2];
8902
8903         for (pass = 0; pass < 2; pass++) {
8904             TCGv_i64 tcg_op1 = tcg_temp_new_i64();
8905             TCGv_i64 tcg_op2 = tcg_temp_new_i64();
8906             int passreg = (pass == 0) ? rn : rm;
8907
8908             read_vec_element(s, tcg_op1, passreg, 0, MO_64);
8909             read_vec_element(s, tcg_op2, passreg, 1, MO_64);
8910             tcg_res[pass] = tcg_temp_new_i64();
8911
8912             switch (opcode) {
8913             case 0x17: /* ADDP */
8914                 tcg_gen_add_i64(tcg_res[pass], tcg_op1, tcg_op2);
8915                 break;
8916             case 0x58: /* FMAXNMP */
8917                 gen_helper_vfp_maxnumd(tcg_res[pass], tcg_op1, tcg_op2, fpst);
8918                 break;
8919             case 0x5a: /* FADDP */
8920                 gen_helper_vfp_addd(tcg_res[pass], tcg_op1, tcg_op2, fpst);
8921                 break;
8922             case 0x5e: /* FMAXP */
8923                 gen_helper_vfp_maxd(tcg_res[pass], tcg_op1, tcg_op2, fpst);
8924                 break;
8925             case 0x78: /* FMINNMP */
8926                 gen_helper_vfp_minnumd(tcg_res[pass], tcg_op1, tcg_op2, fpst);
8927                 break;
8928             case 0x7e: /* FMINP */
8929                 gen_helper_vfp_mind(tcg_res[pass], tcg_op1, tcg_op2, fpst);
8930                 break;
8931             default:
8932                 g_assert_not_reached();
8933             }
8934
8935             tcg_temp_free_i64(tcg_op1);
8936             tcg_temp_free_i64(tcg_op2);
8937         }
8938
8939         for (pass = 0; pass < 2; pass++) {
8940             write_vec_element(s, tcg_res[pass], rd, pass, MO_64);
8941             tcg_temp_free_i64(tcg_res[pass]);
8942         }
8943     } else {
8944         int maxpass = is_q ? 4 : 2;
8945         TCGv_i32 tcg_res[4];
8946
8947         for (pass = 0; pass < maxpass; pass++) {
8948             TCGv_i32 tcg_op1 = tcg_temp_new_i32();
8949             TCGv_i32 tcg_op2 = tcg_temp_new_i32();
8950             NeonGenTwoOpFn *genfn = NULL;
8951             int passreg = pass < (maxpass / 2) ? rn : rm;
8952             int passelt = (is_q && (pass & 1)) ? 2 : 0;
8953
8954             read_vec_element_i32(s, tcg_op1, passreg, passelt, MO_32);
8955             read_vec_element_i32(s, tcg_op2, passreg, passelt + 1, MO_32);
8956             tcg_res[pass] = tcg_temp_new_i32();
8957
8958             switch (opcode) {
8959             case 0x17: /* ADDP */
8960             {
8961                 static NeonGenTwoOpFn * const fns[3] = {
8962                     gen_helper_neon_padd_u8,
8963                     gen_helper_neon_padd_u16,
8964                     tcg_gen_add_i32,
8965                 };
8966                 genfn = fns[size];
8967                 break;
8968             }
8969             case 0x14: /* SMAXP, UMAXP */
8970             {
8971                 static NeonGenTwoOpFn * const fns[3][2] = {
8972                     { gen_helper_neon_pmax_s8, gen_helper_neon_pmax_u8 },
8973                     { gen_helper_neon_pmax_s16, gen_helper_neon_pmax_u16 },
8974                     { gen_max_s32, gen_max_u32 },
8975                 };
8976                 genfn = fns[size][u];
8977                 break;
8978             }
8979             case 0x15: /* SMINP, UMINP */
8980             {
8981                 static NeonGenTwoOpFn * const fns[3][2] = {
8982                     { gen_helper_neon_pmin_s8, gen_helper_neon_pmin_u8 },
8983                     { gen_helper_neon_pmin_s16, gen_helper_neon_pmin_u16 },
8984                     { gen_min_s32, gen_min_u32 },
8985                 };
8986                 genfn = fns[size][u];
8987                 break;
8988             }
8989             /* The FP operations are all on single floats (32 bit) */
8990             case 0x58: /* FMAXNMP */
8991                 gen_helper_vfp_maxnums(tcg_res[pass], tcg_op1, tcg_op2, fpst);
8992                 break;
8993             case 0x5a: /* FADDP */
8994                 gen_helper_vfp_adds(tcg_res[pass], tcg_op1, tcg_op2, fpst);
8995                 break;
8996             case 0x5e: /* FMAXP */
8997                 gen_helper_vfp_maxs(tcg_res[pass], tcg_op1, tcg_op2, fpst);
8998                 break;
8999             case 0x78: /* FMINNMP */
9000                 gen_helper_vfp_minnums(tcg_res[pass], tcg_op1, tcg_op2, fpst);
9001                 break;
9002             case 0x7e: /* FMINP */
9003                 gen_helper_vfp_mins(tcg_res[pass], tcg_op1, tcg_op2, fpst);
9004                 break;
9005             default:
9006                 g_assert_not_reached();
9007             }
9008
9009             /* FP ops called directly, otherwise call now */
9010             if (genfn) {
9011                 genfn(tcg_res[pass], tcg_op1, tcg_op2);
9012             }
9013
9014             tcg_temp_free_i32(tcg_op1);
9015             tcg_temp_free_i32(tcg_op2);
9016         }
9017
9018         for (pass = 0; pass < maxpass; pass++) {
9019             write_vec_element_i32(s, tcg_res[pass], rd, pass, MO_32);
9020             tcg_temp_free_i32(tcg_res[pass]);
9021         }
9022         if (!is_q) {
9023             clear_vec_high(s, rd);
9024         }
9025     }
9026
9027     if (!TCGV_IS_UNUSED_PTR(fpst)) {
9028         tcg_temp_free_ptr(fpst);
9029     }
9030 }
9031
9032 /* Floating point op subgroup of C3.6.16. */
9033 static void disas_simd_3same_float(DisasContext *s, uint32_t insn)
9034 {
9035     /* For floating point ops, the U, size[1] and opcode bits
9036      * together indicate the operation. size[0] indicates single
9037      * or double.
9038      */
9039     int fpopcode = extract32(insn, 11, 5)
9040         | (extract32(insn, 23, 1) << 5)
9041         | (extract32(insn, 29, 1) << 6);
9042     int is_q = extract32(insn, 30, 1);
9043     int size = extract32(insn, 22, 1);
9044     int rm = extract32(insn, 16, 5);
9045     int rn = extract32(insn, 5, 5);
9046     int rd = extract32(insn, 0, 5);
9047
9048     int datasize = is_q ? 128 : 64;
9049     int esize = 32 << size;
9050     int elements = datasize / esize;
9051
9052     if (size == 1 && !is_q) {
9053         unallocated_encoding(s);
9054         return;
9055     }
9056
9057     switch (fpopcode) {
9058     case 0x58: /* FMAXNMP */
9059     case 0x5a: /* FADDP */
9060     case 0x5e: /* FMAXP */
9061     case 0x78: /* FMINNMP */
9062     case 0x7e: /* FMINP */
9063         if (size && !is_q) {
9064             unallocated_encoding(s);
9065             return;
9066         }
9067         handle_simd_3same_pair(s, is_q, 0, fpopcode, size ? MO_64 : MO_32,
9068                                rn, rm, rd);
9069         return;
9070     case 0x1b: /* FMULX */
9071     case 0x1f: /* FRECPS */
9072     case 0x3f: /* FRSQRTS */
9073     case 0x5d: /* FACGE */
9074     case 0x7d: /* FACGT */
9075     case 0x19: /* FMLA */
9076     case 0x39: /* FMLS */
9077     case 0x18: /* FMAXNM */
9078     case 0x1a: /* FADD */
9079     case 0x1c: /* FCMEQ */
9080     case 0x1e: /* FMAX */
9081     case 0x38: /* FMINNM */
9082     case 0x3a: /* FSUB */
9083     case 0x3e: /* FMIN */
9084     case 0x5b: /* FMUL */
9085     case 0x5c: /* FCMGE */
9086     case 0x5f: /* FDIV */
9087     case 0x7a: /* FABD */
9088     case 0x7c: /* FCMGT */
9089         if (!fp_access_check(s)) {
9090             return;
9091         }
9092
9093         handle_3same_float(s, size, elements, fpopcode, rd, rn, rm);
9094         return;
9095     default:
9096         unallocated_encoding(s);
9097         return;
9098     }
9099 }
9100
9101 /* Integer op subgroup of C3.6.16. */
9102 static void disas_simd_3same_int(DisasContext *s, uint32_t insn)
9103 {
9104     int is_q = extract32(insn, 30, 1);
9105     int u = extract32(insn, 29, 1);
9106     int size = extract32(insn, 22, 2);
9107     int opcode = extract32(insn, 11, 5);
9108     int rm = extract32(insn, 16, 5);
9109     int rn = extract32(insn, 5, 5);
9110     int rd = extract32(insn, 0, 5);
9111     int pass;
9112
9113     switch (opcode) {
9114     case 0x13: /* MUL, PMUL */
9115         if (u && size != 0) {
9116             unallocated_encoding(s);
9117             return;
9118         }
9119         /* fall through */
9120     case 0x0: /* SHADD, UHADD */
9121     case 0x2: /* SRHADD, URHADD */
9122     case 0x4: /* SHSUB, UHSUB */
9123     case 0xc: /* SMAX, UMAX */
9124     case 0xd: /* SMIN, UMIN */
9125     case 0xe: /* SABD, UABD */
9126     case 0xf: /* SABA, UABA */
9127     case 0x12: /* MLA, MLS */
9128         if (size == 3) {
9129             unallocated_encoding(s);
9130             return;
9131         }
9132         break;
9133     case 0x16: /* SQDMULH, SQRDMULH */
9134         if (size == 0 || size == 3) {
9135             unallocated_encoding(s);
9136             return;
9137         }
9138         break;
9139     default:
9140         if (size == 3 && !is_q) {
9141             unallocated_encoding(s);
9142             return;
9143         }
9144         break;
9145     }
9146
9147     if (!fp_access_check(s)) {
9148         return;
9149     }
9150
9151     if (size == 3) {
9152         assert(is_q);
9153         for (pass = 0; pass < 2; pass++) {
9154             TCGv_i64 tcg_op1 = tcg_temp_new_i64();
9155             TCGv_i64 tcg_op2 = tcg_temp_new_i64();
9156             TCGv_i64 tcg_res = tcg_temp_new_i64();
9157
9158             read_vec_element(s, tcg_op1, rn, pass, MO_64);
9159             read_vec_element(s, tcg_op2, rm, pass, MO_64);
9160
9161             handle_3same_64(s, opcode, u, tcg_res, tcg_op1, tcg_op2);
9162
9163             write_vec_element(s, tcg_res, rd, pass, MO_64);
9164
9165             tcg_temp_free_i64(tcg_res);
9166             tcg_temp_free_i64(tcg_op1);
9167             tcg_temp_free_i64(tcg_op2);
9168         }
9169     } else {
9170         for (pass = 0; pass < (is_q ? 4 : 2); pass++) {
9171             TCGv_i32 tcg_op1 = tcg_temp_new_i32();
9172             TCGv_i32 tcg_op2 = tcg_temp_new_i32();
9173             TCGv_i32 tcg_res = tcg_temp_new_i32();
9174             NeonGenTwoOpFn *genfn = NULL;
9175             NeonGenTwoOpEnvFn *genenvfn = NULL;
9176
9177             read_vec_element_i32(s, tcg_op1, rn, pass, MO_32);
9178             read_vec_element_i32(s, tcg_op2, rm, pass, MO_32);
9179
9180             switch (opcode) {
9181             case 0x0: /* SHADD, UHADD */
9182             {
9183                 static NeonGenTwoOpFn * const fns[3][2] = {
9184                     { gen_helper_neon_hadd_s8, gen_helper_neon_hadd_u8 },
9185                     { gen_helper_neon_hadd_s16, gen_helper_neon_hadd_u16 },
9186                     { gen_helper_neon_hadd_s32, gen_helper_neon_hadd_u32 },
9187                 };
9188                 genfn = fns[size][u];
9189                 break;
9190             }
9191             case 0x1: /* SQADD, UQADD */
9192             {
9193                 static NeonGenTwoOpEnvFn * const fns[3][2] = {
9194                     { gen_helper_neon_qadd_s8, gen_helper_neon_qadd_u8 },
9195                     { gen_helper_neon_qadd_s16, gen_helper_neon_qadd_u16 },
9196                     { gen_helper_neon_qadd_s32, gen_helper_neon_qadd_u32 },
9197                 };
9198                 genenvfn = fns[size][u];
9199                 break;
9200             }
9201             case 0x2: /* SRHADD, URHADD */
9202             {
9203                 static NeonGenTwoOpFn * const fns[3][2] = {
9204                     { gen_helper_neon_rhadd_s8, gen_helper_neon_rhadd_u8 },
9205                     { gen_helper_neon_rhadd_s16, gen_helper_neon_rhadd_u16 },
9206                     { gen_helper_neon_rhadd_s32, gen_helper_neon_rhadd_u32 },
9207                 };
9208                 genfn = fns[size][u];
9209                 break;
9210             }
9211             case 0x4: /* SHSUB, UHSUB */
9212             {
9213                 static NeonGenTwoOpFn * const fns[3][2] = {
9214                     { gen_helper_neon_hsub_s8, gen_helper_neon_hsub_u8 },
9215                     { gen_helper_neon_hsub_s16, gen_helper_neon_hsub_u16 },
9216                     { gen_helper_neon_hsub_s32, gen_helper_neon_hsub_u32 },
9217                 };
9218                 genfn = fns[size][u];
9219                 break;
9220             }
9221             case 0x5: /* SQSUB, UQSUB */
9222             {
9223                 static NeonGenTwoOpEnvFn * const fns[3][2] = {
9224                     { gen_helper_neon_qsub_s8, gen_helper_neon_qsub_u8 },
9225                     { gen_helper_neon_qsub_s16, gen_helper_neon_qsub_u16 },
9226                     { gen_helper_neon_qsub_s32, gen_helper_neon_qsub_u32 },
9227                 };
9228                 genenvfn = fns[size][u];
9229                 break;
9230             }
9231             case 0x6: /* CMGT, CMHI */
9232             {
9233                 static NeonGenTwoOpFn * const fns[3][2] = {
9234                     { gen_helper_neon_cgt_s8, gen_helper_neon_cgt_u8 },
9235                     { gen_helper_neon_cgt_s16, gen_helper_neon_cgt_u16 },
9236                     { gen_helper_neon_cgt_s32, gen_helper_neon_cgt_u32 },
9237                 };
9238                 genfn = fns[size][u];
9239                 break;
9240             }
9241             case 0x7: /* CMGE, CMHS */
9242             {
9243                 static NeonGenTwoOpFn * const fns[3][2] = {
9244                     { gen_helper_neon_cge_s8, gen_helper_neon_cge_u8 },
9245                     { gen_helper_neon_cge_s16, gen_helper_neon_cge_u16 },
9246                     { gen_helper_neon_cge_s32, gen_helper_neon_cge_u32 },
9247                 };
9248                 genfn = fns[size][u];
9249                 break;
9250             }
9251             case 0x8: /* SSHL, USHL */
9252             {
9253                 static NeonGenTwoOpFn * const fns[3][2] = {
9254                     { gen_helper_neon_shl_s8, gen_helper_neon_shl_u8 },
9255                     { gen_helper_neon_shl_s16, gen_helper_neon_shl_u16 },
9256                     { gen_helper_neon_shl_s32, gen_helper_neon_shl_u32 },
9257                 };
9258                 genfn = fns[size][u];
9259                 break;
9260             }
9261             case 0x9: /* SQSHL, UQSHL */
9262             {
9263                 static NeonGenTwoOpEnvFn * const fns[3][2] = {
9264                     { gen_helper_neon_qshl_s8, gen_helper_neon_qshl_u8 },
9265                     { gen_helper_neon_qshl_s16, gen_helper_neon_qshl_u16 },
9266                     { gen_helper_neon_qshl_s32, gen_helper_neon_qshl_u32 },
9267                 };
9268                 genenvfn = fns[size][u];
9269                 break;
9270             }
9271             case 0xa: /* SRSHL, URSHL */
9272             {
9273                 static NeonGenTwoOpFn * const fns[3][2] = {
9274                     { gen_helper_neon_rshl_s8, gen_helper_neon_rshl_u8 },
9275                     { gen_helper_neon_rshl_s16, gen_helper_neon_rshl_u16 },
9276                     { gen_helper_neon_rshl_s32, gen_helper_neon_rshl_u32 },
9277                 };
9278                 genfn = fns[size][u];
9279                 break;
9280             }
9281             case 0xb: /* SQRSHL, UQRSHL */
9282             {
9283                 static NeonGenTwoOpEnvFn * const fns[3][2] = {
9284                     { gen_helper_neon_qrshl_s8, gen_helper_neon_qrshl_u8 },
9285                     { gen_helper_neon_qrshl_s16, gen_helper_neon_qrshl_u16 },
9286                     { gen_helper_neon_qrshl_s32, gen_helper_neon_qrshl_u32 },
9287                 };
9288                 genenvfn = fns[size][u];
9289                 break;
9290             }
9291             case 0xc: /* SMAX, UMAX */
9292             {
9293                 static NeonGenTwoOpFn * const fns[3][2] = {
9294                     { gen_helper_neon_max_s8, gen_helper_neon_max_u8 },
9295                     { gen_helper_neon_max_s16, gen_helper_neon_max_u16 },
9296                     { gen_max_s32, gen_max_u32 },
9297                 };
9298                 genfn = fns[size][u];
9299                 break;
9300             }
9301
9302             case 0xd: /* SMIN, UMIN */
9303             {
9304                 static NeonGenTwoOpFn * const fns[3][2] = {
9305                     { gen_helper_neon_min_s8, gen_helper_neon_min_u8 },
9306                     { gen_helper_neon_min_s16, gen_helper_neon_min_u16 },
9307                     { gen_min_s32, gen_min_u32 },
9308                 };
9309                 genfn = fns[size][u];
9310                 break;
9311             }
9312             case 0xe: /* SABD, UABD */
9313             case 0xf: /* SABA, UABA */
9314             {
9315                 static NeonGenTwoOpFn * const fns[3][2] = {
9316                     { gen_helper_neon_abd_s8, gen_helper_neon_abd_u8 },
9317                     { gen_helper_neon_abd_s16, gen_helper_neon_abd_u16 },
9318                     { gen_helper_neon_abd_s32, gen_helper_neon_abd_u32 },
9319                 };
9320                 genfn = fns[size][u];
9321                 break;
9322             }
9323             case 0x10: /* ADD, SUB */
9324             {
9325                 static NeonGenTwoOpFn * const fns[3][2] = {
9326                     { gen_helper_neon_add_u8, gen_helper_neon_sub_u8 },
9327                     { gen_helper_neon_add_u16, gen_helper_neon_sub_u16 },
9328                     { tcg_gen_add_i32, tcg_gen_sub_i32 },
9329                 };
9330                 genfn = fns[size][u];
9331                 break;
9332             }
9333             case 0x11: /* CMTST, CMEQ */
9334             {
9335                 static NeonGenTwoOpFn * const fns[3][2] = {
9336                     { gen_helper_neon_tst_u8, gen_helper_neon_ceq_u8 },
9337                     { gen_helper_neon_tst_u16, gen_helper_neon_ceq_u16 },
9338                     { gen_helper_neon_tst_u32, gen_helper_neon_ceq_u32 },
9339                 };
9340                 genfn = fns[size][u];
9341                 break;
9342             }
9343             case 0x13: /* MUL, PMUL */
9344                 if (u) {
9345                     /* PMUL */
9346                     assert(size == 0);
9347                     genfn = gen_helper_neon_mul_p8;
9348                     break;
9349                 }
9350                 /* fall through : MUL */
9351             case 0x12: /* MLA, MLS */
9352             {
9353                 static NeonGenTwoOpFn * const fns[3] = {
9354                     gen_helper_neon_mul_u8,
9355                     gen_helper_neon_mul_u16,
9356                     tcg_gen_mul_i32,
9357                 };
9358                 genfn = fns[size];
9359                 break;
9360             }
9361             case 0x16: /* SQDMULH, SQRDMULH */
9362             {
9363                 static NeonGenTwoOpEnvFn * const fns[2][2] = {
9364                     { gen_helper_neon_qdmulh_s16, gen_helper_neon_qrdmulh_s16 },
9365                     { gen_helper_neon_qdmulh_s32, gen_helper_neon_qrdmulh_s32 },
9366                 };
9367                 assert(size == 1 || size == 2);
9368                 genenvfn = fns[size - 1][u];
9369                 break;
9370             }
9371             default:
9372                 g_assert_not_reached();
9373             }
9374
9375             if (genenvfn) {
9376                 genenvfn(tcg_res, cpu_env, tcg_op1, tcg_op2);
9377             } else {
9378                 genfn(tcg_res, tcg_op1, tcg_op2);
9379             }
9380
9381             if (opcode == 0xf || opcode == 0x12) {
9382                 /* SABA, UABA, MLA, MLS: accumulating ops */
9383                 static NeonGenTwoOpFn * const fns[3][2] = {
9384                     { gen_helper_neon_add_u8, gen_helper_neon_sub_u8 },
9385                     { gen_helper_neon_add_u16, gen_helper_neon_sub_u16 },
9386                     { tcg_gen_add_i32, tcg_gen_sub_i32 },
9387                 };
9388                 bool is_sub = (opcode == 0x12 && u); /* MLS */
9389
9390                 genfn = fns[size][is_sub];
9391                 read_vec_element_i32(s, tcg_op1, rd, pass, MO_32);
9392                 genfn(tcg_res, tcg_op1, tcg_res);
9393             }
9394
9395             write_vec_element_i32(s, tcg_res, rd, pass, MO_32);
9396
9397             tcg_temp_free_i32(tcg_res);
9398             tcg_temp_free_i32(tcg_op1);
9399             tcg_temp_free_i32(tcg_op2);
9400         }
9401     }
9402
9403     if (!is_q) {
9404         clear_vec_high(s, rd);
9405     }
9406 }
9407
9408 /* C3.6.16 AdvSIMD three same
9409  *  31  30  29  28       24 23  22  21 20  16 15    11  10 9    5 4    0
9410  * +---+---+---+-----------+------+---+------+--------+---+------+------+
9411  * | 0 | Q | U | 0 1 1 1 0 | size | 1 |  Rm  | opcode | 1 |  Rn  |  Rd  |
9412  * +---+---+---+-----------+------+---+------+--------+---+------+------+
9413  */
9414 static void disas_simd_three_reg_same(DisasContext *s, uint32_t insn)
9415 {
9416     int opcode = extract32(insn, 11, 5);
9417
9418     switch (opcode) {
9419     case 0x3: /* logic ops */
9420         disas_simd_3same_logic(s, insn);
9421         break;
9422     case 0x17: /* ADDP */
9423     case 0x14: /* SMAXP, UMAXP */
9424     case 0x15: /* SMINP, UMINP */
9425     {
9426         /* Pairwise operations */
9427         int is_q = extract32(insn, 30, 1);
9428         int u = extract32(insn, 29, 1);
9429         int size = extract32(insn, 22, 2);
9430         int rm = extract32(insn, 16, 5);
9431         int rn = extract32(insn, 5, 5);
9432         int rd = extract32(insn, 0, 5);
9433         if (opcode == 0x17) {
9434             if (u || (size == 3 && !is_q)) {
9435                 unallocated_encoding(s);
9436                 return;
9437             }
9438         } else {
9439             if (size == 3) {
9440                 unallocated_encoding(s);
9441                 return;
9442             }
9443         }
9444         handle_simd_3same_pair(s, is_q, u, opcode, size, rn, rm, rd);
9445         break;
9446     }
9447     case 0x18 ... 0x31:
9448         /* floating point ops, sz[1] and U are part of opcode */
9449         disas_simd_3same_float(s, insn);
9450         break;
9451     default:
9452         disas_simd_3same_int(s, insn);
9453         break;
9454     }
9455 }
9456
9457 static void handle_2misc_widening(DisasContext *s, int opcode, bool is_q,
9458                                   int size, int rn, int rd)
9459 {
9460     /* Handle 2-reg-misc ops which are widening (so each size element
9461      * in the source becomes a 2*size element in the destination.
9462      * The only instruction like this is FCVTL.
9463      */
9464     int pass;
9465
9466     if (size == 3) {
9467         /* 32 -> 64 bit fp conversion */
9468         TCGv_i64 tcg_res[2];
9469         int srcelt = is_q ? 2 : 0;
9470
9471         for (pass = 0; pass < 2; pass++) {
9472             TCGv_i32 tcg_op = tcg_temp_new_i32();
9473             tcg_res[pass] = tcg_temp_new_i64();
9474
9475             read_vec_element_i32(s, tcg_op, rn, srcelt + pass, MO_32);
9476             gen_helper_vfp_fcvtds(tcg_res[pass], tcg_op, cpu_env);
9477             tcg_temp_free_i32(tcg_op);
9478         }
9479         for (pass = 0; pass < 2; pass++) {
9480             write_vec_element(s, tcg_res[pass], rd, pass, MO_64);
9481             tcg_temp_free_i64(tcg_res[pass]);
9482         }
9483     } else {
9484         /* 16 -> 32 bit fp conversion */
9485         int srcelt = is_q ? 4 : 0;
9486         TCGv_i32 tcg_res[4];
9487
9488         for (pass = 0; pass < 4; pass++) {
9489             tcg_res[pass] = tcg_temp_new_i32();
9490
9491             read_vec_element_i32(s, tcg_res[pass], rn, srcelt + pass, MO_16);
9492             gen_helper_vfp_fcvt_f16_to_f32(tcg_res[pass], tcg_res[pass],
9493                                            cpu_env);
9494         }
9495         for (pass = 0; pass < 4; pass++) {
9496             write_vec_element_i32(s, tcg_res[pass], rd, pass, MO_32);
9497             tcg_temp_free_i32(tcg_res[pass]);
9498         }
9499     }
9500 }
9501
9502 static void handle_rev(DisasContext *s, int opcode, bool u,
9503                        bool is_q, int size, int rn, int rd)
9504 {
9505     int op = (opcode << 1) | u;
9506     int opsz = op + size;
9507     int grp_size = 3 - opsz;
9508     int dsize = is_q ? 128 : 64;
9509     int i;
9510
9511     if (opsz >= 3) {
9512         unallocated_encoding(s);
9513         return;
9514     }
9515
9516     if (!fp_access_check(s)) {
9517         return;
9518     }
9519
9520     if (size == 0) {
9521         /* Special case bytes, use bswap op on each group of elements */
9522         int groups = dsize / (8 << grp_size);
9523
9524         for (i = 0; i < groups; i++) {
9525             TCGv_i64 tcg_tmp = tcg_temp_new_i64();
9526
9527             read_vec_element(s, tcg_tmp, rn, i, grp_size);
9528             switch (grp_size) {
9529             case MO_16:
9530                 tcg_gen_bswap16_i64(tcg_tmp, tcg_tmp);
9531                 break;
9532             case MO_32:
9533                 tcg_gen_bswap32_i64(tcg_tmp, tcg_tmp);
9534                 break;
9535             case MO_64:
9536                 tcg_gen_bswap64_i64(tcg_tmp, tcg_tmp);
9537                 break;
9538             default:
9539                 g_assert_not_reached();
9540             }
9541             write_vec_element(s, tcg_tmp, rd, i, grp_size);
9542             tcg_temp_free_i64(tcg_tmp);
9543         }
9544         if (!is_q) {
9545             clear_vec_high(s, rd);
9546         }
9547     } else {
9548         int revmask = (1 << grp_size) - 1;
9549         int esize = 8 << size;
9550         int elements = dsize / esize;
9551         TCGv_i64 tcg_rn = tcg_temp_new_i64();
9552         TCGv_i64 tcg_rd = tcg_const_i64(0);
9553         TCGv_i64 tcg_rd_hi = tcg_const_i64(0);
9554
9555         for (i = 0; i < elements; i++) {
9556             int e_rev = (i & 0xf) ^ revmask;
9557             int off = e_rev * esize;
9558             read_vec_element(s, tcg_rn, rn, i, size);
9559             if (off >= 64) {
9560                 tcg_gen_deposit_i64(tcg_rd_hi, tcg_rd_hi,
9561                                     tcg_rn, off - 64, esize);
9562             } else {
9563                 tcg_gen_deposit_i64(tcg_rd, tcg_rd, tcg_rn, off, esize);
9564             }
9565         }
9566         write_vec_element(s, tcg_rd, rd, 0, MO_64);
9567         write_vec_element(s, tcg_rd_hi, rd, 1, MO_64);
9568
9569         tcg_temp_free_i64(tcg_rd_hi);
9570         tcg_temp_free_i64(tcg_rd);
9571         tcg_temp_free_i64(tcg_rn);
9572     }
9573 }
9574
9575 static void handle_2misc_pairwise(DisasContext *s, int opcode, bool u,
9576                                   bool is_q, int size, int rn, int rd)
9577 {
9578     /* Implement the pairwise operations from 2-misc:
9579      * SADDLP, UADDLP, SADALP, UADALP.
9580      * These all add pairs of elements in the input to produce a
9581      * double-width result element in the output (possibly accumulating).
9582      */
9583     bool accum = (opcode == 0x6);
9584     int maxpass = is_q ? 2 : 1;
9585     int pass;
9586     TCGv_i64 tcg_res[2];
9587
9588     if (size == 2) {
9589         /* 32 + 32 -> 64 op */
9590         TCGMemOp memop = size + (u ? 0 : MO_SIGN);
9591
9592         for (pass = 0; pass < maxpass; pass++) {
9593             TCGv_i64 tcg_op1 = tcg_temp_new_i64();
9594             TCGv_i64 tcg_op2 = tcg_temp_new_i64();
9595
9596             tcg_res[pass] = tcg_temp_new_i64();
9597
9598             read_vec_element(s, tcg_op1, rn, pass * 2, memop);
9599             read_vec_element(s, tcg_op2, rn, pass * 2 + 1, memop);
9600             tcg_gen_add_i64(tcg_res[pass], tcg_op1, tcg_op2);
9601             if (accum) {
9602                 read_vec_element(s, tcg_op1, rd, pass, MO_64);
9603                 tcg_gen_add_i64(tcg_res[pass], tcg_res[pass], tcg_op1);
9604             }
9605
9606             tcg_temp_free_i64(tcg_op1);
9607             tcg_temp_free_i64(tcg_op2);
9608         }
9609     } else {
9610         for (pass = 0; pass < maxpass; pass++) {
9611             TCGv_i64 tcg_op = tcg_temp_new_i64();
9612             NeonGenOneOpFn *genfn;
9613             static NeonGenOneOpFn * const fns[2][2] = {
9614                 { gen_helper_neon_addlp_s8,  gen_helper_neon_addlp_u8 },
9615                 { gen_helper_neon_addlp_s16,  gen_helper_neon_addlp_u16 },
9616             };
9617
9618             genfn = fns[size][u];
9619
9620             tcg_res[pass] = tcg_temp_new_i64();
9621
9622             read_vec_element(s, tcg_op, rn, pass, MO_64);
9623             genfn(tcg_res[pass], tcg_op);
9624
9625             if (accum) {
9626                 read_vec_element(s, tcg_op, rd, pass, MO_64);
9627                 if (size == 0) {
9628                     gen_helper_neon_addl_u16(tcg_res[pass],
9629                                              tcg_res[pass], tcg_op);
9630                 } else {
9631                     gen_helper_neon_addl_u32(tcg_res[pass],
9632                                              tcg_res[pass], tcg_op);
9633                 }
9634             }
9635             tcg_temp_free_i64(tcg_op);
9636         }
9637     }
9638     if (!is_q) {
9639         tcg_res[1] = tcg_const_i64(0);
9640     }
9641     for (pass = 0; pass < 2; pass++) {
9642         write_vec_element(s, tcg_res[pass], rd, pass, MO_64);
9643         tcg_temp_free_i64(tcg_res[pass]);
9644     }
9645 }
9646
9647 static void handle_shll(DisasContext *s, bool is_q, int size, int rn, int rd)
9648 {
9649     /* Implement SHLL and SHLL2 */
9650     int pass;
9651     int part = is_q ? 2 : 0;
9652     TCGv_i64 tcg_res[2];
9653
9654     for (pass = 0; pass < 2; pass++) {
9655         static NeonGenWidenFn * const widenfns[3] = {
9656             gen_helper_neon_widen_u8,
9657             gen_helper_neon_widen_u16,
9658             tcg_gen_extu_i32_i64,
9659         };
9660         NeonGenWidenFn *widenfn = widenfns[size];
9661         TCGv_i32 tcg_op = tcg_temp_new_i32();
9662
9663         read_vec_element_i32(s, tcg_op, rn, part + pass, MO_32);
9664         tcg_res[pass] = tcg_temp_new_i64();
9665         widenfn(tcg_res[pass], tcg_op);
9666         tcg_gen_shli_i64(tcg_res[pass], tcg_res[pass], 8 << size);
9667
9668         tcg_temp_free_i32(tcg_op);
9669     }
9670
9671     for (pass = 0; pass < 2; pass++) {
9672         write_vec_element(s, tcg_res[pass], rd, pass, MO_64);
9673         tcg_temp_free_i64(tcg_res[pass]);
9674     }
9675 }
9676
9677 /* C3.6.17 AdvSIMD two reg misc
9678  *   31  30  29 28       24 23  22 21       17 16    12 11 10 9    5 4    0
9679  * +---+---+---+-----------+------+-----------+--------+-----+------+------+
9680  * | 0 | Q | U | 0 1 1 1 0 | size | 1 0 0 0 0 | opcode | 1 0 |  Rn  |  Rd  |
9681  * +---+---+---+-----------+------+-----------+--------+-----+------+------+
9682  */
9683 static void disas_simd_two_reg_misc(DisasContext *s, uint32_t insn)
9684 {
9685     int size = extract32(insn, 22, 2);
9686     int opcode = extract32(insn, 12, 5);
9687     bool u = extract32(insn, 29, 1);
9688     bool is_q = extract32(insn, 30, 1);
9689     int rn = extract32(insn, 5, 5);
9690     int rd = extract32(insn, 0, 5);
9691     bool need_fpstatus = false;
9692     bool need_rmode = false;
9693     int rmode = -1;
9694     TCGv_i32 tcg_rmode;
9695     TCGv_ptr tcg_fpstatus;
9696
9697     switch (opcode) {
9698     case 0x0: /* REV64, REV32 */
9699     case 0x1: /* REV16 */
9700         handle_rev(s, opcode, u, is_q, size, rn, rd);
9701         return;
9702     case 0x5: /* CNT, NOT, RBIT */
9703         if (u && size == 0) {
9704             /* NOT: adjust size so we can use the 64-bits-at-a-time loop. */
9705             size = 3;
9706             break;
9707         } else if (u && size == 1) {
9708             /* RBIT */
9709             break;
9710         } else if (!u && size == 0) {
9711             /* CNT */
9712             break;
9713         }
9714         unallocated_encoding(s);
9715         return;
9716     case 0x12: /* XTN, XTN2, SQXTUN, SQXTUN2 */
9717     case 0x14: /* SQXTN, SQXTN2, UQXTN, UQXTN2 */
9718         if (size == 3) {
9719             unallocated_encoding(s);
9720             return;
9721         }
9722         if (!fp_access_check(s)) {
9723             return;
9724         }
9725
9726         handle_2misc_narrow(s, false, opcode, u, is_q, size, rn, rd);
9727         return;
9728     case 0x4: /* CLS, CLZ */
9729         if (size == 3) {
9730             unallocated_encoding(s);
9731             return;
9732         }
9733         break;
9734     case 0x2: /* SADDLP, UADDLP */
9735     case 0x6: /* SADALP, UADALP */
9736         if (size == 3) {
9737             unallocated_encoding(s);
9738             return;
9739         }
9740         if (!fp_access_check(s)) {
9741             return;
9742         }
9743         handle_2misc_pairwise(s, opcode, u, is_q, size, rn, rd);
9744         return;
9745     case 0x13: /* SHLL, SHLL2 */
9746         if (u == 0 || size == 3) {
9747             unallocated_encoding(s);
9748             return;
9749         }
9750         if (!fp_access_check(s)) {
9751             return;
9752         }
9753         handle_shll(s, is_q, size, rn, rd);
9754         return;
9755     case 0xa: /* CMLT */
9756         if (u == 1) {
9757             unallocated_encoding(s);
9758             return;
9759         }
9760         /* fall through */
9761     case 0x8: /* CMGT, CMGE */
9762     case 0x9: /* CMEQ, CMLE */
9763     case 0xb: /* ABS, NEG */
9764         if (size == 3 && !is_q) {
9765             unallocated_encoding(s);
9766             return;
9767         }
9768         break;
9769     case 0x3: /* SUQADD, USQADD */
9770         if (size == 3 && !is_q) {
9771             unallocated_encoding(s);
9772             return;
9773         }
9774         if (!fp_access_check(s)) {
9775             return;
9776         }
9777         handle_2misc_satacc(s, false, u, is_q, size, rn, rd);
9778         return;
9779     case 0x7: /* SQABS, SQNEG */
9780         if (size == 3 && !is_q) {
9781             unallocated_encoding(s);
9782             return;
9783         }
9784         break;
9785     case 0xc ... 0xf:
9786     case 0x16 ... 0x1d:
9787     case 0x1f:
9788     {
9789         /* Floating point: U, size[1] and opcode indicate operation;
9790          * size[0] indicates single or double precision.
9791          */
9792         int is_double = extract32(size, 0, 1);
9793         opcode |= (extract32(size, 1, 1) << 5) | (u << 6);
9794         size = is_double ? 3 : 2;
9795         switch (opcode) {
9796         case 0x2f: /* FABS */
9797         case 0x6f: /* FNEG */
9798             if (size == 3 && !is_q) {
9799                 unallocated_encoding(s);
9800                 return;
9801             }
9802             break;
9803         case 0x1d: /* SCVTF */
9804         case 0x5d: /* UCVTF */
9805         {
9806             bool is_signed = (opcode == 0x1d) ? true : false;
9807             int elements = is_double ? 2 : is_q ? 4 : 2;
9808             if (is_double && !is_q) {
9809                 unallocated_encoding(s);
9810                 return;
9811             }
9812             if (!fp_access_check(s)) {
9813                 return;
9814             }
9815             handle_simd_intfp_conv(s, rd, rn, elements, is_signed, 0, size);
9816             return;
9817         }
9818         case 0x2c: /* FCMGT (zero) */
9819         case 0x2d: /* FCMEQ (zero) */
9820         case 0x2e: /* FCMLT (zero) */
9821         case 0x6c: /* FCMGE (zero) */
9822         case 0x6d: /* FCMLE (zero) */
9823             if (size == 3 && !is_q) {
9824                 unallocated_encoding(s);
9825                 return;
9826             }
9827             handle_2misc_fcmp_zero(s, opcode, false, u, is_q, size, rn, rd);
9828             return;
9829         case 0x7f: /* FSQRT */
9830             if (size == 3 && !is_q) {
9831                 unallocated_encoding(s);
9832                 return;
9833             }
9834             break;
9835         case 0x1a: /* FCVTNS */
9836         case 0x1b: /* FCVTMS */
9837         case 0x3a: /* FCVTPS */
9838         case 0x3b: /* FCVTZS */
9839         case 0x5a: /* FCVTNU */
9840         case 0x5b: /* FCVTMU */
9841         case 0x7a: /* FCVTPU */
9842         case 0x7b: /* FCVTZU */
9843             need_fpstatus = true;
9844             need_rmode = true;
9845             rmode = extract32(opcode, 5, 1) | (extract32(opcode, 0, 1) << 1);
9846             if (size == 3 && !is_q) {
9847                 unallocated_encoding(s);
9848                 return;
9849             }
9850             break;
9851         case 0x5c: /* FCVTAU */
9852         case 0x1c: /* FCVTAS */
9853             need_fpstatus = true;
9854             need_rmode = true;
9855             rmode = FPROUNDING_TIEAWAY;
9856             if (size == 3 && !is_q) {
9857                 unallocated_encoding(s);
9858                 return;
9859             }
9860             break;
9861         case 0x3c: /* URECPE */
9862             if (size == 3) {
9863                 unallocated_encoding(s);
9864                 return;
9865             }
9866             /* fall through */
9867         case 0x3d: /* FRECPE */
9868         case 0x7d: /* FRSQRTE */
9869             if (size == 3 && !is_q) {
9870                 unallocated_encoding(s);
9871                 return;
9872             }
9873             if (!fp_access_check(s)) {
9874                 return;
9875             }
9876             handle_2misc_reciprocal(s, opcode, false, u, is_q, size, rn, rd);
9877             return;
9878         case 0x56: /* FCVTXN, FCVTXN2 */
9879             if (size == 2) {
9880                 unallocated_encoding(s);
9881                 return;
9882             }
9883             /* fall through */
9884         case 0x16: /* FCVTN, FCVTN2 */
9885             /* handle_2misc_narrow does a 2*size -> size operation, but these
9886              * instructions encode the source size rather than dest size.
9887              */
9888             if (!fp_access_check(s)) {
9889                 return;
9890             }
9891             handle_2misc_narrow(s, false, opcode, 0, is_q, size - 1, rn, rd);
9892             return;
9893         case 0x17: /* FCVTL, FCVTL2 */
9894             if (!fp_access_check(s)) {
9895                 return;
9896             }
9897             handle_2misc_widening(s, opcode, is_q, size, rn, rd);
9898             return;
9899         case 0x18: /* FRINTN */
9900         case 0x19: /* FRINTM */
9901         case 0x38: /* FRINTP */
9902         case 0x39: /* FRINTZ */
9903             need_rmode = true;
9904             rmode = extract32(opcode, 5, 1) | (extract32(opcode, 0, 1) << 1);
9905             /* fall through */
9906         case 0x59: /* FRINTX */
9907         case 0x79: /* FRINTI */
9908             need_fpstatus = true;
9909             if (size == 3 && !is_q) {
9910                 unallocated_encoding(s);
9911                 return;
9912             }
9913             break;
9914         case 0x58: /* FRINTA */
9915             need_rmode = true;
9916             rmode = FPROUNDING_TIEAWAY;
9917             need_fpstatus = true;
9918             if (size == 3 && !is_q) {
9919                 unallocated_encoding(s);
9920                 return;
9921             }
9922             break;
9923         case 0x7c: /* URSQRTE */
9924             if (size == 3) {
9925                 unallocated_encoding(s);
9926                 return;
9927             }
9928             need_fpstatus = true;
9929             break;
9930         default:
9931             unallocated_encoding(s);
9932             return;
9933         }
9934         break;
9935     }
9936     default:
9937         unallocated_encoding(s);
9938         return;
9939     }
9940
9941     if (!fp_access_check(s)) {
9942         return;
9943     }
9944
9945     if (need_fpstatus) {
9946         tcg_fpstatus = get_fpstatus_ptr();
9947     } else {
9948         TCGV_UNUSED_PTR(tcg_fpstatus);
9949     }
9950     if (need_rmode) {
9951         tcg_rmode = tcg_const_i32(arm_rmode_to_sf(rmode));
9952         gen_helper_set_rmode(tcg_rmode, tcg_rmode, cpu_env);
9953     } else {
9954         TCGV_UNUSED_I32(tcg_rmode);
9955     }
9956
9957     if (size == 3) {
9958         /* All 64-bit element operations can be shared with scalar 2misc */
9959         int pass;
9960
9961         for (pass = 0; pass < (is_q ? 2 : 1); pass++) {
9962             TCGv_i64 tcg_op = tcg_temp_new_i64();
9963             TCGv_i64 tcg_res = tcg_temp_new_i64();
9964
9965             read_vec_element(s, tcg_op, rn, pass, MO_64);
9966
9967             handle_2misc_64(s, opcode, u, tcg_res, tcg_op,
9968                             tcg_rmode, tcg_fpstatus);
9969
9970             write_vec_element(s, tcg_res, rd, pass, MO_64);
9971
9972             tcg_temp_free_i64(tcg_res);
9973             tcg_temp_free_i64(tcg_op);
9974         }
9975     } else {
9976         int pass;
9977
9978         for (pass = 0; pass < (is_q ? 4 : 2); pass++) {
9979             TCGv_i32 tcg_op = tcg_temp_new_i32();
9980             TCGv_i32 tcg_res = tcg_temp_new_i32();
9981             TCGCond cond;
9982
9983             read_vec_element_i32(s, tcg_op, rn, pass, MO_32);
9984
9985             if (size == 2) {
9986                 /* Special cases for 32 bit elements */
9987                 switch (opcode) {
9988                 case 0xa: /* CMLT */
9989                     /* 32 bit integer comparison against zero, result is
9990                      * test ? (2^32 - 1) : 0. We implement via setcond(test)
9991                      * and inverting.
9992                      */
9993                     cond = TCG_COND_LT;
9994                 do_cmop:
9995                     tcg_gen_setcondi_i32(cond, tcg_res, tcg_op, 0);
9996                     tcg_gen_neg_i32(tcg_res, tcg_res);
9997                     break;
9998                 case 0x8: /* CMGT, CMGE */
9999                     cond = u ? TCG_COND_GE : TCG_COND_GT;
10000                     goto do_cmop;
10001                 case 0x9: /* CMEQ, CMLE */
10002                     cond = u ? TCG_COND_LE : TCG_COND_EQ;
10003                     goto do_cmop;
10004                 case 0x4: /* CLS */
10005                     if (u) {
10006                         gen_helper_clz32(tcg_res, tcg_op);
10007                     } else {
10008                         gen_helper_cls32(tcg_res, tcg_op);
10009                     }
10010                     break;
10011                 case 0x7: /* SQABS, SQNEG */
10012                     if (u) {
10013                         gen_helper_neon_qneg_s32(tcg_res, cpu_env, tcg_op);
10014                     } else {
10015                         gen_helper_neon_qabs_s32(tcg_res, cpu_env, tcg_op);
10016                     }
10017                     break;
10018                 case 0xb: /* ABS, NEG */
10019                     if (u) {
10020                         tcg_gen_neg_i32(tcg_res, tcg_op);
10021                     } else {
10022                         TCGv_i32 tcg_zero = tcg_const_i32(0);
10023                         tcg_gen_neg_i32(tcg_res, tcg_op);
10024                         tcg_gen_movcond_i32(TCG_COND_GT, tcg_res, tcg_op,
10025                                             tcg_zero, tcg_op, tcg_res);
10026                         tcg_temp_free_i32(tcg_zero);
10027                     }
10028                     break;
10029                 case 0x2f: /* FABS */
10030                     gen_helper_vfp_abss(tcg_res, tcg_op);
10031                     break;
10032                 case 0x6f: /* FNEG */
10033                     gen_helper_vfp_negs(tcg_res, tcg_op);
10034                     break;
10035                 case 0x7f: /* FSQRT */
10036                     gen_helper_vfp_sqrts(tcg_res, tcg_op, cpu_env);
10037                     break;
10038                 case 0x1a: /* FCVTNS */
10039                 case 0x1b: /* FCVTMS */
10040                 case 0x1c: /* FCVTAS */
10041                 case 0x3a: /* FCVTPS */
10042                 case 0x3b: /* FCVTZS */
10043                 {
10044                     TCGv_i32 tcg_shift = tcg_const_i32(0);
10045                     gen_helper_vfp_tosls(tcg_res, tcg_op,
10046                                          tcg_shift, tcg_fpstatus);
10047                     tcg_temp_free_i32(tcg_shift);
10048                     break;
10049                 }
10050                 case 0x5a: /* FCVTNU */
10051                 case 0x5b: /* FCVTMU */
10052                 case 0x5c: /* FCVTAU */
10053                 case 0x7a: /* FCVTPU */
10054                 case 0x7b: /* FCVTZU */
10055                 {
10056                     TCGv_i32 tcg_shift = tcg_const_i32(0);
10057                     gen_helper_vfp_touls(tcg_res, tcg_op,
10058                                          tcg_shift, tcg_fpstatus);
10059                     tcg_temp_free_i32(tcg_shift);
10060                     break;
10061                 }
10062                 case 0x18: /* FRINTN */
10063                 case 0x19: /* FRINTM */
10064                 case 0x38: /* FRINTP */
10065                 case 0x39: /* FRINTZ */
10066                 case 0x58: /* FRINTA */
10067                 case 0x79: /* FRINTI */
10068                     gen_helper_rints(tcg_res, tcg_op, tcg_fpstatus);
10069                     break;
10070                 case 0x59: /* FRINTX */
10071                     gen_helper_rints_exact(tcg_res, tcg_op, tcg_fpstatus);
10072                     break;
10073                 case 0x7c: /* URSQRTE */
10074                     gen_helper_rsqrte_u32(tcg_res, tcg_op, tcg_fpstatus);
10075                     break;
10076                 default:
10077                     g_assert_not_reached();
10078                 }
10079             } else {
10080                 /* Use helpers for 8 and 16 bit elements */
10081                 switch (opcode) {
10082                 case 0x5: /* CNT, RBIT */
10083                     /* For these two insns size is part of the opcode specifier
10084                      * (handled earlier); they always operate on byte elements.
10085                      */
10086                     if (u) {
10087                         gen_helper_neon_rbit_u8(tcg_res, tcg_op);
10088                     } else {
10089                         gen_helper_neon_cnt_u8(tcg_res, tcg_op);
10090                     }
10091                     break;
10092                 case 0x7: /* SQABS, SQNEG */
10093                 {
10094                     NeonGenOneOpEnvFn *genfn;
10095                     static NeonGenOneOpEnvFn * const fns[2][2] = {
10096                         { gen_helper_neon_qabs_s8, gen_helper_neon_qneg_s8 },
10097                         { gen_helper_neon_qabs_s16, gen_helper_neon_qneg_s16 },
10098                     };
10099                     genfn = fns[size][u];
10100                     genfn(tcg_res, cpu_env, tcg_op);
10101                     break;
10102                 }
10103                 case 0x8: /* CMGT, CMGE */
10104                 case 0x9: /* CMEQ, CMLE */
10105                 case 0xa: /* CMLT */
10106                 {
10107                     static NeonGenTwoOpFn * const fns[3][2] = {
10108                         { gen_helper_neon_cgt_s8, gen_helper_neon_cgt_s16 },
10109                         { gen_helper_neon_cge_s8, gen_helper_neon_cge_s16 },
10110                         { gen_helper_neon_ceq_u8, gen_helper_neon_ceq_u16 },
10111                     };
10112                     NeonGenTwoOpFn *genfn;
10113                     int comp;
10114                     bool reverse;
10115                     TCGv_i32 tcg_zero = tcg_const_i32(0);
10116
10117                     /* comp = index into [CMGT, CMGE, CMEQ, CMLE, CMLT] */
10118                     comp = (opcode - 0x8) * 2 + u;
10119                     /* ...but LE, LT are implemented as reverse GE, GT */
10120                     reverse = (comp > 2);
10121                     if (reverse) {
10122                         comp = 4 - comp;
10123                     }
10124                     genfn = fns[comp][size];
10125                     if (reverse) {
10126                         genfn(tcg_res, tcg_zero, tcg_op);
10127                     } else {
10128                         genfn(tcg_res, tcg_op, tcg_zero);
10129                     }
10130                     tcg_temp_free_i32(tcg_zero);
10131                     break;
10132                 }
10133                 case 0xb: /* ABS, NEG */
10134                     if (u) {
10135                         TCGv_i32 tcg_zero = tcg_const_i32(0);
10136                         if (size) {
10137                             gen_helper_neon_sub_u16(tcg_res, tcg_zero, tcg_op);
10138                         } else {
10139                             gen_helper_neon_sub_u8(tcg_res, tcg_zero, tcg_op);
10140                         }
10141                         tcg_temp_free_i32(tcg_zero);
10142                     } else {
10143                         if (size) {
10144                             gen_helper_neon_abs_s16(tcg_res, tcg_op);
10145                         } else {
10146                             gen_helper_neon_abs_s8(tcg_res, tcg_op);
10147                         }
10148                     }
10149                     break;
10150                 case 0x4: /* CLS, CLZ */
10151                     if (u) {
10152                         if (size == 0) {
10153                             gen_helper_neon_clz_u8(tcg_res, tcg_op);
10154                         } else {
10155                             gen_helper_neon_clz_u16(tcg_res, tcg_op);
10156                         }
10157                     } else {
10158                         if (size == 0) {
10159                             gen_helper_neon_cls_s8(tcg_res, tcg_op);
10160                         } else {
10161                             gen_helper_neon_cls_s16(tcg_res, tcg_op);
10162                         }
10163                     }
10164                     break;
10165                 default:
10166                     g_assert_not_reached();
10167                 }
10168             }
10169
10170             write_vec_element_i32(s, tcg_res, rd, pass, MO_32);
10171
10172             tcg_temp_free_i32(tcg_res);
10173             tcg_temp_free_i32(tcg_op);
10174         }
10175     }
10176     if (!is_q) {
10177         clear_vec_high(s, rd);
10178     }
10179
10180     if (need_rmode) {
10181         gen_helper_set_rmode(tcg_rmode, tcg_rmode, cpu_env);
10182         tcg_temp_free_i32(tcg_rmode);
10183     }
10184     if (need_fpstatus) {
10185         tcg_temp_free_ptr(tcg_fpstatus);
10186     }
10187 }
10188
10189 /* C3.6.13 AdvSIMD scalar x indexed element
10190  *  31 30  29 28       24 23  22 21  20  19  16 15 12  11  10 9    5 4    0
10191  * +-----+---+-----------+------+---+---+------+-----+---+---+------+------+
10192  * | 0 1 | U | 1 1 1 1 1 | size | L | M |  Rm  | opc | H | 0 |  Rn  |  Rd  |
10193  * +-----+---+-----------+------+---+---+------+-----+---+---+------+------+
10194  * C3.6.18 AdvSIMD vector x indexed element
10195  *   31  30  29 28       24 23  22 21  20  19  16 15 12  11  10 9    5 4    0
10196  * +---+---+---+-----------+------+---+---+------+-----+---+---+------+------+
10197  * | 0 | Q | U | 0 1 1 1 1 | size | L | M |  Rm  | opc | H | 0 |  Rn  |  Rd  |
10198  * +---+---+---+-----------+------+---+---+------+-----+---+---+------+------+
10199  */
10200 static void disas_simd_indexed(DisasContext *s, uint32_t insn)
10201 {
10202     /* This encoding has two kinds of instruction:
10203      *  normal, where we perform elt x idxelt => elt for each
10204      *     element in the vector
10205      *  long, where we perform elt x idxelt and generate a result of
10206      *     double the width of the input element
10207      * The long ops have a 'part' specifier (ie come in INSN, INSN2 pairs).
10208      */
10209     bool is_scalar = extract32(insn, 28, 1);
10210     bool is_q = extract32(insn, 30, 1);
10211     bool u = extract32(insn, 29, 1);
10212     int size = extract32(insn, 22, 2);
10213     int l = extract32(insn, 21, 1);
10214     int m = extract32(insn, 20, 1);
10215     /* Note that the Rm field here is only 4 bits, not 5 as it usually is */
10216     int rm = extract32(insn, 16, 4);
10217     int opcode = extract32(insn, 12, 4);
10218     int h = extract32(insn, 11, 1);
10219     int rn = extract32(insn, 5, 5);
10220     int rd = extract32(insn, 0, 5);
10221     bool is_long = false;
10222     bool is_fp = false;
10223     int index;
10224     TCGv_ptr fpst;
10225
10226     switch (opcode) {
10227     case 0x0: /* MLA */
10228     case 0x4: /* MLS */
10229         if (!u || is_scalar) {
10230             unallocated_encoding(s);
10231             return;
10232         }
10233         break;
10234     case 0x2: /* SMLAL, SMLAL2, UMLAL, UMLAL2 */
10235     case 0x6: /* SMLSL, SMLSL2, UMLSL, UMLSL2 */
10236     case 0xa: /* SMULL, SMULL2, UMULL, UMULL2 */
10237         if (is_scalar) {
10238             unallocated_encoding(s);
10239             return;
10240         }
10241         is_long = true;
10242         break;
10243     case 0x3: /* SQDMLAL, SQDMLAL2 */
10244     case 0x7: /* SQDMLSL, SQDMLSL2 */
10245     case 0xb: /* SQDMULL, SQDMULL2 */
10246         is_long = true;
10247         /* fall through */
10248     case 0xc: /* SQDMULH */
10249     case 0xd: /* SQRDMULH */
10250         if (u) {
10251             unallocated_encoding(s);
10252             return;
10253         }
10254         break;
10255     case 0x8: /* MUL */
10256         if (u || is_scalar) {
10257             unallocated_encoding(s);
10258             return;
10259         }
10260         break;
10261     case 0x1: /* FMLA */
10262     case 0x5: /* FMLS */
10263         if (u) {
10264             unallocated_encoding(s);
10265             return;
10266         }
10267         /* fall through */
10268     case 0x9: /* FMUL, FMULX */
10269         if (!extract32(size, 1, 1)) {
10270             unallocated_encoding(s);
10271             return;
10272         }
10273         is_fp = true;
10274         break;
10275     default:
10276         unallocated_encoding(s);
10277         return;
10278     }
10279
10280     if (is_fp) {
10281         /* low bit of size indicates single/double */
10282         size = extract32(size, 0, 1) ? 3 : 2;
10283         if (size == 2) {
10284             index = h << 1 | l;
10285         } else {
10286             if (l || !is_q) {
10287                 unallocated_encoding(s);
10288                 return;
10289             }
10290             index = h;
10291         }
10292         rm |= (m << 4);
10293     } else {
10294         switch (size) {
10295         case 1:
10296             index = h << 2 | l << 1 | m;
10297             break;
10298         case 2:
10299             index = h << 1 | l;
10300             rm |= (m << 4);
10301             break;
10302         default:
10303             unallocated_encoding(s);
10304             return;
10305         }
10306     }
10307
10308     if (!fp_access_check(s)) {
10309         return;
10310     }
10311
10312     if (is_fp) {
10313         fpst = get_fpstatus_ptr();
10314     } else {
10315         TCGV_UNUSED_PTR(fpst);
10316     }
10317
10318     if (size == 3) {
10319         TCGv_i64 tcg_idx = tcg_temp_new_i64();
10320         int pass;
10321
10322         assert(is_fp && is_q && !is_long);
10323
10324         read_vec_element(s, tcg_idx, rm, index, MO_64);
10325
10326         for (pass = 0; pass < (is_scalar ? 1 : 2); pass++) {
10327             TCGv_i64 tcg_op = tcg_temp_new_i64();
10328             TCGv_i64 tcg_res = tcg_temp_new_i64();
10329
10330             read_vec_element(s, tcg_op, rn, pass, MO_64);
10331
10332             switch (opcode) {
10333             case 0x5: /* FMLS */
10334                 /* As usual for ARM, separate negation for fused multiply-add */
10335                 gen_helper_vfp_negd(tcg_op, tcg_op);
10336                 /* fall through */
10337             case 0x1: /* FMLA */
10338                 read_vec_element(s, tcg_res, rd, pass, MO_64);
10339                 gen_helper_vfp_muladdd(tcg_res, tcg_op, tcg_idx, tcg_res, fpst);
10340                 break;
10341             case 0x9: /* FMUL, FMULX */
10342                 if (u) {
10343                     gen_helper_vfp_mulxd(tcg_res, tcg_op, tcg_idx, fpst);
10344                 } else {
10345                     gen_helper_vfp_muld(tcg_res, tcg_op, tcg_idx, fpst);
10346                 }
10347                 break;
10348             default:
10349                 g_assert_not_reached();
10350             }
10351
10352             write_vec_element(s, tcg_res, rd, pass, MO_64);
10353             tcg_temp_free_i64(tcg_op);
10354             tcg_temp_free_i64(tcg_res);
10355         }
10356
10357         if (is_scalar) {
10358             clear_vec_high(s, rd);
10359         }
10360
10361         tcg_temp_free_i64(tcg_idx);
10362     } else if (!is_long) {
10363         /* 32 bit floating point, or 16 or 32 bit integer.
10364          * For the 16 bit scalar case we use the usual Neon helpers and
10365          * rely on the fact that 0 op 0 == 0 with no side effects.
10366          */
10367         TCGv_i32 tcg_idx = tcg_temp_new_i32();
10368         int pass, maxpasses;
10369
10370         if (is_scalar) {
10371             maxpasses = 1;
10372         } else {
10373             maxpasses = is_q ? 4 : 2;
10374         }
10375
10376         read_vec_element_i32(s, tcg_idx, rm, index, size);
10377
10378         if (size == 1 && !is_scalar) {
10379             /* The simplest way to handle the 16x16 indexed ops is to duplicate
10380              * the index into both halves of the 32 bit tcg_idx and then use
10381              * the usual Neon helpers.
10382              */
10383             tcg_gen_deposit_i32(tcg_idx, tcg_idx, tcg_idx, 16, 16);
10384         }
10385
10386         for (pass = 0; pass < maxpasses; pass++) {
10387             TCGv_i32 tcg_op = tcg_temp_new_i32();
10388             TCGv_i32 tcg_res = tcg_temp_new_i32();
10389
10390             read_vec_element_i32(s, tcg_op, rn, pass, is_scalar ? size : MO_32);
10391
10392             switch (opcode) {
10393             case 0x0: /* MLA */
10394             case 0x4: /* MLS */
10395             case 0x8: /* MUL */
10396             {
10397                 static NeonGenTwoOpFn * const fns[2][2] = {
10398                     { gen_helper_neon_add_u16, gen_helper_neon_sub_u16 },
10399                     { tcg_gen_add_i32, tcg_gen_sub_i32 },
10400                 };
10401                 NeonGenTwoOpFn *genfn;
10402                 bool is_sub = opcode == 0x4;
10403
10404                 if (size == 1) {
10405                     gen_helper_neon_mul_u16(tcg_res, tcg_op, tcg_idx);
10406                 } else {
10407                     tcg_gen_mul_i32(tcg_res, tcg_op, tcg_idx);
10408                 }
10409                 if (opcode == 0x8) {
10410                     break;
10411                 }
10412                 read_vec_element_i32(s, tcg_op, rd, pass, MO_32);
10413                 genfn = fns[size - 1][is_sub];
10414                 genfn(tcg_res, tcg_op, tcg_res);
10415                 break;
10416             }
10417             case 0x5: /* FMLS */
10418                 /* As usual for ARM, separate negation for fused multiply-add */
10419                 gen_helper_vfp_negs(tcg_op, tcg_op);
10420                 /* fall through */
10421             case 0x1: /* FMLA */
10422                 read_vec_element_i32(s, tcg_res, rd, pass, MO_32);
10423                 gen_helper_vfp_muladds(tcg_res, tcg_op, tcg_idx, tcg_res, fpst);
10424                 break;
10425             case 0x9: /* FMUL, FMULX */
10426                 if (u) {
10427                     gen_helper_vfp_mulxs(tcg_res, tcg_op, tcg_idx, fpst);
10428                 } else {
10429                     gen_helper_vfp_muls(tcg_res, tcg_op, tcg_idx, fpst);
10430                 }
10431                 break;
10432             case 0xc: /* SQDMULH */
10433                 if (size == 1) {
10434                     gen_helper_neon_qdmulh_s16(tcg_res, cpu_env,
10435                                                tcg_op, tcg_idx);
10436                 } else {
10437                     gen_helper_neon_qdmulh_s32(tcg_res, cpu_env,
10438                                                tcg_op, tcg_idx);
10439                 }
10440                 break;
10441             case 0xd: /* SQRDMULH */
10442                 if (size == 1) {
10443                     gen_helper_neon_qrdmulh_s16(tcg_res, cpu_env,
10444                                                 tcg_op, tcg_idx);
10445                 } else {
10446                     gen_helper_neon_qrdmulh_s32(tcg_res, cpu_env,
10447                                                 tcg_op, tcg_idx);
10448                 }
10449                 break;
10450             default:
10451                 g_assert_not_reached();
10452             }
10453
10454             if (is_scalar) {
10455                 write_fp_sreg(s, rd, tcg_res);
10456             } else {
10457                 write_vec_element_i32(s, tcg_res, rd, pass, MO_32);
10458             }
10459
10460             tcg_temp_free_i32(tcg_op);
10461             tcg_temp_free_i32(tcg_res);
10462         }
10463
10464         tcg_temp_free_i32(tcg_idx);
10465
10466         if (!is_q) {
10467             clear_vec_high(s, rd);
10468         }
10469     } else {
10470         /* long ops: 16x16->32 or 32x32->64 */
10471         TCGv_i64 tcg_res[2];
10472         int pass;
10473         bool satop = extract32(opcode, 0, 1);
10474         TCGMemOp memop = MO_32;
10475
10476         if (satop || !u) {
10477             memop |= MO_SIGN;
10478         }
10479
10480         if (size == 2) {
10481             TCGv_i64 tcg_idx = tcg_temp_new_i64();
10482
10483             read_vec_element(s, tcg_idx, rm, index, memop);
10484
10485             for (pass = 0; pass < (is_scalar ? 1 : 2); pass++) {
10486                 TCGv_i64 tcg_op = tcg_temp_new_i64();
10487                 TCGv_i64 tcg_passres;
10488                 int passelt;
10489
10490                 if (is_scalar) {
10491                     passelt = 0;
10492                 } else {
10493                     passelt = pass + (is_q * 2);
10494                 }
10495
10496                 read_vec_element(s, tcg_op, rn, passelt, memop);
10497
10498                 tcg_res[pass] = tcg_temp_new_i64();
10499
10500                 if (opcode == 0xa || opcode == 0xb) {
10501                     /* Non-accumulating ops */
10502                     tcg_passres = tcg_res[pass];
10503                 } else {
10504                     tcg_passres = tcg_temp_new_i64();
10505                 }
10506
10507                 tcg_gen_mul_i64(tcg_passres, tcg_op, tcg_idx);
10508                 tcg_temp_free_i64(tcg_op);
10509
10510                 if (satop) {
10511                     /* saturating, doubling */
10512                     gen_helper_neon_addl_saturate_s64(tcg_passres, cpu_env,
10513                                                       tcg_passres, tcg_passres);
10514                 }
10515
10516                 if (opcode == 0xa || opcode == 0xb) {
10517                     continue;
10518                 }
10519
10520                 /* Accumulating op: handle accumulate step */
10521                 read_vec_element(s, tcg_res[pass], rd, pass, MO_64);
10522
10523                 switch (opcode) {
10524                 case 0x2: /* SMLAL, SMLAL2, UMLAL, UMLAL2 */
10525                     tcg_gen_add_i64(tcg_res[pass], tcg_res[pass], tcg_passres);
10526                     break;
10527                 case 0x6: /* SMLSL, SMLSL2, UMLSL, UMLSL2 */
10528                     tcg_gen_sub_i64(tcg_res[pass], tcg_res[pass], tcg_passres);
10529                     break;
10530                 case 0x7: /* SQDMLSL, SQDMLSL2 */
10531                     tcg_gen_neg_i64(tcg_passres, tcg_passres);
10532                     /* fall through */
10533                 case 0x3: /* SQDMLAL, SQDMLAL2 */
10534                     gen_helper_neon_addl_saturate_s64(tcg_res[pass], cpu_env,
10535                                                       tcg_res[pass],
10536                                                       tcg_passres);
10537                     break;
10538                 default:
10539                     g_assert_not_reached();
10540                 }
10541                 tcg_temp_free_i64(tcg_passres);
10542             }
10543             tcg_temp_free_i64(tcg_idx);
10544
10545             if (is_scalar) {
10546                 clear_vec_high(s, rd);
10547             }
10548         } else {
10549             TCGv_i32 tcg_idx = tcg_temp_new_i32();
10550
10551             assert(size == 1);
10552             read_vec_element_i32(s, tcg_idx, rm, index, size);
10553
10554             if (!is_scalar) {
10555                 /* The simplest way to handle the 16x16 indexed ops is to
10556                  * duplicate the index into both halves of the 32 bit tcg_idx
10557                  * and then use the usual Neon helpers.
10558                  */
10559                 tcg_gen_deposit_i32(tcg_idx, tcg_idx, tcg_idx, 16, 16);
10560             }
10561
10562             for (pass = 0; pass < (is_scalar ? 1 : 2); pass++) {
10563                 TCGv_i32 tcg_op = tcg_temp_new_i32();
10564                 TCGv_i64 tcg_passres;
10565
10566                 if (is_scalar) {
10567                     read_vec_element_i32(s, tcg_op, rn, pass, size);
10568                 } else {
10569                     read_vec_element_i32(s, tcg_op, rn,
10570                                          pass + (is_q * 2), MO_32);
10571                 }
10572
10573                 tcg_res[pass] = tcg_temp_new_i64();
10574
10575                 if (opcode == 0xa || opcode == 0xb) {
10576                     /* Non-accumulating ops */
10577                     tcg_passres = tcg_res[pass];
10578                 } else {
10579                     tcg_passres = tcg_temp_new_i64();
10580                 }
10581
10582                 if (memop & MO_SIGN) {
10583                     gen_helper_neon_mull_s16(tcg_passres, tcg_op, tcg_idx);
10584                 } else {
10585                     gen_helper_neon_mull_u16(tcg_passres, tcg_op, tcg_idx);
10586                 }
10587                 if (satop) {
10588                     gen_helper_neon_addl_saturate_s32(tcg_passres, cpu_env,
10589                                                       tcg_passres, tcg_passres);
10590                 }
10591                 tcg_temp_free_i32(tcg_op);
10592
10593                 if (opcode == 0xa || opcode == 0xb) {
10594                     continue;
10595                 }
10596
10597                 /* Accumulating op: handle accumulate step */
10598                 read_vec_element(s, tcg_res[pass], rd, pass, MO_64);
10599
10600                 switch (opcode) {
10601                 case 0x2: /* SMLAL, SMLAL2, UMLAL, UMLAL2 */
10602                     gen_helper_neon_addl_u32(tcg_res[pass], tcg_res[pass],
10603                                              tcg_passres);
10604                     break;
10605                 case 0x6: /* SMLSL, SMLSL2, UMLSL, UMLSL2 */
10606                     gen_helper_neon_subl_u32(tcg_res[pass], tcg_res[pass],
10607                                              tcg_passres);
10608                     break;
10609                 case 0x7: /* SQDMLSL, SQDMLSL2 */
10610                     gen_helper_neon_negl_u32(tcg_passres, tcg_passres);
10611                     /* fall through */
10612                 case 0x3: /* SQDMLAL, SQDMLAL2 */
10613                     gen_helper_neon_addl_saturate_s32(tcg_res[pass], cpu_env,
10614                                                       tcg_res[pass],
10615                                                       tcg_passres);
10616                     break;
10617                 default:
10618                     g_assert_not_reached();
10619                 }
10620                 tcg_temp_free_i64(tcg_passres);
10621             }
10622             tcg_temp_free_i32(tcg_idx);
10623
10624             if (is_scalar) {
10625                 tcg_gen_ext32u_i64(tcg_res[0], tcg_res[0]);
10626             }
10627         }
10628
10629         if (is_scalar) {
10630             tcg_res[1] = tcg_const_i64(0);
10631         }
10632
10633         for (pass = 0; pass < 2; pass++) {
10634             write_vec_element(s, tcg_res[pass], rd, pass, MO_64);
10635             tcg_temp_free_i64(tcg_res[pass]);
10636         }
10637     }
10638
10639     if (!TCGV_IS_UNUSED_PTR(fpst)) {
10640         tcg_temp_free_ptr(fpst);
10641     }
10642 }
10643
10644 /* C3.6.19 Crypto AES
10645  *  31             24 23  22 21       17 16    12 11 10 9    5 4    0
10646  * +-----------------+------+-----------+--------+-----+------+------+
10647  * | 0 1 0 0 1 1 1 0 | size | 1 0 1 0 0 | opcode | 1 0 |  Rn  |  Rd  |
10648  * +-----------------+------+-----------+--------+-----+------+------+
10649  */
10650 static void disas_crypto_aes(DisasContext *s, uint32_t insn)
10651 {
10652     int size = extract32(insn, 22, 2);
10653     int opcode = extract32(insn, 12, 5);
10654     int rn = extract32(insn, 5, 5);
10655     int rd = extract32(insn, 0, 5);
10656     int decrypt;
10657     TCGv_i32 tcg_rd_regno, tcg_rn_regno, tcg_decrypt;
10658     CryptoThreeOpEnvFn *genfn;
10659
10660     if (!arm_dc_feature(s, ARM_FEATURE_V8_AES)
10661         || size != 0) {
10662         unallocated_encoding(s);
10663         return;
10664     }
10665
10666     switch (opcode) {
10667     case 0x4: /* AESE */
10668         decrypt = 0;
10669         genfn = gen_helper_crypto_aese;
10670         break;
10671     case 0x6: /* AESMC */
10672         decrypt = 0;
10673         genfn = gen_helper_crypto_aesmc;
10674         break;
10675     case 0x5: /* AESD */
10676         decrypt = 1;
10677         genfn = gen_helper_crypto_aese;
10678         break;
10679     case 0x7: /* AESIMC */
10680         decrypt = 1;
10681         genfn = gen_helper_crypto_aesmc;
10682         break;
10683     default:
10684         unallocated_encoding(s);
10685         return;
10686     }
10687
10688     /* Note that we convert the Vx register indexes into the
10689      * index within the vfp.regs[] array, so we can share the
10690      * helper with the AArch32 instructions.
10691      */
10692     tcg_rd_regno = tcg_const_i32(rd << 1);
10693     tcg_rn_regno = tcg_const_i32(rn << 1);
10694     tcg_decrypt = tcg_const_i32(decrypt);
10695
10696     genfn(cpu_env, tcg_rd_regno, tcg_rn_regno, tcg_decrypt);
10697
10698     tcg_temp_free_i32(tcg_rd_regno);
10699     tcg_temp_free_i32(tcg_rn_regno);
10700     tcg_temp_free_i32(tcg_decrypt);
10701 }
10702
10703 /* C3.6.20 Crypto three-reg SHA
10704  *  31             24 23  22  21 20  16  15 14    12 11 10 9    5 4    0
10705  * +-----------------+------+---+------+---+--------+-----+------+------+
10706  * | 0 1 0 1 1 1 1 0 | size | 0 |  Rm  | 0 | opcode | 0 0 |  Rn  |  Rd  |
10707  * +-----------------+------+---+------+---+--------+-----+------+------+
10708  */
10709 static void disas_crypto_three_reg_sha(DisasContext *s, uint32_t insn)
10710 {
10711     int size = extract32(insn, 22, 2);
10712     int opcode = extract32(insn, 12, 3);
10713     int rm = extract32(insn, 16, 5);
10714     int rn = extract32(insn, 5, 5);
10715     int rd = extract32(insn, 0, 5);
10716     CryptoThreeOpEnvFn *genfn;
10717     TCGv_i32 tcg_rd_regno, tcg_rn_regno, tcg_rm_regno;
10718     int feature = ARM_FEATURE_V8_SHA256;
10719
10720     if (size != 0) {
10721         unallocated_encoding(s);
10722         return;
10723     }
10724
10725     switch (opcode) {
10726     case 0: /* SHA1C */
10727     case 1: /* SHA1P */
10728     case 2: /* SHA1M */
10729     case 3: /* SHA1SU0 */
10730         genfn = NULL;
10731         feature = ARM_FEATURE_V8_SHA1;
10732         break;
10733     case 4: /* SHA256H */
10734         genfn = gen_helper_crypto_sha256h;
10735         break;
10736     case 5: /* SHA256H2 */
10737         genfn = gen_helper_crypto_sha256h2;
10738         break;
10739     case 6: /* SHA256SU1 */
10740         genfn = gen_helper_crypto_sha256su1;
10741         break;
10742     default:
10743         unallocated_encoding(s);
10744         return;
10745     }
10746
10747     if (!arm_dc_feature(s, feature)) {
10748         unallocated_encoding(s);
10749         return;
10750     }
10751
10752     tcg_rd_regno = tcg_const_i32(rd << 1);
10753     tcg_rn_regno = tcg_const_i32(rn << 1);
10754     tcg_rm_regno = tcg_const_i32(rm << 1);
10755
10756     if (genfn) {
10757         genfn(cpu_env, tcg_rd_regno, tcg_rn_regno, tcg_rm_regno);
10758     } else {
10759         TCGv_i32 tcg_opcode = tcg_const_i32(opcode);
10760
10761         gen_helper_crypto_sha1_3reg(cpu_env, tcg_rd_regno,
10762                                     tcg_rn_regno, tcg_rm_regno, tcg_opcode);
10763         tcg_temp_free_i32(tcg_opcode);
10764     }
10765
10766     tcg_temp_free_i32(tcg_rd_regno);
10767     tcg_temp_free_i32(tcg_rn_regno);
10768     tcg_temp_free_i32(tcg_rm_regno);
10769 }
10770
10771 /* C3.6.21 Crypto two-reg SHA
10772  *  31             24 23  22 21       17 16    12 11 10 9    5 4    0
10773  * +-----------------+------+-----------+--------+-----+------+------+
10774  * | 0 1 0 1 1 1 1 0 | size | 1 0 1 0 0 | opcode | 1 0 |  Rn  |  Rd  |
10775  * +-----------------+------+-----------+--------+-----+------+------+
10776  */
10777 static void disas_crypto_two_reg_sha(DisasContext *s, uint32_t insn)
10778 {
10779     int size = extract32(insn, 22, 2);
10780     int opcode = extract32(insn, 12, 5);
10781     int rn = extract32(insn, 5, 5);
10782     int rd = extract32(insn, 0, 5);
10783     CryptoTwoOpEnvFn *genfn;
10784     int feature;
10785     TCGv_i32 tcg_rd_regno, tcg_rn_regno;
10786
10787     if (size != 0) {
10788         unallocated_encoding(s);
10789         return;
10790     }
10791
10792     switch (opcode) {
10793     case 0: /* SHA1H */
10794         feature = ARM_FEATURE_V8_SHA1;
10795         genfn = gen_helper_crypto_sha1h;
10796         break;
10797     case 1: /* SHA1SU1 */
10798         feature = ARM_FEATURE_V8_SHA1;
10799         genfn = gen_helper_crypto_sha1su1;
10800         break;
10801     case 2: /* SHA256SU0 */
10802         feature = ARM_FEATURE_V8_SHA256;
10803         genfn = gen_helper_crypto_sha256su0;
10804         break;
10805     default:
10806         unallocated_encoding(s);
10807         return;
10808     }
10809
10810     if (!arm_dc_feature(s, feature)) {
10811         unallocated_encoding(s);
10812         return;
10813     }
10814
10815     tcg_rd_regno = tcg_const_i32(rd << 1);
10816     tcg_rn_regno = tcg_const_i32(rn << 1);
10817
10818     genfn(cpu_env, tcg_rd_regno, tcg_rn_regno);
10819
10820     tcg_temp_free_i32(tcg_rd_regno);
10821     tcg_temp_free_i32(tcg_rn_regno);
10822 }
10823
10824 /* C3.6 Data processing - SIMD, inc Crypto
10825  *
10826  * As the decode gets a little complex we are using a table based
10827  * approach for this part of the decode.
10828  */
10829 static const AArch64DecodeTable data_proc_simd[] = {
10830     /* pattern  ,  mask     ,  fn                        */
10831     { 0x0e200400, 0x9f200400, disas_simd_three_reg_same },
10832     { 0x0e200000, 0x9f200c00, disas_simd_three_reg_diff },
10833     { 0x0e200800, 0x9f3e0c00, disas_simd_two_reg_misc },
10834     { 0x0e300800, 0x9f3e0c00, disas_simd_across_lanes },
10835     { 0x0e000400, 0x9fe08400, disas_simd_copy },
10836     { 0x0f000000, 0x9f000400, disas_simd_indexed }, /* vector indexed */
10837     /* simd_mod_imm decode is a subset of simd_shift_imm, so must precede it */
10838     { 0x0f000400, 0x9ff80400, disas_simd_mod_imm },
10839     { 0x0f000400, 0x9f800400, disas_simd_shift_imm },
10840     { 0x0e000000, 0xbf208c00, disas_simd_tb },
10841     { 0x0e000800, 0xbf208c00, disas_simd_zip_trn },
10842     { 0x2e000000, 0xbf208400, disas_simd_ext },
10843     { 0x5e200400, 0xdf200400, disas_simd_scalar_three_reg_same },
10844     { 0x5e200000, 0xdf200c00, disas_simd_scalar_three_reg_diff },
10845     { 0x5e200800, 0xdf3e0c00, disas_simd_scalar_two_reg_misc },
10846     { 0x5e300800, 0xdf3e0c00, disas_simd_scalar_pairwise },
10847     { 0x5e000400, 0xdfe08400, disas_simd_scalar_copy },
10848     { 0x5f000000, 0xdf000400, disas_simd_indexed }, /* scalar indexed */
10849     { 0x5f000400, 0xdf800400, disas_simd_scalar_shift_imm },
10850     { 0x4e280800, 0xff3e0c00, disas_crypto_aes },
10851     { 0x5e000000, 0xff208c00, disas_crypto_three_reg_sha },
10852     { 0x5e280800, 0xff3e0c00, disas_crypto_two_reg_sha },
10853     { 0x00000000, 0x00000000, NULL }
10854 };
10855
10856 static void disas_data_proc_simd(DisasContext *s, uint32_t insn)
10857 {
10858     /* Note that this is called with all non-FP cases from
10859      * table C3-6 so it must UNDEF for entries not specifically
10860      * allocated to instructions in that table.
10861      */
10862     AArch64DecodeFn *fn = lookup_disas_fn(&data_proc_simd[0], insn);
10863     if (fn) {
10864         fn(s, insn);
10865     } else {
10866         unallocated_encoding(s);
10867     }
10868 }
10869
10870 /* C3.6 Data processing - SIMD and floating point */
10871 static void disas_data_proc_simd_fp(DisasContext *s, uint32_t insn)
10872 {
10873     if (extract32(insn, 28, 1) == 1 && extract32(insn, 30, 1) == 0) {
10874         disas_data_proc_fp(s, insn);
10875     } else {
10876         /* SIMD, including crypto */
10877         disas_data_proc_simd(s, insn);
10878     }
10879 }
10880
10881 /* C3.1 A64 instruction index by encoding */
10882 static void disas_a64_insn(CPUARMState *env, DisasContext *s)
10883 {
10884     uint32_t insn;
10885
10886     insn = arm_ldl_code(env, s->pc, s->bswap_code);
10887     s->insn = insn;
10888     s->pc += 4;
10889
10890     s->fp_access_checked = false;
10891
10892     switch (extract32(insn, 25, 4)) {
10893     case 0x0: case 0x1: case 0x2: case 0x3: /* UNALLOCATED */
10894         unallocated_encoding(s);
10895         break;
10896     case 0x8: case 0x9: /* Data processing - immediate */
10897         disas_data_proc_imm(s, insn);
10898         break;
10899     case 0xa: case 0xb: /* Branch, exception generation and system insns */
10900         disas_b_exc_sys(s, insn);
10901         break;
10902     case 0x4:
10903     case 0x6:
10904     case 0xc:
10905     case 0xe:      /* Loads and stores */
10906         disas_ldst(s, insn);
10907         break;
10908     case 0x5:
10909     case 0xd:      /* Data processing - register */
10910         disas_data_proc_reg(s, insn);
10911         break;
10912     case 0x7:
10913     case 0xf:      /* Data processing - SIMD and floating point */
10914         disas_data_proc_simd_fp(s, insn);
10915         break;
10916     default:
10917         assert(FALSE); /* all 15 cases should be handled above */
10918         break;
10919     }
10920
10921     /* if we allocated any temporaries, free them here */
10922     free_tmp_a64(s);
10923 }
10924
10925 void gen_intermediate_code_internal_a64(ARMCPU *cpu,
10926                                         TranslationBlock *tb,
10927                                         bool search_pc)
10928 {
10929     CPUState *cs = CPU(cpu);
10930     CPUARMState *env = &cpu->env;
10931     DisasContext dc1, *dc = &dc1;
10932     CPUBreakpoint *bp;
10933     int j, lj;
10934     target_ulong pc_start;
10935     target_ulong next_page_start;
10936     int num_insns;
10937     int max_insns;
10938
10939     pc_start = tb->pc;
10940
10941     dc->tb = tb;
10942
10943     dc->is_jmp = DISAS_NEXT;
10944     dc->pc = pc_start;
10945     dc->singlestep_enabled = cs->singlestep_enabled;
10946     dc->condjmp = 0;
10947
10948     dc->aarch64 = 1;
10949     dc->el3_is_aa64 = arm_el_is_aa64(env, 3);
10950     dc->thumb = 0;
10951     dc->bswap_code = 0;
10952     dc->condexec_mask = 0;
10953     dc->condexec_cond = 0;
10954     dc->mmu_idx = ARM_TBFLAG_MMUIDX(tb->flags);
10955     dc->current_el = arm_mmu_idx_to_el(dc->mmu_idx);
10956 #if !defined(CONFIG_USER_ONLY)
10957     dc->user = (dc->current_el == 0);
10958 #endif
10959     dc->fp_excp_el = ARM_TBFLAG_FPEXC_EL(tb->flags);
10960     dc->vec_len = 0;
10961     dc->vec_stride = 0;
10962     dc->cp_regs = cpu->cp_regs;
10963     dc->features = env->features;
10964
10965     /* Single step state. The code-generation logic here is:
10966      *  SS_ACTIVE == 0:
10967      *   generate code with no special handling for single-stepping (except
10968      *   that anything that can make us go to SS_ACTIVE == 1 must end the TB;
10969      *   this happens anyway because those changes are all system register or
10970      *   PSTATE writes).
10971      *  SS_ACTIVE == 1, PSTATE.SS == 1: (active-not-pending)
10972      *   emit code for one insn
10973      *   emit code to clear PSTATE.SS
10974      *   emit code to generate software step exception for completed step
10975      *   end TB (as usual for having generated an exception)
10976      *  SS_ACTIVE == 1, PSTATE.SS == 0: (active-pending)
10977      *   emit code to generate a software step exception
10978      *   end the TB
10979      */
10980     dc->ss_active = ARM_TBFLAG_SS_ACTIVE(tb->flags);
10981     dc->pstate_ss = ARM_TBFLAG_PSTATE_SS(tb->flags);
10982     dc->is_ldex = false;
10983     dc->ss_same_el = (arm_debug_target_el(env) == dc->current_el);
10984
10985     init_tmp_a64_array(dc);
10986
10987     next_page_start = (pc_start & TARGET_PAGE_MASK) + TARGET_PAGE_SIZE;
10988     lj = -1;
10989     num_insns = 0;
10990     max_insns = tb->cflags & CF_COUNT_MASK;
10991     if (max_insns == 0) {
10992         max_insns = CF_COUNT_MASK;
10993     }
10994
10995     gen_tb_start(tb);
10996
10997     tcg_clear_temp_count();
10998
10999     do {
11000         if (unlikely(!QTAILQ_EMPTY(&cs->breakpoints))) {
11001             QTAILQ_FOREACH(bp, &cs->breakpoints, entry) {
11002                 if (bp->pc == dc->pc) {
11003                     gen_exception_internal_insn(dc, 0, EXCP_DEBUG);
11004                     /* Advance PC so that clearing the breakpoint will
11005                        invalidate this TB.  */
11006                     dc->pc += 2;
11007                     goto done_generating;
11008                 }
11009             }
11010         }
11011
11012         if (search_pc) {
11013             j = tcg_op_buf_count();
11014             if (lj < j) {
11015                 lj++;
11016                 while (lj < j) {
11017                     tcg_ctx.gen_opc_instr_start[lj++] = 0;
11018                 }
11019             }
11020             tcg_ctx.gen_opc_pc[lj] = dc->pc;
11021             tcg_ctx.gen_opc_instr_start[lj] = 1;
11022             tcg_ctx.gen_opc_icount[lj] = num_insns;
11023         }
11024
11025         if (num_insns + 1 == max_insns && (tb->cflags & CF_LAST_IO)) {
11026             gen_io_start();
11027         }
11028
11029         if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP | CPU_LOG_TB_OP_OPT))) {
11030             tcg_gen_debug_insn_start(dc->pc);
11031         }
11032
11033         if (dc->ss_active && !dc->pstate_ss) {
11034             /* Singlestep state is Active-pending.
11035              * If we're in this state at the start of a TB then either
11036              *  a) we just took an exception to an EL which is being debugged
11037              *     and this is the first insn in the exception handler
11038              *  b) debug exceptions were masked and we just unmasked them
11039              *     without changing EL (eg by clearing PSTATE.D)
11040              * In either case we're going to take a swstep exception in the
11041              * "did not step an insn" case, and so the syndrome ISV and EX
11042              * bits should be zero.
11043              */
11044             assert(num_insns == 0);
11045             gen_exception(EXCP_UDEF, syn_swstep(dc->ss_same_el, 0, 0),
11046                           default_exception_el(dc));
11047             dc->is_jmp = DISAS_EXC;
11048             break;
11049         }
11050
11051         disas_a64_insn(env, dc);
11052
11053         if (tcg_check_temp_count()) {
11054             fprintf(stderr, "TCG temporary leak before "TARGET_FMT_lx"\n",
11055                     dc->pc);
11056         }
11057
11058         /* Translation stops when a conditional branch is encountered.
11059          * Otherwise the subsequent code could get translated several times.
11060          * Also stop translation when a page boundary is reached.  This
11061          * ensures prefetch aborts occur at the right place.
11062          */
11063         num_insns++;
11064     } while (!dc->is_jmp && !tcg_op_buf_full() &&
11065              !cs->singlestep_enabled &&
11066              !singlestep &&
11067              !dc->ss_active &&
11068              dc->pc < next_page_start &&
11069              num_insns < max_insns);
11070
11071     if (tb->cflags & CF_LAST_IO) {
11072         gen_io_end();
11073     }
11074
11075     if (unlikely(cs->singlestep_enabled || dc->ss_active)
11076         && dc->is_jmp != DISAS_EXC) {
11077         /* Note that this means single stepping WFI doesn't halt the CPU.
11078          * For conditional branch insns this is harmless unreachable code as
11079          * gen_goto_tb() has already handled emitting the debug exception
11080          * (and thus a tb-jump is not possible when singlestepping).
11081          */
11082         assert(dc->is_jmp != DISAS_TB_JUMP);
11083         if (dc->is_jmp != DISAS_JUMP) {
11084             gen_a64_set_pc_im(dc->pc);
11085         }
11086         if (cs->singlestep_enabled) {
11087             gen_exception_internal(EXCP_DEBUG);
11088         } else {
11089             gen_step_complete_exception(dc);
11090         }
11091     } else {
11092         switch (dc->is_jmp) {
11093         case DISAS_NEXT:
11094             gen_goto_tb(dc, 1, dc->pc);
11095             break;
11096         default:
11097         case DISAS_UPDATE:
11098             gen_a64_set_pc_im(dc->pc);
11099             /* fall through */
11100         case DISAS_JUMP:
11101             /* indicate that the hash table must be used to find the next TB */
11102             tcg_gen_exit_tb(0);
11103             break;
11104         case DISAS_TB_JUMP:
11105         case DISAS_EXC:
11106         case DISAS_SWI:
11107             break;
11108         case DISAS_WFE:
11109             gen_a64_set_pc_im(dc->pc);
11110             gen_helper_wfe(cpu_env);
11111             break;
11112         case DISAS_YIELD:
11113             gen_a64_set_pc_im(dc->pc);
11114             gen_helper_yield(cpu_env);
11115             break;
11116         case DISAS_WFI:
11117             /* This is a special case because we don't want to just halt the CPU
11118              * if trying to debug across a WFI.
11119              */
11120             gen_a64_set_pc_im(dc->pc);
11121             gen_helper_wfi(cpu_env);
11122             /* The helper doesn't necessarily throw an exception, but we
11123              * must go back to the main loop to check for interrupts anyway.
11124              */
11125             tcg_gen_exit_tb(0);
11126             break;
11127         }
11128     }
11129
11130 done_generating:
11131     gen_tb_end(tb, num_insns);
11132
11133 #ifdef DEBUG_DISAS
11134     if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
11135         qemu_log("----------------\n");
11136         qemu_log("IN: %s\n", lookup_symbol(pc_start));
11137         log_target_disas(cs, pc_start, dc->pc - pc_start,
11138                          4 | (dc->bswap_code << 1));
11139         qemu_log("\n");
11140     }
11141 #endif
11142     if (search_pc) {
11143         j = tcg_op_buf_count();
11144         lj++;
11145         while (lj <= j) {
11146             tcg_ctx.gen_opc_instr_start[lj++] = 0;
11147         }
11148     } else {
11149         tb->size = dc->pc - pc_start;
11150         tb->icount = num_insns;
11151     }
11152 }