1 /*
2  *  ARM translation
3  *
4  *  Copyright (c) 2003 Fabrice Bellard
5  *  Copyright (c) 2005-2007 CodeSourcery
6  *  Copyright (c) 2007 OpenedHand, Ltd.
7  *  Copyright (c) 2015 Nguyen Anh Quynh (Unicorn engine)
8  *
9  * This library is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU Lesser General Public
11  * License as published by the Free Software Foundation; either
12  * version 2 of the License, or (at your option) any later version.
13  *
14  * This library is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17  * Lesser General Public License for more details.
18  *
19  * You should have received a copy of the GNU Lesser General Public
20  * License along with this library; if not, see <http://www.gnu.org/licenses/>.
21  */
22 #include <stdarg.h>
23 #include <stdlib.h>
24 #include <stdio.h>
25 #include <string.h>
26 #include "unicorn/platform.h"
27 
28 #include "cpu.h"
29 #include "internals.h"
30 #include "tcg-op.h"
31 #include "qemu/log.h"
32 #include "qemu/bitops.h"
33 #include "arm_ldst.h"
34 
35 #include "exec/helper-proto.h"
36 #include "exec/helper-gen.h"
37 
38 #include "exec/gen-icount.h"
39 
40 #define ENABLE_ARCH_4T    arm_dc_feature(s, ARM_FEATURE_V4T)
41 #define ENABLE_ARCH_5     arm_dc_feature(s, ARM_FEATURE_V5)
42 /* currently all emulated v5 cores are also v5TE, so don't bother */
43 #define ENABLE_ARCH_5TE   arm_dc_feature(s, ARM_FEATURE_V5)
44 #define ENABLE_ARCH_5J    0
45 #define ENABLE_ARCH_6     arm_dc_feature(s, ARM_FEATURE_V6)
46 #define ENABLE_ARCH_6K    arm_dc_feature(s, ARM_FEATURE_V6K)
47 #define ENABLE_ARCH_6T2   arm_dc_feature(s, ARM_FEATURE_THUMB2)
48 #define ENABLE_ARCH_7     arm_dc_feature(s, ARM_FEATURE_V7)
49 #define ENABLE_ARCH_8     arm_dc_feature(s, ARM_FEATURE_V8)
50 
51 #define ARCH(x) do { if (!ENABLE_ARCH_##x) goto illegal_op; } while(0)
52 
53 #include "translate.h"
54 
55 #if defined(CONFIG_USER_ONLY)
56 #define IS_USER(s) 1
57 #else
58 #define IS_USER(s) (s->user)
59 #endif
60 
61 #ifdef CONFIG_USER_ONLY
62 static TCGv_i64 cpu_exclusive_test;
63 static TCGv_i32 cpu_exclusive_info;
64 #endif
65 
66 
67 static const char *regnames[] =
68     { "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
69       "r8", "r9", "r10", "r11", "r12", "r13", "r14", "pc" };
70 
71 /* initialize TCG globals.  */
arm_translate_init(struct uc_struct * uc)72 void arm_translate_init(struct uc_struct *uc)
73 {
74     int i;
75     TCGContext *tcg_ctx = uc->tcg_ctx;
76 
77     tcg_ctx->cpu_env = tcg_global_reg_new_ptr(uc->tcg_ctx, TCG_AREG0, "env");
78 
79     for (i = 0; i < 16; i++) {
80         tcg_ctx->cpu_R[i] = tcg_global_mem_new_i32(uc->tcg_ctx, TCG_AREG0,
81                                           offsetof(CPUARMState, regs[i]),
82                                           regnames[i]);
83     }
84     tcg_ctx->cpu_CF = tcg_global_mem_new_i32(uc->tcg_ctx, TCG_AREG0, offsetof(CPUARMState, CF), "CF");
85     tcg_ctx->cpu_NF = tcg_global_mem_new_i32(uc->tcg_ctx, TCG_AREG0, offsetof(CPUARMState, NF), "NF");
86     tcg_ctx->cpu_VF = tcg_global_mem_new_i32(uc->tcg_ctx, TCG_AREG0, offsetof(CPUARMState, VF), "VF");
87     tcg_ctx->cpu_ZF = tcg_global_mem_new_i32(uc->tcg_ctx, TCG_AREG0, offsetof(CPUARMState, ZF), "ZF");
88 
89     tcg_ctx->cpu_exclusive_addr = tcg_global_mem_new_i64(uc->tcg_ctx, TCG_AREG0,
90         offsetof(CPUARMState, exclusive_addr), "exclusive_addr");
91     tcg_ctx->cpu_exclusive_val = tcg_global_mem_new_i64(uc->tcg_ctx, TCG_AREG0,
92         offsetof(CPUARMState, exclusive_val), "exclusive_val");
93 #ifdef CONFIG_USER_ONLY
94     cpu_exclusive_test = tcg_global_mem_new_i64(uc->tcg_ctx, TCG_AREG0,
95         offsetof(CPUARMState, exclusive_test), "exclusive_test");
96     cpu_exclusive_info = tcg_global_mem_new_i32(uc->tcg_ctx, TCG_AREG0,
97         offsetof(CPUARMState, exclusive_info), "exclusive_info");
98 #endif
99 
100     a64_translate_init(uc);
101 }
102 
load_cpu_offset(struct uc_struct * uc,int offset)103 static inline TCGv_i32 load_cpu_offset(struct uc_struct *uc, int offset)
104 {
105     TCGContext *tcg_ctx = uc->tcg_ctx;
106     TCGv_i32 tmp = tcg_temp_new_i32(tcg_ctx);
107     tcg_gen_ld_i32(tcg_ctx, tmp, tcg_ctx->cpu_env, offset);
108     return tmp;
109 }
110 
111 #define load_cpu_field(uc, name) load_cpu_offset(uc, offsetof(CPUARMState, name))
112 
store_cpu_offset(TCGContext * tcg_ctx,TCGv_i32 var,int offset)113 static inline void store_cpu_offset(TCGContext *tcg_ctx, TCGv_i32 var, int offset)
114 {
115     tcg_gen_st_i32(tcg_ctx, var, tcg_ctx->cpu_env, offset);
116     tcg_temp_free_i32(tcg_ctx, var);
117 }
118 
119 #define store_cpu_field(s, var, name) \
120     store_cpu_offset(s, var, offsetof(CPUARMState, name))
121 
122 /* Set a variable to the value of a CPU register.  */
load_reg_var(DisasContext * s,TCGv_i32 var,int reg)123 static void load_reg_var(DisasContext *s, TCGv_i32 var, int reg)
124 {
125     TCGContext *tcg_ctx = s->uc->tcg_ctx;
126     if (reg == 15) {
127         uint32_t addr;
128         /* normally, since we updated PC, we need only to add one insn */
129         if (s->thumb)
130             addr = (long)s->pc + 2;
131         else
132             addr = (long)s->pc + 4;
133         tcg_gen_movi_i32(tcg_ctx, var, addr);
134     } else {
135         tcg_gen_mov_i32(tcg_ctx, var, tcg_ctx->cpu_R[reg & 0x0f]);
136     }
137 }
138 
139 /* Create a new temporary and set it to the value of a CPU register.  */
load_reg(DisasContext * s,int reg)140 static inline TCGv_i32 load_reg(DisasContext *s, int reg)
141 {
142     TCGContext *tcg_ctx = s->uc->tcg_ctx;
143     TCGv_i32 tmp = tcg_temp_new_i32(tcg_ctx);
144     load_reg_var(s, tmp, reg);
145     return tmp;
146 }
147 
148 /* Set a CPU register.  The source must be a temporary and will be
149    marked as dead.  */
store_reg(DisasContext * s,int reg,TCGv_i32 var)150 static void store_reg(DisasContext *s, int reg, TCGv_i32 var)
151 {
152     TCGContext *tcg_ctx = s->uc->tcg_ctx;
153     if (reg == 15) {
154         tcg_gen_andi_i32(tcg_ctx, var, var, ~1);
155         s->is_jmp = DISAS_JUMP;
156     }
157     tcg_gen_mov_i32(tcg_ctx, tcg_ctx->cpu_R[reg & 0x0f], var);
158     tcg_temp_free_i32(tcg_ctx, var);
159 }
160 
161 /* Value extensions.  */
162 #define gen_uxtb(var) tcg_gen_ext8u_i32(tcg_ctx, var, var)
163 #define gen_uxth(var) tcg_gen_ext16u_i32(tcg_ctx, var, var)
164 #define gen_sxtb(var) tcg_gen_ext8s_i32(tcg_ctx, var, var)
165 #define gen_sxth(var) tcg_gen_ext16s_i32(tcg_ctx, var, var)
166 
167 #define gen_sxtb16(var) gen_helper_sxtb16(tcg_ctx, var, var)
168 #define gen_uxtb16(var) gen_helper_uxtb16(tcg_ctx, var, var)
169 
170 
gen_set_cpsr(DisasContext * s,TCGv_i32 var,uint32_t mask)171 static inline void gen_set_cpsr(DisasContext *s, TCGv_i32 var, uint32_t mask)
172 {
173     TCGContext *tcg_ctx = s->uc->tcg_ctx;
174     TCGv_i32 tmp_mask = tcg_const_i32(tcg_ctx, mask);
175     gen_helper_cpsr_write(tcg_ctx, tcg_ctx->cpu_env, var, tmp_mask);
176     tcg_temp_free_i32(tcg_ctx, tmp_mask);
177 }
178 /* Set NZCV flags from the high 4 bits of var.  */
179 #define gen_set_nzcv(s, var) gen_set_cpsr(s, var, CPSR_NZCV)
180 
gen_exception_internal(DisasContext * s,int excp)181 static void gen_exception_internal(DisasContext *s, int excp)
182 {
183     TCGContext *tcg_ctx = s->uc->tcg_ctx;
184     TCGv_i32 tcg_excp = tcg_const_i32(tcg_ctx, excp);
185 
186     assert(excp_is_internal(excp));
187     gen_helper_exception_internal(tcg_ctx, tcg_ctx->cpu_env, tcg_excp);
188     tcg_temp_free_i32(tcg_ctx, tcg_excp);
189 }
190 
gen_exception(DisasContext * s,int excp,uint32_t syndrome)191 static void gen_exception(DisasContext *s, int excp, uint32_t syndrome)  // qq
192 {
193     TCGContext *tcg_ctx = s->uc->tcg_ctx;
194     TCGv_i32 tcg_excp = tcg_const_i32(tcg_ctx, excp);
195     TCGv_i32 tcg_syn = tcg_const_i32(tcg_ctx, syndrome);
196 
197     gen_helper_exception_with_syndrome(tcg_ctx, tcg_ctx->cpu_env, tcg_excp, tcg_syn);
198     tcg_temp_free_i32(tcg_ctx, tcg_syn);
199     tcg_temp_free_i32(tcg_ctx, tcg_excp);
200 }
201 
gen_ss_advance(DisasContext * s)202 static void gen_ss_advance(DisasContext *s)
203 {
204     TCGContext *tcg_ctx = s->uc->tcg_ctx;
205     /* If the singlestep state is Active-not-pending, advance to
206      * Active-pending.
207      */
208     if (s->ss_active) {
209         s->pstate_ss = 0;
210         gen_helper_clear_pstate_ss(tcg_ctx, tcg_ctx->cpu_env);
211     }
212 }
213 
gen_step_complete_exception(DisasContext * s)214 static void gen_step_complete_exception(DisasContext *s)
215 {
216     /* We just completed step of an insn. Move from Active-not-pending
217      * to Active-pending, and then also take the swstep exception.
218      * This corresponds to making the (IMPDEF) choice to prioritize
219      * swstep exceptions over asynchronous exceptions taken to an exception
220      * level where debug is disabled. This choice has the advantage that
221      * we do not need to maintain internal state corresponding to the
222      * ISV/EX syndrome bits between completion of the step and generation
223      * of the exception, and our syndrome information is always correct.
224      */
225     gen_ss_advance(s);
226     gen_exception(s, EXCP_UDEF, syn_swstep(s->ss_same_el, 1, s->is_ldex));
227     s->is_jmp = DISAS_EXC;
228 }
229 
gen_smul_dual(DisasContext * s,TCGv_i32 a,TCGv_i32 b)230 static void gen_smul_dual(DisasContext *s, TCGv_i32 a, TCGv_i32 b)
231 {
232     TCGContext *tcg_ctx = s->uc->tcg_ctx;
233     TCGv_i32 tmp1 = tcg_temp_new_i32(tcg_ctx);
234     TCGv_i32 tmp2 = tcg_temp_new_i32(tcg_ctx);
235     tcg_gen_ext16s_i32(tcg_ctx, tmp1, a);
236     tcg_gen_ext16s_i32(tcg_ctx, tmp2, b);
237     tcg_gen_mul_i32(tcg_ctx, tmp1, tmp1, tmp2);
238     tcg_temp_free_i32(tcg_ctx, tmp2);
239     tcg_gen_sari_i32(tcg_ctx, a, a, 16);
240     tcg_gen_sari_i32(tcg_ctx, b, b, 16);
241     tcg_gen_mul_i32(tcg_ctx, b, b, a);
242     tcg_gen_mov_i32(tcg_ctx, a, tmp1);
243     tcg_temp_free_i32(tcg_ctx, tmp1);
244 }
245 
246 /* Byteswap each halfword.  */
gen_rev16(DisasContext * s,TCGv_i32 var)247 static void gen_rev16(DisasContext *s, TCGv_i32 var)
248 {
249     TCGContext *tcg_ctx = s->uc->tcg_ctx;
250     TCGv_i32 tmp = tcg_temp_new_i32(tcg_ctx);
251     tcg_gen_shri_i32(tcg_ctx, tmp, var, 8);
252     tcg_gen_andi_i32(tcg_ctx, tmp, tmp, 0x00ff00ff);
253     tcg_gen_shli_i32(tcg_ctx, var, var, 8);
254     tcg_gen_andi_i32(tcg_ctx, var, var, 0xff00ff00);
255     tcg_gen_or_i32(tcg_ctx, var, var, tmp);
256     tcg_temp_free_i32(tcg_ctx, tmp);
257 }
258 
259 /* Byteswap low halfword and sign extend.  */
gen_revsh(DisasContext * s,TCGv_i32 var)260 static void gen_revsh(DisasContext *s, TCGv_i32 var)
261 {
262     TCGContext *tcg_ctx = s->uc->tcg_ctx;
263     tcg_gen_ext16u_i32(tcg_ctx, var, var);
264     tcg_gen_bswap16_i32(tcg_ctx, var, var);
265     tcg_gen_ext16s_i32(tcg_ctx, var, var);
266 }
267 
268 /* Unsigned bitfield extract.  */
gen_ubfx(DisasContext * s,TCGv_i32 var,int shift,uint32_t mask)269 static void gen_ubfx(DisasContext *s, TCGv_i32 var, int shift, uint32_t mask)
270 {
271     TCGContext *tcg_ctx = s->uc->tcg_ctx;
272     if (shift)
273         tcg_gen_shri_i32(tcg_ctx, var, var, shift);
274     tcg_gen_andi_i32(tcg_ctx, var, var, mask);
275 }
276 
277 /* Signed bitfield extract.  */
gen_sbfx(DisasContext * s,TCGv_i32 var,int shift,int width)278 static void gen_sbfx(DisasContext *s, TCGv_i32 var, int shift, int width)
279 {
280     TCGContext *tcg_ctx = s->uc->tcg_ctx;
281     uint32_t signbit;
282 
283     if (shift)
284         tcg_gen_sari_i32(tcg_ctx, var, var, shift);
285     if (shift + width < 32) {
286         signbit = 1u << (width - 1);
287         tcg_gen_andi_i32(tcg_ctx, var, var, (1u << width) - 1);
288         tcg_gen_xori_i32(tcg_ctx, var, var, signbit);
289         tcg_gen_subi_i32(tcg_ctx, var, var, signbit);
290     }
291 }
292 
293 /* Return (b << 32) + a. Mark inputs as dead */
gen_addq_msw(DisasContext * s,TCGv_i64 a,TCGv_i32 b)294 static TCGv_i64 gen_addq_msw(DisasContext *s, TCGv_i64 a, TCGv_i32 b)
295 {
296     TCGContext *tcg_ctx = s->uc->tcg_ctx;
297     TCGv_i64 tmp64 = tcg_temp_new_i64(tcg_ctx);
298 
299     tcg_gen_extu_i32_i64(tcg_ctx, tmp64, b);
300     tcg_temp_free_i32(tcg_ctx, b);
301     tcg_gen_shli_i64(tcg_ctx, tmp64, tmp64, 32);
302     tcg_gen_add_i64(tcg_ctx, a, tmp64, a);
303 
304     tcg_temp_free_i64(tcg_ctx, tmp64);
305     return a;
306 }
307 
308 /* Return (b << 32) - a. Mark inputs as dead. */
gen_subq_msw(DisasContext * s,TCGv_i64 a,TCGv_i32 b)309 static TCGv_i64 gen_subq_msw(DisasContext *s, TCGv_i64 a, TCGv_i32 b)
310 {
311     TCGContext *tcg_ctx = s->uc->tcg_ctx;
312     TCGv_i64 tmp64 = tcg_temp_new_i64(tcg_ctx);
313 
314     tcg_gen_extu_i32_i64(tcg_ctx, tmp64, b);
315     tcg_temp_free_i32(tcg_ctx, b);
316     tcg_gen_shli_i64(tcg_ctx, tmp64, tmp64, 32);
317     tcg_gen_sub_i64(tcg_ctx, a, tmp64, a);
318 
319     tcg_temp_free_i64(tcg_ctx, tmp64);
320     return a;
321 }
322 
323 /* 32x32->64 multiply.  Marks inputs as dead.  */
gen_mulu_i64_i32(DisasContext * s,TCGv_i32 a,TCGv_i32 b)324 static TCGv_i64 gen_mulu_i64_i32(DisasContext *s, TCGv_i32 a, TCGv_i32 b)
325 {
326     TCGContext *tcg_ctx = s->uc->tcg_ctx;
327     TCGv_i32 lo = tcg_temp_new_i32(tcg_ctx);
328     TCGv_i32 hi = tcg_temp_new_i32(tcg_ctx);
329     TCGv_i64 ret;
330 
331     tcg_gen_mulu2_i32(tcg_ctx, lo, hi, a, b);
332     tcg_temp_free_i32(tcg_ctx, a);
333     tcg_temp_free_i32(tcg_ctx, b);
334 
335     ret = tcg_temp_new_i64(tcg_ctx);
336     tcg_gen_concat_i32_i64(tcg_ctx, ret, lo, hi);
337     tcg_temp_free_i32(tcg_ctx, lo);
338     tcg_temp_free_i32(tcg_ctx, hi);
339 
340     return ret;
341 }
342 
gen_muls_i64_i32(DisasContext * s,TCGv_i32 a,TCGv_i32 b)343 static TCGv_i64 gen_muls_i64_i32(DisasContext *s, TCGv_i32 a, TCGv_i32 b)
344 {
345     TCGContext *tcg_ctx = s->uc->tcg_ctx;
346     TCGv_i32 lo = tcg_temp_new_i32(tcg_ctx);
347     TCGv_i32 hi = tcg_temp_new_i32(tcg_ctx);
348     TCGv_i64 ret;
349 
350     tcg_gen_muls2_i32(tcg_ctx, lo, hi, a, b);
351     tcg_temp_free_i32(tcg_ctx, a);
352     tcg_temp_free_i32(tcg_ctx, b);
353 
354     ret = tcg_temp_new_i64(tcg_ctx);
355     tcg_gen_concat_i32_i64(tcg_ctx, ret, lo, hi);
356     tcg_temp_free_i32(tcg_ctx, lo);
357     tcg_temp_free_i32(tcg_ctx, hi);
358 
359     return ret;
360 }
361 
362 /* Swap low and high halfwords.  */
gen_swap_half(DisasContext * s,TCGv_i32 var)363 static void gen_swap_half(DisasContext *s, TCGv_i32 var)
364 {
365     TCGContext *tcg_ctx = s->uc->tcg_ctx;
366     TCGv_i32 tmp = tcg_temp_new_i32(tcg_ctx);
367     tcg_gen_shri_i32(tcg_ctx, tmp, var, 16);
368     tcg_gen_shli_i32(tcg_ctx, var, var, 16);
369     tcg_gen_or_i32(tcg_ctx, var, var, tmp);
370     tcg_temp_free_i32(tcg_ctx, tmp);
371 }
372 
373 /* Dual 16-bit add.  Result placed in t0 and t1 is marked as dead.
374     tmp = (t0 ^ t1) & 0x8000;
375     t0 &= ~0x8000;
376     t1 &= ~0x8000;
377     t0 = (t0 + t1) ^ tmp;
378  */
379 
gen_add16(DisasContext * s,TCGv_i32 t0,TCGv_i32 t1)380 static void gen_add16(DisasContext *s, TCGv_i32 t0, TCGv_i32 t1)
381 {
382     TCGContext *tcg_ctx = s->uc->tcg_ctx;
383     TCGv_i32 tmp = tcg_temp_new_i32(tcg_ctx);
384     tcg_gen_xor_i32(tcg_ctx, tmp, t0, t1);
385     tcg_gen_andi_i32(tcg_ctx, tmp, tmp, 0x8000);
386     tcg_gen_andi_i32(tcg_ctx, t0, t0, ~0x8000);
387     tcg_gen_andi_i32(tcg_ctx, t1, t1, ~0x8000);
388     tcg_gen_add_i32(tcg_ctx, t0, t0, t1);
389     tcg_gen_xor_i32(tcg_ctx, t0, t0, tmp);
390     tcg_temp_free_i32(tcg_ctx, tmp);
391     tcg_temp_free_i32(tcg_ctx, t1);
392 }
393 
394 /* Set CF to the top bit of var.  */
gen_set_CF_bit31(DisasContext * s,TCGv_i32 var)395 static void gen_set_CF_bit31(DisasContext *s, TCGv_i32 var)
396 {
397     TCGContext *tcg_ctx = s->uc->tcg_ctx;
398     tcg_gen_shri_i32(tcg_ctx, tcg_ctx->cpu_CF, var, 31);
399 }
400 
401 /* Set N and Z flags from var.  */
gen_logic_CC(DisasContext * s,TCGv_i32 var)402 static inline void gen_logic_CC(DisasContext *s, TCGv_i32 var)
403 {
404     TCGContext *tcg_ctx = s->uc->tcg_ctx;
405     tcg_gen_mov_i32(tcg_ctx, tcg_ctx->cpu_NF, var);
406     tcg_gen_mov_i32(tcg_ctx, tcg_ctx->cpu_ZF, var);
407 }
408 
409 /* T0 += T1 + CF.  */
gen_adc(DisasContext * s,TCGv_i32 t0,TCGv_i32 t1)410 static void gen_adc(DisasContext *s, TCGv_i32 t0, TCGv_i32 t1)
411 {
412     TCGContext *tcg_ctx = s->uc->tcg_ctx;
413     tcg_gen_add_i32(tcg_ctx, t0, t0, t1);
414     tcg_gen_add_i32(tcg_ctx, t0, t0, tcg_ctx->cpu_CF);
415 }
416 
417 /* dest = T0 + T1 + CF. */
gen_add_carry(DisasContext * s,TCGv_i32 dest,TCGv_i32 t0,TCGv_i32 t1)418 static void gen_add_carry(DisasContext *s, TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
419 {
420     TCGContext *tcg_ctx = s->uc->tcg_ctx;
421     tcg_gen_add_i32(tcg_ctx, dest, t0, t1);
422     tcg_gen_add_i32(tcg_ctx, dest, dest, tcg_ctx->cpu_CF);
423 }
424 
425 /* dest = T0 - T1 + CF - 1.  */
gen_sub_carry(DisasContext * s,TCGv_i32 dest,TCGv_i32 t0,TCGv_i32 t1)426 static void gen_sub_carry(DisasContext *s, TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
427 {
428     TCGContext *tcg_ctx = s->uc->tcg_ctx;
429     tcg_gen_sub_i32(tcg_ctx, dest, t0, t1);
430     tcg_gen_add_i32(tcg_ctx, dest, dest, tcg_ctx->cpu_CF);
431     tcg_gen_subi_i32(tcg_ctx, dest, dest, 1);
432 }
433 
434 /* dest = T0 + T1. Compute C, N, V and Z flags */
gen_add_CC(DisasContext * s,TCGv_i32 dest,TCGv_i32 t0,TCGv_i32 t1)435 static void gen_add_CC(DisasContext *s, TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
436 {
437     TCGContext *tcg_ctx = s->uc->tcg_ctx;
438     TCGv_i32 tmp = tcg_temp_new_i32(tcg_ctx);
439     tcg_gen_movi_i32(tcg_ctx, tmp, 0);
440     tcg_gen_add2_i32(tcg_ctx, tcg_ctx->cpu_NF, tcg_ctx->cpu_CF, t0, tmp, t1, tmp);
441     tcg_gen_mov_i32(tcg_ctx, tcg_ctx->cpu_ZF, tcg_ctx->cpu_NF);
442     tcg_gen_xor_i32(tcg_ctx, tcg_ctx->cpu_VF, tcg_ctx->cpu_NF, t0);
443     tcg_gen_xor_i32(tcg_ctx, tmp, t0, t1);
444     tcg_gen_andc_i32(tcg_ctx, tcg_ctx->cpu_VF, tcg_ctx->cpu_VF, tmp);
445     tcg_temp_free_i32(tcg_ctx, tmp);
446     tcg_gen_mov_i32(tcg_ctx, dest, tcg_ctx->cpu_NF);
447 }
448 
449 /* dest = T0 + T1 + CF.  Compute C, N, V and Z flags */
gen_adc_CC(DisasContext * s,TCGv_i32 dest,TCGv_i32 t0,TCGv_i32 t1)450 static void gen_adc_CC(DisasContext *s, TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
451 {
452     TCGContext *tcg_ctx = s->uc->tcg_ctx;
453     TCGv_i32 tmp = tcg_temp_new_i32(tcg_ctx);
454     if (TCG_TARGET_HAS_add2_i32) {
455         tcg_gen_movi_i32(tcg_ctx, tmp, 0);
456         tcg_gen_add2_i32(tcg_ctx, tcg_ctx->cpu_NF, tcg_ctx->cpu_CF, t0, tmp, tcg_ctx->cpu_CF, tmp);
457         tcg_gen_add2_i32(tcg_ctx, tcg_ctx->cpu_NF, tcg_ctx->cpu_CF, tcg_ctx->cpu_NF, tcg_ctx->cpu_CF, t1, tmp);
458     } else {
459         TCGv_i64 q0 = tcg_temp_new_i64(tcg_ctx);
460         TCGv_i64 q1 = tcg_temp_new_i64(tcg_ctx);
461         tcg_gen_extu_i32_i64(tcg_ctx, q0, t0);
462         tcg_gen_extu_i32_i64(tcg_ctx, q1, t1);
463         tcg_gen_add_i64(tcg_ctx, q0, q0, q1);
464         tcg_gen_extu_i32_i64(tcg_ctx, q1, tcg_ctx->cpu_CF);
465         tcg_gen_add_i64(tcg_ctx, q0, q0, q1);
466         tcg_gen_extr_i64_i32(tcg_ctx, tcg_ctx->cpu_NF, tcg_ctx->cpu_CF, q0);
467         tcg_temp_free_i64(tcg_ctx, q0);
468         tcg_temp_free_i64(tcg_ctx, q1);
469     }
470     tcg_gen_mov_i32(tcg_ctx, tcg_ctx->cpu_ZF, tcg_ctx->cpu_NF);
471     tcg_gen_xor_i32(tcg_ctx, tcg_ctx->cpu_VF, tcg_ctx->cpu_NF, t0);
472     tcg_gen_xor_i32(tcg_ctx, tmp, t0, t1);
473     tcg_gen_andc_i32(tcg_ctx, tcg_ctx->cpu_VF, tcg_ctx->cpu_VF, tmp);
474     tcg_temp_free_i32(tcg_ctx, tmp);
475     tcg_gen_mov_i32(tcg_ctx, dest, tcg_ctx->cpu_NF);
476 }
477 
478 /* dest = T0 - T1. Compute C, N, V and Z flags */
gen_sub_CC(DisasContext * s,TCGv_i32 dest,TCGv_i32 t0,TCGv_i32 t1)479 static void gen_sub_CC(DisasContext *s, TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
480 {
481     TCGContext *tcg_ctx = s->uc->tcg_ctx;
482     TCGv_i32 tmp;
483     tcg_gen_sub_i32(tcg_ctx, tcg_ctx->cpu_NF, t0, t1);
484     tcg_gen_mov_i32(tcg_ctx, tcg_ctx->cpu_ZF, tcg_ctx->cpu_NF);
485     tcg_gen_setcond_i32(tcg_ctx, TCG_COND_GEU, tcg_ctx->cpu_CF, t0, t1);
486     tcg_gen_xor_i32(tcg_ctx, tcg_ctx->cpu_VF, tcg_ctx->cpu_NF, t0);
487     tmp = tcg_temp_new_i32(tcg_ctx);
488     tcg_gen_xor_i32(tcg_ctx, tmp, t0, t1);
489     tcg_gen_and_i32(tcg_ctx, tcg_ctx->cpu_VF, tcg_ctx->cpu_VF, tmp);
490     tcg_temp_free_i32(tcg_ctx, tmp);
491     tcg_gen_mov_i32(tcg_ctx, dest, tcg_ctx->cpu_NF);
492 }
493 
494 /* dest = T0 + ~T1 + CF.  Compute C, N, V and Z flags */
gen_sbc_CC(DisasContext * s,TCGv_i32 dest,TCGv_i32 t0,TCGv_i32 t1)495 static void gen_sbc_CC(DisasContext *s, TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
496 {
497     TCGContext *tcg_ctx = s->uc->tcg_ctx;
498     TCGv_i32 tmp = tcg_temp_new_i32(tcg_ctx);
499     tcg_gen_not_i32(tcg_ctx, tmp, t1);
500     gen_adc_CC(s, dest, t0, tmp);
501     tcg_temp_free_i32(tcg_ctx, tmp);
502 }
503 
504 #define GEN_SHIFT(name)                                               \
505 static void gen_##name(DisasContext *s, TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)       \
506 {                                                                     \
507     TCGContext *tcg_ctx = s->uc->tcg_ctx; \
508     TCGv_i32 tmp1, tmp2, tmp3;                                        \
509     tmp1 = tcg_temp_new_i32(tcg_ctx);                                        \
510     tcg_gen_andi_i32(tcg_ctx, tmp1, t1, 0xff);                                 \
511     tmp2 = tcg_const_i32(tcg_ctx, 0);                                          \
512     tmp3 = tcg_const_i32(tcg_ctx, 0x1f);                                       \
513     tcg_gen_movcond_i32(tcg_ctx, TCG_COND_GTU, tmp2, tmp1, tmp3, tmp2, t0);    \
514     tcg_temp_free_i32(tcg_ctx, tmp3);                                          \
515     tcg_gen_andi_i32(tcg_ctx, tmp1, tmp1, 0x1f);                               \
516     tcg_gen_##name##_i32(tcg_ctx, dest, tmp2, tmp1);                           \
517     tcg_temp_free_i32(tcg_ctx, tmp2);                                          \
518     tcg_temp_free_i32(tcg_ctx, tmp1);                                          \
519 }
520 GEN_SHIFT(shl)
GEN_SHIFT(shr)521 GEN_SHIFT(shr)
522 #undef GEN_SHIFT
523 
524 static void gen_sar(DisasContext *s, TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
525 {
526     TCGContext *tcg_ctx = s->uc->tcg_ctx;
527     TCGv_i32 tmp1, tmp2;
528     tmp1 = tcg_temp_new_i32(tcg_ctx);
529     tcg_gen_andi_i32(tcg_ctx, tmp1, t1, 0xff);
530     tmp2 = tcg_const_i32(tcg_ctx, 0x1f);
531     tcg_gen_movcond_i32(tcg_ctx, TCG_COND_GTU, tmp1, tmp1, tmp2, tmp2, tmp1);
532     tcg_temp_free_i32(tcg_ctx, tmp2);
533     tcg_gen_sar_i32(tcg_ctx, dest, t0, tmp1);
534     tcg_temp_free_i32(tcg_ctx, tmp1);
535 }
536 
tcg_gen_abs_i32(DisasContext * s,TCGv_i32 dest,TCGv_i32 src)537 static void tcg_gen_abs_i32(DisasContext *s, TCGv_i32 dest, TCGv_i32 src)
538 {
539     TCGContext *tcg_ctx = s->uc->tcg_ctx;
540     TCGv_i32 c0 = tcg_const_i32(tcg_ctx, 0);
541     TCGv_i32 tmp = tcg_temp_new_i32(tcg_ctx);
542     tcg_gen_neg_i32(tcg_ctx, tmp, src);
543     tcg_gen_movcond_i32(tcg_ctx, TCG_COND_GT, dest, src, c0, src, tmp);
544     tcg_temp_free_i32(tcg_ctx, c0);
545     tcg_temp_free_i32(tcg_ctx, tmp);
546 }
547 
shifter_out_im(DisasContext * s,TCGv_i32 var,int shift)548 static void shifter_out_im(DisasContext *s, TCGv_i32 var, int shift)
549 {
550     TCGContext *tcg_ctx = s->uc->tcg_ctx;
551     if (shift == 0) {
552         tcg_gen_andi_i32(tcg_ctx, tcg_ctx->cpu_CF, var, 1);
553     } else {
554         tcg_gen_shri_i32(tcg_ctx, tcg_ctx->cpu_CF, var, shift);
555         if (shift != 31) {
556             tcg_gen_andi_i32(tcg_ctx, tcg_ctx->cpu_CF, tcg_ctx->cpu_CF, 1);
557         }
558     }
559 }
560 
561 /* Shift by immediate.  Includes special handling for shift == 0.  */
gen_arm_shift_im(DisasContext * s,TCGv_i32 var,int shiftop,int shift,int flags)562 static inline void gen_arm_shift_im(DisasContext *s, TCGv_i32 var, int shiftop,
563                                     int shift, int flags)
564 {
565     TCGContext *tcg_ctx = s->uc->tcg_ctx;
566     switch (shiftop) {
567     case 0: /* LSL */
568         if (shift != 0) {
569             if (flags)
570                 shifter_out_im(s, var, 32 - shift);
571             tcg_gen_shli_i32(tcg_ctx, var, var, shift);
572         }
573         break;
574     case 1: /* LSR */
575         if (shift == 0) {
576             if (flags) {
577                 tcg_gen_shri_i32(tcg_ctx, tcg_ctx->cpu_CF, var, 31);
578             }
579             tcg_gen_movi_i32(tcg_ctx, var, 0);
580         } else {
581             if (flags)
582                 shifter_out_im(s, var, shift - 1);
583             tcg_gen_shri_i32(tcg_ctx, var, var, shift);
584         }
585         break;
586     case 2: /* ASR */
587         if (shift == 0)
588             shift = 32;
589         if (flags)
590             shifter_out_im(s, var, shift - 1);
591         if (shift == 32)
592           shift = 31;
593         tcg_gen_sari_i32(tcg_ctx, var, var, shift);
594         break;
595     case 3: /* ROR/RRX */
596         if (shift != 0) {
597             if (flags)
598                 shifter_out_im(s, var, shift - 1);
599             tcg_gen_rotri_i32(tcg_ctx, var, var, shift); break;
600         } else {
601             TCGv_i32 tmp = tcg_temp_new_i32(tcg_ctx);
602             tcg_gen_shli_i32(tcg_ctx, tmp, tcg_ctx->cpu_CF, 31);
603             if (flags)
604                 shifter_out_im(s, var, 0);
605             tcg_gen_shri_i32(tcg_ctx, var, var, 1);
606             tcg_gen_or_i32(tcg_ctx, var, var, tmp);
607             tcg_temp_free_i32(tcg_ctx, tmp);
608         }
609     }
610 }
611 
gen_arm_shift_reg(DisasContext * s,TCGv_i32 var,int shiftop,TCGv_i32 shift,int flags)612 static inline void gen_arm_shift_reg(DisasContext *s, TCGv_i32 var, int shiftop,
613                                      TCGv_i32 shift, int flags)
614 {
615     TCGContext *tcg_ctx = s->uc->tcg_ctx;
616     if (flags) {
617         switch (shiftop) {
618         case 0: gen_helper_shl_cc(tcg_ctx, var, tcg_ctx->cpu_env, var, shift); break;
619         case 1: gen_helper_shr_cc(tcg_ctx, var, tcg_ctx->cpu_env, var, shift); break;
620         case 2: gen_helper_sar_cc(tcg_ctx, var, tcg_ctx->cpu_env, var, shift); break;
621         case 3: gen_helper_ror_cc(tcg_ctx, var, tcg_ctx->cpu_env, var, shift); break;
622         }
623     } else {
624         switch (shiftop) {
625         case 0:
626             gen_shl(s, var, var, shift);
627             break;
628         case 1:
629             gen_shr(s, var, var, shift);
630             break;
631         case 2:
632             gen_sar(s, var, var, shift);
633             break;
634         case 3: tcg_gen_andi_i32(tcg_ctx, shift, shift, 0x1f);
635                 tcg_gen_rotr_i32(tcg_ctx, var, var, shift); break;
636         }
637     }
638     tcg_temp_free_i32(tcg_ctx, shift);
639 }
640 
641 #define PAS_OP(pfx) \
642     switch (op2) {  \
643     case 0: gen_pas_helper(glue(pfx,add16)); break; \
644     case 1: gen_pas_helper(glue(pfx,addsubx)); break; \
645     case 2: gen_pas_helper(glue(pfx,subaddx)); break; \
646     case 3: gen_pas_helper(glue(pfx,sub16)); break; \
647     case 4: gen_pas_helper(glue(pfx,add8)); break; \
648     case 7: gen_pas_helper(glue(pfx,sub8)); break; \
649     }
gen_arm_parallel_addsub(DisasContext * s,int op1,int op2,TCGv_i32 a,TCGv_i32 b)650 static void gen_arm_parallel_addsub(DisasContext *s, int op1, int op2, TCGv_i32 a, TCGv_i32 b)
651 {
652     TCGContext *tcg_ctx = s->uc->tcg_ctx;
653     TCGv_ptr tmp;
654 
655     switch (op1) {
656 #define gen_pas_helper(name) glue(gen_helper_,name)(tcg_ctx, a, a, b, tmp)
657     case 1:
658         tmp = tcg_temp_new_ptr(tcg_ctx);
659         tcg_gen_addi_ptr(tcg_ctx, tmp, tcg_ctx->cpu_env, offsetof(CPUARMState, GE));
660         PAS_OP(s)
661         tcg_temp_free_ptr(tcg_ctx, tmp);
662         break;
663     case 5:
664         tmp = tcg_temp_new_ptr(tcg_ctx);
665         tcg_gen_addi_ptr(tcg_ctx, tmp, tcg_ctx->cpu_env, offsetof(CPUARMState, GE));
666         PAS_OP(u)
667         tcg_temp_free_ptr(tcg_ctx, tmp);
668         break;
669 #undef gen_pas_helper
670 #define gen_pas_helper(name) glue(gen_helper_,name)(tcg_ctx, a, a, b)
671     case 2:
672         PAS_OP(q);
673         break;
674     case 3:
675         PAS_OP(sh);
676         break;
677     case 6:
678         PAS_OP(uq);
679         break;
680     case 7:
681         PAS_OP(uh);
682         break;
683 #undef gen_pas_helper
684     }
685 }
686 #undef PAS_OP
687 
688 /* For unknown reasons Arm and Thumb-2 use arbitrarily different encodings.  */
689 #define PAS_OP(pfx) \
690     switch (op1) {  \
691     case 0: gen_pas_helper(glue(pfx,add8)); break; \
692     case 1: gen_pas_helper(glue(pfx,add16)); break; \
693     case 2: gen_pas_helper(glue(pfx,addsubx)); break; \
694     case 4: gen_pas_helper(glue(pfx,sub8)); break; \
695     case 5: gen_pas_helper(glue(pfx,sub16)); break; \
696     case 6: gen_pas_helper(glue(pfx,subaddx)); break; \
697     }
gen_thumb2_parallel_addsub(DisasContext * s,int op1,int op2,TCGv_i32 a,TCGv_i32 b)698 static void gen_thumb2_parallel_addsub(DisasContext *s, int op1, int op2, TCGv_i32 a, TCGv_i32 b)
699 {
700     TCGContext *tcg_ctx = s->uc->tcg_ctx;
701     TCGv_ptr tmp;
702 
703     switch (op2) {
704 #define gen_pas_helper(name) glue(gen_helper_,name)(tcg_ctx, a, a, b, tmp)
705     case 0:
706         tmp = tcg_temp_new_ptr(tcg_ctx);
707         tcg_gen_addi_ptr(tcg_ctx, tmp, tcg_ctx->cpu_env, offsetof(CPUARMState, GE));
708         PAS_OP(s)
709         tcg_temp_free_ptr(tcg_ctx, tmp);
710         break;
711     case 4:
712         tmp = tcg_temp_new_ptr(tcg_ctx);
713         tcg_gen_addi_ptr(tcg_ctx, tmp, tcg_ctx->cpu_env, offsetof(CPUARMState, GE));
714         PAS_OP(u)
715         tcg_temp_free_ptr(tcg_ctx, tmp);
716         break;
717 #undef gen_pas_helper
718 #define gen_pas_helper(name) glue(gen_helper_,name)(tcg_ctx, a, a, b)
719     case 1:
720         PAS_OP(q);
721         break;
722     case 2:
723         PAS_OP(sh);
724         break;
725     case 5:
726         PAS_OP(uq);
727         break;
728     case 6:
729         PAS_OP(uh);
730         break;
731 #undef gen_pas_helper
732     }
733 }
734 #undef PAS_OP
735 
736 /*
737  * generate a conditional branch based on ARM condition code cc.
738  * This is common between ARM and Aarch64 targets.
739  */
arm_gen_test_cc(TCGContext * tcg_ctx,int cc,int label)740 void arm_gen_test_cc(TCGContext *tcg_ctx, int cc, int label)
741 {
742     TCGv_i32 tmp;
743     int inv;
744 
745     switch (cc) {
746     case 0: /* eq: Z */
747         tcg_gen_brcondi_i32(tcg_ctx, TCG_COND_EQ, tcg_ctx->cpu_ZF, 0, label);
748         break;
749     case 1: /* ne: !Z */
750         tcg_gen_brcondi_i32(tcg_ctx, TCG_COND_NE, tcg_ctx->cpu_ZF, 0, label);
751         break;
752     case 2: /* cs: C */
753         tcg_gen_brcondi_i32(tcg_ctx, TCG_COND_NE, tcg_ctx->cpu_CF, 0, label);
754         break;
755     case 3: /* cc: !C */
756         tcg_gen_brcondi_i32(tcg_ctx, TCG_COND_EQ, tcg_ctx->cpu_CF, 0, label);
757         break;
758     case 4: /* mi: N */
759         tcg_gen_brcondi_i32(tcg_ctx, TCG_COND_LT, tcg_ctx->cpu_NF, 0, label);
760         break;
761     case 5: /* pl: !N */
762         tcg_gen_brcondi_i32(tcg_ctx, TCG_COND_GE, tcg_ctx->cpu_NF, 0, label);
763         break;
764     case 6: /* vs: V */
765         tcg_gen_brcondi_i32(tcg_ctx, TCG_COND_LT, tcg_ctx->cpu_VF, 0, label);
766         break;
767     case 7: /* vc: !V */
768         tcg_gen_brcondi_i32(tcg_ctx, TCG_COND_GE, tcg_ctx->cpu_VF, 0, label);
769         break;
770     case 8: /* hi: C && !Z */
771         inv = gen_new_label(tcg_ctx);
772         tcg_gen_brcondi_i32(tcg_ctx, TCG_COND_EQ, tcg_ctx->cpu_CF, 0, inv);
773         tcg_gen_brcondi_i32(tcg_ctx, TCG_COND_NE, tcg_ctx->cpu_ZF, 0, label);
774         gen_set_label(tcg_ctx, inv);
775         break;
776     case 9: /* ls: !C || Z */
777         tcg_gen_brcondi_i32(tcg_ctx, TCG_COND_EQ, tcg_ctx->cpu_CF, 0, label);
778         tcg_gen_brcondi_i32(tcg_ctx, TCG_COND_EQ, tcg_ctx->cpu_ZF, 0, label);
779         break;
780     case 10: /* ge: N == V -> N ^ V == 0 */
781         tmp = tcg_temp_new_i32(tcg_ctx);
782         tcg_gen_xor_i32(tcg_ctx, tmp, tcg_ctx->cpu_VF, tcg_ctx->cpu_NF);
783         tcg_gen_brcondi_i32(tcg_ctx, TCG_COND_GE, tmp, 0, label);
784         tcg_temp_free_i32(tcg_ctx, tmp);
785         break;
786     case 11: /* lt: N != V -> N ^ V != 0 */
787         tmp = tcg_temp_new_i32(tcg_ctx);
788         tcg_gen_xor_i32(tcg_ctx, tmp, tcg_ctx->cpu_VF, tcg_ctx->cpu_NF);
789         tcg_gen_brcondi_i32(tcg_ctx, TCG_COND_LT, tmp, 0, label);
790         tcg_temp_free_i32(tcg_ctx, tmp);
791         break;
792     case 12: /* gt: !Z && N == V */
793         inv = gen_new_label(tcg_ctx);
794         tcg_gen_brcondi_i32(tcg_ctx, TCG_COND_EQ, tcg_ctx->cpu_ZF, 0, inv);
795         tmp = tcg_temp_new_i32(tcg_ctx);
796         tcg_gen_xor_i32(tcg_ctx, tmp, tcg_ctx->cpu_VF, tcg_ctx->cpu_NF);
797         tcg_gen_brcondi_i32(tcg_ctx, TCG_COND_GE, tmp, 0, label);
798         tcg_temp_free_i32(tcg_ctx, tmp);
799         gen_set_label(tcg_ctx, inv);
800         break;
801     case 13: /* le: Z || N != V */
802         tcg_gen_brcondi_i32(tcg_ctx, TCG_COND_EQ, tcg_ctx->cpu_ZF, 0, label);
803         tmp = tcg_temp_new_i32(tcg_ctx);
804         tcg_gen_xor_i32(tcg_ctx, tmp, tcg_ctx->cpu_VF, tcg_ctx->cpu_NF);
805         tcg_gen_brcondi_i32(tcg_ctx, TCG_COND_LT, tmp, 0, label);
806         tcg_temp_free_i32(tcg_ctx, tmp);
807         break;
808     default:
809         /* fprintf(stderr, "Bad condition code 0x%x\n", cc); */
810         tmp = tcg_const_i32(tcg_ctx, EXCP_EXCEPTION_EXIT);
811         gen_helper_exception_internal(tcg_ctx, tcg_ctx->cpu_env, tmp);
812         tcg_temp_free_i32(tcg_ctx, tmp);
813     }
814 }
815 
816 static const uint8_t table_logic_cc[16] = {
817     1, /* and */
818     1, /* xor */
819     0, /* sub */
820     0, /* rsb */
821     0, /* add */
822     0, /* adc */
823     0, /* sbc */
824     0, /* rsc */
825     1, /* andl */
826     1, /* xorl */
827     0, /* cmp */
828     0, /* cmn */
829     1, /* orr */
830     1, /* mov */
831     1, /* bic */
832     1, /* mvn */
833 };
834 
835 /* Set PC and Thumb state from an immediate address.  */
gen_bx_im(DisasContext * s,uint32_t addr)836 static inline void gen_bx_im(DisasContext *s, uint32_t addr)
837 {
838     TCGv_i32 tmp;
839     TCGContext *tcg_ctx = s->uc->tcg_ctx;
840 
841     s->is_jmp = DISAS_UPDATE;
842     if (s->thumb != (addr & 1)) {
843         tmp = tcg_temp_new_i32(tcg_ctx);
844         tcg_gen_movi_i32(tcg_ctx, tmp, addr & 1);
845         tcg_gen_st_i32(tcg_ctx, tmp, tcg_ctx->cpu_env, offsetof(CPUARMState, thumb));
846         tcg_temp_free_i32(tcg_ctx, tmp);
847     }
848     tcg_gen_movi_i32(tcg_ctx, tcg_ctx->cpu_R[15], addr & ~1);
849 }
850 
851 /* Set PC and Thumb state from var.  var is marked as dead.  */
gen_bx(DisasContext * s,TCGv_i32 var)852 static inline void gen_bx(DisasContext *s, TCGv_i32 var)
853 {
854     TCGContext *tcg_ctx = s->uc->tcg_ctx;
855 
856     s->is_jmp = DISAS_UPDATE;
857     tcg_gen_andi_i32(tcg_ctx, tcg_ctx->cpu_R[15], var, ~1);
858     tcg_gen_andi_i32(tcg_ctx, var, var, 1);
859     store_cpu_field(tcg_ctx, var, thumb);
860 }
861 
862 /* Variant of store_reg which uses branch&exchange logic when storing
863    to r15 in ARM architecture v7 and above. The source must be a temporary
864    and will be marked as dead. */
store_reg_bx(DisasContext * s,int reg,TCGv_i32 var)865 static inline void store_reg_bx(DisasContext *s, int reg, TCGv_i32 var)
866 {
867     if (reg == 15 && ENABLE_ARCH_7) {
868         gen_bx(s, var);
869     } else {
870         store_reg(s, reg, var);
871     }
872 }
873 
874 /* Variant of store_reg which uses branch&exchange logic when storing
875  * to r15 in ARM architecture v5T and above. This is used for storing
876  * the results of a LDR/LDM/POP into r15, and corresponds to the cases
877  * in the ARM ARM which use the LoadWritePC() pseudocode function. */
store_reg_from_load(DisasContext * s,int reg,TCGv_i32 var)878 static inline void store_reg_from_load(DisasContext *s, int reg, TCGv_i32 var)
879 {
880     if (reg == 15 && ENABLE_ARCH_5) {
881         gen_bx(s, var);
882     } else {
883         store_reg(s, reg, var);
884     }
885 }
886 
887 /* Abstractions of "generate code to do a guest load/store for
888  * AArch32", where a vaddr is always 32 bits (and is zero
889  * extended if we're a 64 bit core) and  data is also
890  * 32 bits unless specifically doing a 64 bit access.
891  * These functions work like tcg_gen_qemu_{ld,st}* except
892  * that the address argument is TCGv_i32 rather than TCGv.
893  */
894 #if TARGET_LONG_BITS == 32
895 
896 #define DO_GEN_LD(SUFF, OPC)                                             \
897 static inline void gen_aa32_ld##SUFF(DisasContext *s, TCGv_i32 val, TCGv_i32 addr, int index) \
898 {                                                                        \
899     tcg_gen_qemu_ld_i32(s->uc, val, addr, index, OPC);                          \
900 }
901 
902 #define DO_GEN_ST(SUFF, OPC)                                             \
903 static inline void gen_aa32_st##SUFF(DisasContext *s, TCGv_i32 val, TCGv_i32 addr, int index) \
904 {                                                                        \
905     tcg_gen_qemu_st_i32(s->uc, val, addr, index, OPC);                          \
906 }
907 
gen_aa32_ld64(DisasContext * s,TCGv_i64 val,TCGv_i32 addr,int index)908 static inline void gen_aa32_ld64(DisasContext *s, TCGv_i64 val, TCGv_i32 addr, int index)
909 {
910     tcg_gen_qemu_ld_i64(s->uc, val, addr, index, MO_TEQ);
911 }
912 
gen_aa32_st64(DisasContext * s,TCGv_i64 val,TCGv_i32 addr,int index)913 static inline void gen_aa32_st64(DisasContext *s, TCGv_i64 val, TCGv_i32 addr, int index)
914 {
915     tcg_gen_qemu_st_i64(s->uc, val, addr, index, MO_TEQ);
916 }
917 
918 #else
919 
920 #define DO_GEN_LD(SUFF, OPC)                                             \
921 static inline void gen_aa32_ld##SUFF(DisasContext *s, TCGv_i32 val, TCGv_i32 addr, int index) \
922 {                                                                        \
923     TCGContext *tcg_ctx = s->uc->tcg_ctx;  \
924     TCGv addr64 = tcg_temp_new(tcg_ctx);                                        \
925     tcg_gen_extu_i32_i64(tcg_ctx, addr64, addr);                                  \
926     tcg_gen_qemu_ld_i32(s->uc, val, addr64, index, OPC);                        \
927     tcg_temp_free(tcg_ctx, addr64);                                               \
928 }
929 
930 #define DO_GEN_ST(SUFF, OPC)                                             \
931 static inline void gen_aa32_st##SUFF(DisasContext *s, TCGv_i32 val, TCGv_i32 addr, int index) \
932 {                                                                        \
933     TCGContext *tcg_ctx = s->uc->tcg_ctx;  \
934     TCGv addr64 = tcg_temp_new(tcg_ctx);                                        \
935     tcg_gen_extu_i32_i64(tcg_ctx, addr64, addr);                                  \
936     tcg_gen_qemu_st_i32(s->uc, val, addr64, index, OPC);                        \
937     tcg_temp_free(tcg_ctx, addr64);                                               \
938 }
939 
gen_aa32_ld64(DisasContext * s,TCGv_i64 val,TCGv_i32 addr,int index)940 static inline void gen_aa32_ld64(DisasContext *s, TCGv_i64 val, TCGv_i32 addr, int index)
941 {
942     TCGContext *tcg_ctx = s->uc->tcg_ctx;
943     TCGv addr64 = tcg_temp_new(tcg_ctx);
944     tcg_gen_extu_i32_i64(tcg_ctx, addr64, addr);
945     tcg_gen_qemu_ld_i64(s->uc, val, addr64, index, MO_TEQ);
946     tcg_temp_free(tcg_ctx, addr64);
947 }
948 
gen_aa32_st64(DisasContext * s,TCGv_i64 val,TCGv_i32 addr,int index)949 static inline void gen_aa32_st64(DisasContext *s, TCGv_i64 val, TCGv_i32 addr, int index)
950 {
951     TCGContext *tcg_ctx = s->uc->tcg_ctx;
952     TCGv addr64 = tcg_temp_new(tcg_ctx);
953     tcg_gen_extu_i32_i64(tcg_ctx, addr64, addr);
954     tcg_gen_qemu_st_i64(s->uc, val, addr64, index, MO_TEQ);
955     tcg_temp_free(tcg_ctx, addr64);
956 }
957 
958 #endif
959 
960 DO_GEN_LD(8s, MO_SB)
961 DO_GEN_LD(8u, MO_UB)
962 DO_GEN_LD(16s, MO_TESW)
963 DO_GEN_LD(16u, MO_TEUW)
964 DO_GEN_LD(32u, MO_TEUL)
965 DO_GEN_ST(8, MO_UB)
966 DO_GEN_ST(16, MO_TEUW)
967 DO_GEN_ST(32, MO_TEUL)
968 
gen_set_pc_im(DisasContext * s,target_ulong val)969 static inline void gen_set_pc_im(DisasContext *s, target_ulong val)
970 {
971     TCGContext *tcg_ctx = s->uc->tcg_ctx;
972     tcg_gen_movi_i32(tcg_ctx, tcg_ctx->cpu_R[15], val);
973 }
974 
gen_hvc(DisasContext * s,int imm16)975 static inline void gen_hvc(DisasContext *s, int imm16)
976 {
977     TCGContext *tcg_ctx = s->uc->tcg_ctx;
978     /* The pre HVC helper handles cases when HVC gets trapped
979      * as an undefined insn by runtime configuration (ie before
980      * the insn really executes).
981      */
982     gen_set_pc_im(s, s->pc - 4);
983     gen_helper_pre_hvc(tcg_ctx, tcg_ctx->cpu_env);
984     /* Otherwise we will treat this as a real exception which
985      * happens after execution of the insn. (The distinction matters
986      * for the PC value reported to the exception handler and also
987      * for single stepping.)
988      */
989     s->svc_imm = imm16;
990     gen_set_pc_im(s, s->pc);
991     s->is_jmp = DISAS_HVC;
992 }
993 
gen_smc(DisasContext * s)994 static inline void gen_smc(DisasContext *s)
995 {
996     /* As with HVC, we may take an exception either before or after
997      * the insn executes.
998      */
999     TCGv_i32 tmp;
1000     TCGContext *tcg_ctx = s->uc->tcg_ctx;
1001 
1002     gen_set_pc_im(s, s->pc - 4);
1003     tmp = tcg_const_i32(tcg_ctx, syn_aa32_smc());
1004     gen_helper_pre_smc(tcg_ctx, tcg_ctx->cpu_env, tmp);
1005     tcg_temp_free_i32(tcg_ctx, tmp);
1006     gen_set_pc_im(s, s->pc);
1007     s->is_jmp = DISAS_SMC;
1008 }
1009 
1010 static inline void
gen_set_condexec(DisasContext * s)1011 gen_set_condexec (DisasContext *s)
1012 {
1013     if (s->condexec_mask) {
1014         TCGContext *tcg_ctx = s->uc->tcg_ctx;
1015         uint32_t val = (s->condexec_cond << 4) | (s->condexec_mask >> 1);
1016         TCGv_i32 tmp = tcg_temp_new_i32(tcg_ctx);
1017         tcg_gen_movi_i32(tcg_ctx, tmp, val);
1018         store_cpu_field(tcg_ctx, tmp, condexec_bits);
1019     }
1020 }
1021 
gen_exception_internal_insn(DisasContext * s,int offset,int excp)1022 static void gen_exception_internal_insn(DisasContext *s, int offset, int excp)
1023 {
1024     gen_set_condexec(s);
1025     gen_set_pc_im(s, s->pc - offset);
1026     gen_exception_internal(s, excp);
1027     s->is_jmp = DISAS_JUMP;
1028 }
1029 
gen_exception_insn(DisasContext * s,int offset,int excp,int syn)1030 static void gen_exception_insn(DisasContext *s, int offset, int excp, int syn)
1031 {
1032     gen_set_condexec(s);
1033     gen_set_pc_im(s, s->pc - offset);
1034     gen_exception(s, excp, syn);   // qq
1035     s->is_jmp = DISAS_JUMP;
1036 }
1037 
1038 /* Force a TB lookup after an instruction that changes the CPU state.  */
gen_lookup_tb(DisasContext * s)1039 static inline void gen_lookup_tb(DisasContext *s)
1040 {
1041     TCGContext *tcg_ctx = s->uc->tcg_ctx;
1042     tcg_gen_movi_i32(tcg_ctx, tcg_ctx->cpu_R[15], s->pc & ~1);
1043     s->is_jmp = DISAS_UPDATE;
1044 }
1045 
gen_add_data_offset(DisasContext * s,unsigned int insn,TCGv_i32 var)1046 static inline void gen_add_data_offset(DisasContext *s, unsigned int insn,
1047                                        TCGv_i32 var)
1048 {
1049     TCGContext *tcg_ctx = s->uc->tcg_ctx;
1050     int val, rm, shift, shiftop;
1051     TCGv_i32 offset;
1052 
1053     if (!(insn & (1 << 25))) {
1054         /* immediate */
1055         val = insn & 0xfff;
1056         if (!(insn & (1 << 23)))
1057             val = -val;
1058         if (val != 0)
1059             tcg_gen_addi_i32(tcg_ctx, var, var, val);
1060     } else {
1061         /* shift/register */
1062         rm = (insn) & 0xf;
1063         shift = (insn >> 7) & 0x1f;
1064         shiftop = (insn >> 5) & 3;
1065         offset = load_reg(s, rm);
1066         gen_arm_shift_im(s, offset, shiftop, shift, 0);
1067         if (!(insn & (1 << 23)))
1068             tcg_gen_sub_i32(tcg_ctx, var, var, offset);
1069         else
1070             tcg_gen_add_i32(tcg_ctx, var, var, offset);
1071         tcg_temp_free_i32(tcg_ctx, offset);
1072     }
1073 }
1074 
gen_add_datah_offset(DisasContext * s,unsigned int insn,int extra,TCGv_i32 var)1075 static inline void gen_add_datah_offset(DisasContext *s, unsigned int insn,
1076                                         int extra, TCGv_i32 var)
1077 {
1078     TCGContext *tcg_ctx = s->uc->tcg_ctx;
1079     int val, rm;
1080     TCGv_i32 offset;
1081 
1082     if (insn & (1 << 22)) {
1083         /* immediate */
1084         val = (insn & 0xf) | ((insn >> 4) & 0xf0);
1085         if (!(insn & (1 << 23)))
1086             val = -val;
1087         val += extra;
1088         if (val != 0)
1089             tcg_gen_addi_i32(tcg_ctx, var, var, val);
1090     } else {
1091         /* register */
1092         if (extra)
1093             tcg_gen_addi_i32(tcg_ctx, var, var, extra);
1094         rm = (insn) & 0xf;
1095         offset = load_reg(s, rm);
1096         if (!(insn & (1 << 23)))
1097             tcg_gen_sub_i32(tcg_ctx, var, var, offset);
1098         else
1099             tcg_gen_add_i32(tcg_ctx, var, var, offset);
1100         tcg_temp_free_i32(tcg_ctx, offset);
1101     }
1102 }
1103 
get_fpstatus_ptr(DisasContext * s,int neon)1104 static TCGv_ptr get_fpstatus_ptr(DisasContext *s, int neon)
1105 {
1106     TCGContext *tcg_ctx = s->uc->tcg_ctx;
1107     TCGv_ptr statusptr = tcg_temp_new_ptr(tcg_ctx);
1108     int offset;
1109     if (neon) {
1110         offset = offsetof(CPUARMState, vfp.standard_fp_status);
1111     } else {
1112         offset = offsetof(CPUARMState, vfp.fp_status);
1113     }
1114     tcg_gen_addi_ptr(tcg_ctx, statusptr, tcg_ctx->cpu_env, offset);
1115     return statusptr;
1116 }
1117 
1118 #define VFP_OP2(name)                                                 \
1119 static inline void gen_vfp_##name(DisasContext *s, int dp)                             \
1120 {                                                                     \
1121     TCGContext *tcg_ctx = s->uc->tcg_ctx; \
1122     TCGv_ptr fpst = get_fpstatus_ptr(s, 0);                              \
1123     if (dp) {                                                         \
1124         gen_helper_vfp_##name##d(tcg_ctx, tcg_ctx->cpu_F0d, tcg_ctx->cpu_F0d, tcg_ctx->cpu_F1d, fpst);    \
1125     } else {                                                          \
1126         gen_helper_vfp_##name##s(tcg_ctx, tcg_ctx->cpu_F0s, tcg_ctx->cpu_F0s, tcg_ctx->cpu_F1s, fpst);    \
1127     }                                                                 \
1128     tcg_temp_free_ptr(tcg_ctx, fpst);                                          \
1129 }
1130 
1131 VFP_OP2(add)
VFP_OP2(sub)1132 VFP_OP2(sub)
1133 VFP_OP2(mul)
1134 VFP_OP2(div)
1135 
1136 #undef VFP_OP2
1137 
1138 static inline void gen_vfp_F1_mul(DisasContext *s, int dp)
1139 {
1140     TCGContext *tcg_ctx = s->uc->tcg_ctx;
1141     /* Like gen_vfp_mul() but put result in F1 */
1142     TCGv_ptr fpst = get_fpstatus_ptr(s, 0);
1143     if (dp) {
1144         gen_helper_vfp_muld(tcg_ctx, tcg_ctx->cpu_F1d, tcg_ctx->cpu_F0d, tcg_ctx->cpu_F1d, fpst);
1145     } else {
1146         gen_helper_vfp_muls(tcg_ctx, tcg_ctx->cpu_F1s, tcg_ctx->cpu_F0s, tcg_ctx->cpu_F1s, fpst);
1147     }
1148     tcg_temp_free_ptr(tcg_ctx, fpst);
1149 }
1150 
gen_vfp_F1_neg(DisasContext * s,int dp)1151 static inline void gen_vfp_F1_neg(DisasContext *s, int dp)
1152 {
1153     TCGContext *tcg_ctx = s->uc->tcg_ctx;
1154     /* Like gen_vfp_neg() but put result in F1 */
1155     if (dp) {
1156         gen_helper_vfp_negd(tcg_ctx, tcg_ctx->cpu_F1d, tcg_ctx->cpu_F0d);
1157     } else {
1158         gen_helper_vfp_negs(tcg_ctx, tcg_ctx->cpu_F1s, tcg_ctx->cpu_F0s);
1159     }
1160 }
1161 
gen_vfp_abs(DisasContext * s,int dp)1162 static inline void gen_vfp_abs(DisasContext *s, int dp)
1163 {
1164     TCGContext *tcg_ctx = s->uc->tcg_ctx;
1165     if (dp)
1166         gen_helper_vfp_absd(tcg_ctx, tcg_ctx->cpu_F0d, tcg_ctx->cpu_F0d);
1167     else
1168         gen_helper_vfp_abss(tcg_ctx, tcg_ctx->cpu_F0s, tcg_ctx->cpu_F0s);
1169 }
1170 
gen_vfp_neg(DisasContext * s,int dp)1171 static inline void gen_vfp_neg(DisasContext *s, int dp)
1172 {
1173     TCGContext *tcg_ctx = s->uc->tcg_ctx;
1174     if (dp)
1175         gen_helper_vfp_negd(tcg_ctx, tcg_ctx->cpu_F0d, tcg_ctx->cpu_F0d);
1176     else
1177         gen_helper_vfp_negs(tcg_ctx, tcg_ctx->cpu_F0s, tcg_ctx->cpu_F0s);
1178 }
1179 
gen_vfp_sqrt(DisasContext * s,int dp)1180 static inline void gen_vfp_sqrt(DisasContext *s, int dp)
1181 {
1182     TCGContext *tcg_ctx = s->uc->tcg_ctx;
1183     if (dp)
1184         gen_helper_vfp_sqrtd(tcg_ctx, tcg_ctx->cpu_F0d, tcg_ctx->cpu_F0d, tcg_ctx->cpu_env);
1185     else
1186         gen_helper_vfp_sqrts(tcg_ctx, tcg_ctx->cpu_F0s, tcg_ctx->cpu_F0s, tcg_ctx->cpu_env);
1187 }
1188 
gen_vfp_cmp(DisasContext * s,int dp)1189 static inline void gen_vfp_cmp(DisasContext *s, int dp)
1190 {
1191     TCGContext *tcg_ctx = s->uc->tcg_ctx;
1192     if (dp)
1193         gen_helper_vfp_cmpd(tcg_ctx, tcg_ctx->cpu_F0d, tcg_ctx->cpu_F1d, tcg_ctx->cpu_env);
1194     else
1195         gen_helper_vfp_cmps(tcg_ctx, tcg_ctx->cpu_F0s, tcg_ctx->cpu_F1s, tcg_ctx->cpu_env);
1196 }
1197 
gen_vfp_cmpe(DisasContext * s,int dp)1198 static inline void gen_vfp_cmpe(DisasContext *s, int dp)
1199 {
1200     TCGContext *tcg_ctx = s->uc->tcg_ctx;
1201     if (dp)
1202         gen_helper_vfp_cmped(tcg_ctx, tcg_ctx->cpu_F0d, tcg_ctx->cpu_F1d, tcg_ctx->cpu_env);
1203     else
1204         gen_helper_vfp_cmpes(tcg_ctx, tcg_ctx->cpu_F0s, tcg_ctx->cpu_F1s, tcg_ctx->cpu_env);
1205 }
1206 
gen_vfp_F1_ld0(DisasContext * s,int dp)1207 static inline void gen_vfp_F1_ld0(DisasContext *s, int dp)
1208 {
1209     TCGContext *tcg_ctx = s->uc->tcg_ctx;
1210     if (dp)
1211         tcg_gen_movi_i64(tcg_ctx, tcg_ctx->cpu_F1d, 0);
1212     else
1213         tcg_gen_movi_i32(tcg_ctx, tcg_ctx->cpu_F1s, 0);
1214 }
1215 
1216 #define VFP_GEN_ITOF(name) \
1217 static inline void gen_vfp_##name(DisasContext *s, int dp, int neon) \
1218 { \
1219     TCGContext *tcg_ctx = s->uc->tcg_ctx; \
1220     TCGv_ptr statusptr = get_fpstatus_ptr(s, neon); \
1221     if (dp) { \
1222         gen_helper_vfp_##name##d(tcg_ctx, tcg_ctx->cpu_F0d, tcg_ctx->cpu_F0s, statusptr); \
1223     } else { \
1224         gen_helper_vfp_##name##s(tcg_ctx, tcg_ctx->cpu_F0s, tcg_ctx->cpu_F0s, statusptr); \
1225     } \
1226     tcg_temp_free_ptr(tcg_ctx, statusptr); \
1227 }
1228 
1229 VFP_GEN_ITOF(uito)
VFP_GEN_ITOF(sito)1230 VFP_GEN_ITOF(sito)
1231 #undef VFP_GEN_ITOF
1232 
1233 #define VFP_GEN_FTOI(name) \
1234 static inline void gen_vfp_##name(DisasContext *s, int dp, int neon) \
1235 { \
1236     TCGContext *tcg_ctx = s->uc->tcg_ctx; \
1237     TCGv_ptr statusptr = get_fpstatus_ptr(s, neon); \
1238     if (dp) { \
1239         gen_helper_vfp_##name##d(tcg_ctx, tcg_ctx->cpu_F0s, tcg_ctx->cpu_F0d, statusptr); \
1240     } else { \
1241         gen_helper_vfp_##name##s(tcg_ctx, tcg_ctx->cpu_F0s, tcg_ctx->cpu_F0s, statusptr); \
1242     } \
1243     tcg_temp_free_ptr(tcg_ctx, statusptr); \
1244 }
1245 
1246 VFP_GEN_FTOI(toui)
1247 VFP_GEN_FTOI(touiz)
1248 VFP_GEN_FTOI(tosi)
1249 VFP_GEN_FTOI(tosiz)
1250 #undef VFP_GEN_FTOI
1251 
1252 #define VFP_GEN_FIX(name, round) \
1253 static inline void gen_vfp_##name(DisasContext *s, int dp, int shift, int neon) \
1254 { \
1255     TCGContext *tcg_ctx = s->uc->tcg_ctx; \
1256     TCGv_i32 tmp_shift = tcg_const_i32(tcg_ctx, shift); \
1257     TCGv_ptr statusptr = get_fpstatus_ptr(s, neon); \
1258     if (dp) { \
1259         gen_helper_vfp_##name##d##round(tcg_ctx, tcg_ctx->cpu_F0d, tcg_ctx->cpu_F0d, tmp_shift, \
1260                                         statusptr); \
1261     } else { \
1262         gen_helper_vfp_##name##s##round(tcg_ctx, tcg_ctx->cpu_F0s, tcg_ctx->cpu_F0s, tmp_shift, \
1263                                         statusptr); \
1264     } \
1265     tcg_temp_free_i32(tcg_ctx, tmp_shift); \
1266     tcg_temp_free_ptr(tcg_ctx, statusptr); \
1267 }
1268 VFP_GEN_FIX(tosh, _round_to_zero)
1269 VFP_GEN_FIX(tosl, _round_to_zero)
1270 VFP_GEN_FIX(touh, _round_to_zero)
1271 VFP_GEN_FIX(toul, _round_to_zero)
1272 VFP_GEN_FIX(shto, )
1273 VFP_GEN_FIX(slto, )
1274 VFP_GEN_FIX(uhto, )
1275 VFP_GEN_FIX(ulto, )
1276 #undef VFP_GEN_FIX
1277 
1278 static inline void gen_vfp_ld(DisasContext *s, int dp, TCGv_i32 addr)
1279 {
1280     TCGContext *tcg_ctx = s->uc->tcg_ctx;
1281     if (dp) {
1282         gen_aa32_ld64(s, tcg_ctx->cpu_F0d, addr, get_mem_index(s));
1283     } else {
1284         gen_aa32_ld32u(s, tcg_ctx->cpu_F0s, addr, get_mem_index(s));
1285     }
1286 }
1287 
gen_vfp_st(DisasContext * s,int dp,TCGv_i32 addr)1288 static inline void gen_vfp_st(DisasContext *s, int dp, TCGv_i32 addr)
1289 {
1290     TCGContext *tcg_ctx = s->uc->tcg_ctx;
1291     if (dp) {
1292         gen_aa32_st64(s, tcg_ctx->cpu_F0d, addr, get_mem_index(s));
1293     } else {
1294         gen_aa32_st32(s, tcg_ctx->cpu_F0s, addr, get_mem_index(s));
1295     }
1296 }
1297 
1298 static inline long
vfp_reg_offset(int dp,int reg)1299 vfp_reg_offset (int dp, int reg)
1300 {
1301     if (dp)
1302         return offsetof(CPUARMState, vfp.regs[reg]);
1303     else if (reg & 1) {
1304         return offsetof(CPUARMState, vfp.regs[reg >> 1])
1305           + offsetof(CPU_DoubleU, l.upper);
1306     } else {
1307         return offsetof(CPUARMState, vfp.regs[reg >> 1])
1308           + offsetof(CPU_DoubleU, l.lower);
1309     }
1310 }
1311 
1312 /* Return the offset of a 32-bit piece of a NEON register.
1313    zero is the least significant end of the register.  */
1314 static inline long
neon_reg_offset(int reg,int n)1315 neon_reg_offset (int reg, int n)
1316 {
1317     int sreg;
1318     sreg = reg * 2 + n;
1319     return vfp_reg_offset(0, sreg);
1320 }
1321 
neon_load_reg(TCGContext * tcg_ctx,int reg,int pass)1322 static TCGv_i32 neon_load_reg(TCGContext *tcg_ctx, int reg, int pass)
1323 {
1324     TCGv_i32 tmp = tcg_temp_new_i32(tcg_ctx);
1325     tcg_gen_ld_i32(tcg_ctx, tmp, tcg_ctx->cpu_env, neon_reg_offset(reg, pass));
1326     return tmp;
1327 }
1328 
neon_store_reg(TCGContext * tcg_ctx,int reg,int pass,TCGv_i32 var)1329 static void neon_store_reg(TCGContext *tcg_ctx, int reg, int pass, TCGv_i32 var)
1330 {
1331     tcg_gen_st_i32(tcg_ctx, var, tcg_ctx->cpu_env, neon_reg_offset(reg, pass));
1332     tcg_temp_free_i32(tcg_ctx, var);
1333 }
1334 
neon_load_reg64(TCGContext * tcg_ctx,TCGv_i64 var,int reg)1335 static inline void neon_load_reg64(TCGContext *tcg_ctx, TCGv_i64 var, int reg)
1336 {
1337     tcg_gen_ld_i64(tcg_ctx, var, tcg_ctx->cpu_env, vfp_reg_offset(1, reg));
1338 }
1339 
neon_store_reg64(TCGContext * tcg_ctx,TCGv_i64 var,int reg)1340 static inline void neon_store_reg64(TCGContext *tcg_ctx, TCGv_i64 var, int reg)
1341 {
1342     tcg_gen_st_i64(tcg_ctx, var, tcg_ctx->cpu_env, vfp_reg_offset(1, reg));
1343 }
1344 
1345 #define tcg_gen_ld_f32 tcg_gen_ld_i32
1346 #define tcg_gen_ld_f64 tcg_gen_ld_i64
1347 #define tcg_gen_st_f32 tcg_gen_st_i32
1348 #define tcg_gen_st_f64 tcg_gen_st_i64
1349 
gen_mov_F0_vreg(DisasContext * s,int dp,int reg)1350 static inline void gen_mov_F0_vreg(DisasContext *s, int dp, int reg)
1351 {
1352     TCGContext *tcg_ctx = s->uc->tcg_ctx;
1353     if (dp)
1354         tcg_gen_ld_f64(tcg_ctx, tcg_ctx->cpu_F0d, tcg_ctx->cpu_env, vfp_reg_offset(dp, reg));
1355     else
1356         tcg_gen_ld_f32(tcg_ctx, tcg_ctx->cpu_F0s, tcg_ctx->cpu_env, vfp_reg_offset(dp, reg));
1357 }
1358 
gen_mov_F1_vreg(DisasContext * s,int dp,int reg)1359 static inline void gen_mov_F1_vreg(DisasContext *s, int dp, int reg)
1360 {
1361     TCGContext *tcg_ctx = s->uc->tcg_ctx;
1362     if (dp)
1363         tcg_gen_ld_f64(tcg_ctx, tcg_ctx->cpu_F1d, tcg_ctx->cpu_env, vfp_reg_offset(dp, reg));
1364     else
1365         tcg_gen_ld_f32(tcg_ctx, tcg_ctx->cpu_F1s, tcg_ctx->cpu_env, vfp_reg_offset(dp, reg));
1366 }
1367 
gen_mov_vreg_F0(DisasContext * s,int dp,int reg)1368 static inline void gen_mov_vreg_F0(DisasContext *s, int dp, int reg)
1369 {
1370     TCGContext *tcg_ctx = s->uc->tcg_ctx;
1371     if (dp)
1372         tcg_gen_st_f64(tcg_ctx, tcg_ctx->cpu_F0d, tcg_ctx->cpu_env, vfp_reg_offset(dp, reg));
1373     else
1374         tcg_gen_st_f32(tcg_ctx, tcg_ctx->cpu_F0s, tcg_ctx->cpu_env, vfp_reg_offset(dp, reg));
1375 }
1376 
1377 #define ARM_CP_RW_BIT   (1 << 20)
1378 
iwmmxt_load_reg(DisasContext * s,TCGv_i64 var,int reg)1379 static inline void iwmmxt_load_reg(DisasContext *s, TCGv_i64 var, int reg)
1380 {
1381     TCGContext *tcg_ctx = s->uc->tcg_ctx;
1382     tcg_gen_ld_i64(tcg_ctx, var, tcg_ctx->cpu_env, offsetof(CPUARMState, iwmmxt.regs[reg]));
1383 }
1384 
iwmmxt_store_reg(DisasContext * s,TCGv_i64 var,int reg)1385 static inline void iwmmxt_store_reg(DisasContext *s, TCGv_i64 var, int reg)
1386 {
1387     TCGContext *tcg_ctx = s->uc->tcg_ctx;
1388     tcg_gen_st_i64(tcg_ctx, var, tcg_ctx->cpu_env, offsetof(CPUARMState, iwmmxt.regs[reg]));
1389 }
1390 
iwmmxt_load_creg(DisasContext * s,int reg)1391 static inline TCGv_i32 iwmmxt_load_creg(DisasContext *s, int reg)
1392 {
1393     TCGContext *tcg_ctx = s->uc->tcg_ctx;
1394     TCGv_i32 var = tcg_temp_new_i32(tcg_ctx);
1395     tcg_gen_ld_i32(tcg_ctx, var, tcg_ctx->cpu_env, offsetof(CPUARMState, iwmmxt.cregs[reg]));
1396     return var;
1397 }
1398 
iwmmxt_store_creg(DisasContext * s,int reg,TCGv_i32 var)1399 static inline void iwmmxt_store_creg(DisasContext *s, int reg, TCGv_i32 var)
1400 {
1401     TCGContext *tcg_ctx = s->uc->tcg_ctx;
1402     tcg_gen_st_i32(tcg_ctx, var, tcg_ctx->cpu_env, offsetof(CPUARMState, iwmmxt.cregs[reg]));
1403     tcg_temp_free_i32(tcg_ctx, var);
1404 }
1405 
gen_op_iwmmxt_movq_wRn_M0(DisasContext * s,int rn)1406 static inline void gen_op_iwmmxt_movq_wRn_M0(DisasContext *s, int rn)
1407 {
1408     TCGContext *tcg_ctx = s->uc->tcg_ctx;
1409     iwmmxt_store_reg(s, tcg_ctx->cpu_M0, rn);
1410 }
1411 
gen_op_iwmmxt_movq_M0_wRn(DisasContext * s,int rn)1412 static inline void gen_op_iwmmxt_movq_M0_wRn(DisasContext *s, int rn)
1413 {
1414     TCGContext *tcg_ctx = s->uc->tcg_ctx;
1415     iwmmxt_load_reg(s, tcg_ctx->cpu_M0, rn);
1416 }
1417 
gen_op_iwmmxt_orq_M0_wRn(DisasContext * s,int rn)1418 static inline void gen_op_iwmmxt_orq_M0_wRn(DisasContext *s, int rn)
1419 {
1420     TCGContext *tcg_ctx = s->uc->tcg_ctx;
1421     iwmmxt_load_reg(s, tcg_ctx->cpu_V1, rn);
1422     tcg_gen_or_i64(tcg_ctx, tcg_ctx->cpu_M0, tcg_ctx->cpu_M0, tcg_ctx->cpu_V1);
1423 }
1424 
gen_op_iwmmxt_andq_M0_wRn(DisasContext * s,int rn)1425 static inline void gen_op_iwmmxt_andq_M0_wRn(DisasContext *s, int rn)
1426 {
1427     TCGContext *tcg_ctx = s->uc->tcg_ctx;
1428     iwmmxt_load_reg(s, tcg_ctx->cpu_V1, rn);
1429     tcg_gen_and_i64(tcg_ctx, tcg_ctx->cpu_M0, tcg_ctx->cpu_M0, tcg_ctx->cpu_V1);
1430 }
1431 
gen_op_iwmmxt_xorq_M0_wRn(DisasContext * s,int rn)1432 static inline void gen_op_iwmmxt_xorq_M0_wRn(DisasContext *s, int rn)
1433 {
1434     TCGContext *tcg_ctx = s->uc->tcg_ctx;
1435     iwmmxt_load_reg(s, tcg_ctx->cpu_V1, rn);
1436     tcg_gen_xor_i64(tcg_ctx, tcg_ctx->cpu_M0, tcg_ctx->cpu_M0, tcg_ctx->cpu_V1);
1437 }
1438 
1439 #define IWMMXT_OP(name) \
1440 static inline void gen_op_iwmmxt_##name##_M0_wRn(DisasContext *s, int rn) \
1441 { \
1442     TCGContext *tcg_ctx = s->uc->tcg_ctx; \
1443     iwmmxt_load_reg(s, tcg_ctx->cpu_V1, rn); \
1444     gen_helper_iwmmxt_##name(tcg_ctx, tcg_ctx->cpu_M0, tcg_ctx->cpu_M0, tcg_ctx->cpu_V1); \
1445 }
1446 
1447 #define IWMMXT_OP_ENV(name) \
1448 static inline void gen_op_iwmmxt_##name##_M0_wRn(DisasContext *s, int rn) \
1449 { \
1450     TCGContext *tcg_ctx = s->uc->tcg_ctx; \
1451     iwmmxt_load_reg(s, tcg_ctx->cpu_V1, rn); \
1452     gen_helper_iwmmxt_##name(tcg_ctx, tcg_ctx->cpu_M0, tcg_ctx->cpu_env, tcg_ctx->cpu_M0, tcg_ctx->cpu_V1); \
1453 }
1454 
1455 #define IWMMXT_OP_ENV_SIZE(name) \
1456 IWMMXT_OP_ENV(name##b) \
1457 IWMMXT_OP_ENV(name##w) \
1458 IWMMXT_OP_ENV(name##l)
1459 
1460 #define IWMMXT_OP_ENV1(name) \
1461 static inline void gen_op_iwmmxt_##name##_M0(DisasContext *s) \
1462 { \
1463     TCGContext *tcg_ctx = s->uc->tcg_ctx; \
1464     gen_helper_iwmmxt_##name(tcg_ctx, tcg_ctx->cpu_M0, tcg_ctx->cpu_env, tcg_ctx->cpu_M0); \
1465 }
1466 
1467 IWMMXT_OP(maddsq)
IWMMXT_OP(madduq)1468 IWMMXT_OP(madduq)
1469 IWMMXT_OP(sadb)
1470 IWMMXT_OP(sadw)
1471 IWMMXT_OP(mulslw)
1472 IWMMXT_OP(mulshw)
1473 IWMMXT_OP(mululw)
1474 IWMMXT_OP(muluhw)
1475 IWMMXT_OP(macsw)
1476 IWMMXT_OP(macuw)
1477 
1478 IWMMXT_OP_ENV_SIZE(unpackl)
1479 IWMMXT_OP_ENV_SIZE(unpackh)
1480 
1481 IWMMXT_OP_ENV1(unpacklub)
1482 IWMMXT_OP_ENV1(unpackluw)
1483 IWMMXT_OP_ENV1(unpacklul)
1484 IWMMXT_OP_ENV1(unpackhub)
1485 IWMMXT_OP_ENV1(unpackhuw)
1486 IWMMXT_OP_ENV1(unpackhul)
1487 IWMMXT_OP_ENV1(unpacklsb)
1488 IWMMXT_OP_ENV1(unpacklsw)
1489 IWMMXT_OP_ENV1(unpacklsl)
1490 IWMMXT_OP_ENV1(unpackhsb)
1491 IWMMXT_OP_ENV1(unpackhsw)
1492 IWMMXT_OP_ENV1(unpackhsl)
1493 
1494 IWMMXT_OP_ENV_SIZE(cmpeq)
1495 IWMMXT_OP_ENV_SIZE(cmpgtu)
1496 IWMMXT_OP_ENV_SIZE(cmpgts)
1497 
1498 IWMMXT_OP_ENV_SIZE(mins)
1499 IWMMXT_OP_ENV_SIZE(minu)
1500 IWMMXT_OP_ENV_SIZE(maxs)
1501 IWMMXT_OP_ENV_SIZE(maxu)
1502 
1503 IWMMXT_OP_ENV_SIZE(subn)
1504 IWMMXT_OP_ENV_SIZE(addn)
1505 IWMMXT_OP_ENV_SIZE(subu)
1506 IWMMXT_OP_ENV_SIZE(addu)
1507 IWMMXT_OP_ENV_SIZE(subs)
1508 IWMMXT_OP_ENV_SIZE(adds)
1509 
1510 IWMMXT_OP_ENV(avgb0)
1511 IWMMXT_OP_ENV(avgb1)
1512 IWMMXT_OP_ENV(avgw0)
1513 IWMMXT_OP_ENV(avgw1)
1514 
1515 IWMMXT_OP_ENV(packuw)
1516 IWMMXT_OP_ENV(packul)
1517 IWMMXT_OP_ENV(packuq)
1518 IWMMXT_OP_ENV(packsw)
1519 IWMMXT_OP_ENV(packsl)
1520 IWMMXT_OP_ENV(packsq)
1521 
1522 static void gen_op_iwmmxt_set_mup(DisasContext *s)
1523 {
1524     TCGContext *tcg_ctx = s->uc->tcg_ctx;
1525     TCGv_i32 tmp;
1526     tmp = load_cpu_field(s->uc, iwmmxt.cregs[ARM_IWMMXT_wCon]);
1527     tcg_gen_ori_i32(tcg_ctx, tmp, tmp, 2);
1528     store_cpu_field(tcg_ctx, tmp, iwmmxt.cregs[ARM_IWMMXT_wCon]);
1529 }
1530 
gen_op_iwmmxt_set_cup(DisasContext * s)1531 static void gen_op_iwmmxt_set_cup(DisasContext *s)
1532 {
1533     TCGContext *tcg_ctx = s->uc->tcg_ctx;
1534     TCGv_i32 tmp;
1535     tmp = load_cpu_field(s->uc, iwmmxt.cregs[ARM_IWMMXT_wCon]);
1536     tcg_gen_ori_i32(tcg_ctx, tmp, tmp, 1);
1537     store_cpu_field(tcg_ctx, tmp, iwmmxt.cregs[ARM_IWMMXT_wCon]);
1538 }
1539 
gen_op_iwmmxt_setpsr_nz(DisasContext * s)1540 static void gen_op_iwmmxt_setpsr_nz(DisasContext *s)
1541 {
1542     TCGContext *tcg_ctx = s->uc->tcg_ctx;
1543     TCGv_i32 tmp = tcg_temp_new_i32(tcg_ctx);
1544     gen_helper_iwmmxt_setpsr_nz(tcg_ctx, tmp, tcg_ctx->cpu_M0);
1545     store_cpu_field(tcg_ctx, tmp, iwmmxt.cregs[ARM_IWMMXT_wCASF]);
1546 }
1547 
gen_op_iwmmxt_addl_M0_wRn(DisasContext * s,int rn)1548 static inline void gen_op_iwmmxt_addl_M0_wRn(DisasContext *s, int rn)
1549 {
1550     TCGContext *tcg_ctx = s->uc->tcg_ctx;
1551     iwmmxt_load_reg(s, tcg_ctx->cpu_V1, rn);
1552     tcg_gen_ext32u_i64(tcg_ctx, tcg_ctx->cpu_V1, tcg_ctx->cpu_V1);
1553     tcg_gen_add_i64(tcg_ctx, tcg_ctx->cpu_M0, tcg_ctx->cpu_M0, tcg_ctx->cpu_V1);
1554 }
1555 
gen_iwmmxt_address(DisasContext * s,uint32_t insn,TCGv_i32 dest)1556 static inline int gen_iwmmxt_address(DisasContext *s, uint32_t insn,
1557                                      TCGv_i32 dest)
1558 {
1559     TCGContext *tcg_ctx = s->uc->tcg_ctx;
1560     int rd;
1561     uint32_t offset;
1562     TCGv_i32 tmp;
1563 
1564     rd = (insn >> 16) & 0xf;
1565     tmp = load_reg(s, rd);
1566 
1567     offset = (insn & 0xff) << ((insn >> 7) & 2);
1568     if (insn & (1 << 24)) {
1569         /* Pre indexed */
1570         if (insn & (1 << 23))
1571             tcg_gen_addi_i32(tcg_ctx, tmp, tmp, offset);
1572         else
1573             tcg_gen_addi_i32(tcg_ctx, tmp, tmp, 0-offset);
1574         tcg_gen_mov_i32(tcg_ctx, dest, tmp);
1575         if (insn & (1 << 21))
1576             store_reg(s, rd, tmp);
1577         else
1578             tcg_temp_free_i32(tcg_ctx, tmp);
1579     } else if (insn & (1 << 21)) {
1580         /* Post indexed */
1581         tcg_gen_mov_i32(tcg_ctx, dest, tmp);
1582         if (insn & (1 << 23))
1583             tcg_gen_addi_i32(tcg_ctx, tmp, tmp, offset);
1584         else
1585             tcg_gen_addi_i32(tcg_ctx, tmp, tmp, 0-offset);
1586         store_reg(s, rd, tmp);
1587     } else if (!(insn & (1 << 23)))
1588         return 1;
1589     return 0;
1590 }
1591 
gen_iwmmxt_shift(DisasContext * s,uint32_t insn,uint32_t mask,TCGv_i32 dest)1592 static inline int gen_iwmmxt_shift(DisasContext *s, uint32_t insn, uint32_t mask, TCGv_i32 dest)
1593 {
1594     TCGContext *tcg_ctx = s->uc->tcg_ctx;
1595     int rd = (insn >> 0) & 0xf;
1596     TCGv_i32 tmp;
1597 
1598     if (insn & (1 << 8)) {
1599         if (rd < ARM_IWMMXT_wCGR0 || rd > ARM_IWMMXT_wCGR3) {
1600             return 1;
1601         } else {
1602             tmp = iwmmxt_load_creg(s, rd);
1603         }
1604     } else {
1605         tmp = tcg_temp_new_i32(tcg_ctx);
1606         iwmmxt_load_reg(s, tcg_ctx->cpu_V0, rd);
1607         tcg_gen_trunc_i64_i32(tcg_ctx, tmp, tcg_ctx->cpu_V0);
1608     }
1609     tcg_gen_andi_i32(tcg_ctx, tmp, tmp, mask);
1610     tcg_gen_mov_i32(tcg_ctx, dest, tmp);
1611     tcg_temp_free_i32(tcg_ctx, tmp);
1612     return 0;
1613 }
1614 
1615 /* Disassemble an iwMMXt instruction.  Returns nonzero if an error occurred
1616    (ie. an undefined instruction).  */
disas_iwmmxt_insn(DisasContext * s,uint32_t insn)1617 static int disas_iwmmxt_insn(DisasContext *s, uint32_t insn)
1618 {
1619     TCGContext *tcg_ctx = s->uc->tcg_ctx;
1620     int rd, wrd;
1621     int rdhi, rdlo, rd0, rd1, i;
1622     TCGv_i32 addr;
1623     TCGv_i32 tmp, tmp2, tmp3;
1624 
1625     if ((insn & 0x0e000e00) == 0x0c000000) {
1626         if ((insn & 0x0fe00ff0) == 0x0c400000) {
1627             wrd = insn & 0xf;
1628             rdlo = (insn >> 12) & 0xf;
1629             rdhi = (insn >> 16) & 0xf;
1630             if (insn & ARM_CP_RW_BIT) {         /* TMRRC */
1631                 iwmmxt_load_reg(s, tcg_ctx->cpu_V0, wrd);
1632                 tcg_gen_trunc_i64_i32(tcg_ctx, tcg_ctx->cpu_R[rdlo], tcg_ctx->cpu_V0);
1633                 tcg_gen_shri_i64(tcg_ctx, tcg_ctx->cpu_V0, tcg_ctx->cpu_V0, 32);
1634                 tcg_gen_trunc_i64_i32(tcg_ctx, tcg_ctx->cpu_R[rdhi], tcg_ctx->cpu_V0);
1635             } else {                    /* TMCRR */
1636                 tcg_gen_concat_i32_i64(tcg_ctx, tcg_ctx->cpu_V0, tcg_ctx->cpu_R[rdlo], tcg_ctx->cpu_R[rdhi]);
1637                 iwmmxt_store_reg(s, tcg_ctx->cpu_V0, wrd);
1638                 gen_op_iwmmxt_set_mup(s);
1639             }
1640             return 0;
1641         }
1642 
1643         wrd = (insn >> 12) & 0xf;
1644         addr = tcg_temp_new_i32(tcg_ctx);
1645         if (gen_iwmmxt_address(s, insn, addr)) {
1646             tcg_temp_free_i32(tcg_ctx, addr);
1647             return 1;
1648         }
1649         if (insn & ARM_CP_RW_BIT) {
1650             if ((insn >> 28) == 0xf) {          /* WLDRW wCx */
1651                 tmp = tcg_temp_new_i32(tcg_ctx);
1652                 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
1653                 iwmmxt_store_creg(s, wrd, tmp);
1654             } else {
1655                 i = 1;
1656                 if (insn & (1 << 8)) {
1657                     if (insn & (1 << 22)) {     /* WLDRD */
1658                         gen_aa32_ld64(s, tcg_ctx->cpu_M0, addr, get_mem_index(s));
1659                         i = 0;
1660                     } else {                /* WLDRW wRd */
1661                         tmp = tcg_temp_new_i32(tcg_ctx);
1662                         gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
1663                     }
1664                 } else {
1665                     tmp = tcg_temp_new_i32(tcg_ctx);
1666                     if (insn & (1 << 22)) {     /* WLDRH */
1667                         gen_aa32_ld16u(s, tmp, addr, get_mem_index(s));
1668                     } else {                /* WLDRB */
1669                         gen_aa32_ld8u(s, tmp, addr, get_mem_index(s));
1670                     }
1671                 }
1672                 if (i) {
1673                     tcg_gen_extu_i32_i64(tcg_ctx, tcg_ctx->cpu_M0, tmp);
1674                     tcg_temp_free_i32(tcg_ctx, tmp);
1675                 }
1676                 gen_op_iwmmxt_movq_wRn_M0(s, wrd);
1677             }
1678         } else {
1679             if ((insn >> 28) == 0xf) {          /* WSTRW wCx */
1680                 tmp = iwmmxt_load_creg(s, wrd);
1681                 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
1682             } else {
1683                 gen_op_iwmmxt_movq_M0_wRn(s, wrd);
1684                 tmp = tcg_temp_new_i32(tcg_ctx);
1685                 if (insn & (1 << 8)) {
1686                     if (insn & (1 << 22)) {     /* WSTRD */
1687                         gen_aa32_st64(s, tcg_ctx->cpu_M0, addr, get_mem_index(s));
1688                     } else {                /* WSTRW wRd */
1689                         tcg_gen_trunc_i64_i32(tcg_ctx, tmp, tcg_ctx->cpu_M0);
1690                         gen_aa32_st32(s, tmp, addr, get_mem_index(s));
1691                     }
1692                 } else {
1693                     if (insn & (1 << 22)) {     /* WSTRH */
1694                         tcg_gen_trunc_i64_i32(tcg_ctx, tmp, tcg_ctx->cpu_M0);
1695                         gen_aa32_st16(s, tmp, addr, get_mem_index(s));
1696                     } else {                /* WSTRB */
1697                         tcg_gen_trunc_i64_i32(tcg_ctx, tmp, tcg_ctx->cpu_M0);
1698                         gen_aa32_st8(s, tmp, addr, get_mem_index(s));
1699                     }
1700                 }
1701             }
1702             tcg_temp_free_i32(tcg_ctx, tmp);
1703         }
1704         tcg_temp_free_i32(tcg_ctx, addr);
1705         return 0;
1706     }
1707 
1708     if ((insn & 0x0f000000) != 0x0e000000)
1709         return 1;
1710 
1711     switch (((insn >> 12) & 0xf00) | ((insn >> 4) & 0xff)) {
1712     case 0x000:                     /* WOR */
1713         wrd = (insn >> 12) & 0xf;
1714         rd0 = (insn >> 0) & 0xf;
1715         rd1 = (insn >> 16) & 0xf;
1716         gen_op_iwmmxt_movq_M0_wRn(s, rd0);
1717         gen_op_iwmmxt_orq_M0_wRn(s, rd1);
1718         gen_op_iwmmxt_setpsr_nz(s);
1719         gen_op_iwmmxt_movq_wRn_M0(s, wrd);
1720         gen_op_iwmmxt_set_mup(s);
1721         gen_op_iwmmxt_set_cup(s);
1722         break;
1723     case 0x011:                     /* TMCR */
1724         if (insn & 0xf)
1725             return 1;
1726         rd = (insn >> 12) & 0xf;
1727         wrd = (insn >> 16) & 0xf;
1728         switch (wrd) {
1729         case ARM_IWMMXT_wCID:
1730         case ARM_IWMMXT_wCASF:
1731             break;
1732         case ARM_IWMMXT_wCon:
1733             gen_op_iwmmxt_set_cup(s);
1734             /* Fall through.  */
1735         case ARM_IWMMXT_wCSSF:
1736             tmp = iwmmxt_load_creg(s, wrd);
1737             tmp2 = load_reg(s, rd);
1738             tcg_gen_andc_i32(tcg_ctx, tmp, tmp, tmp2);
1739             tcg_temp_free_i32(tcg_ctx, tmp2);
1740             iwmmxt_store_creg(s, wrd, tmp);
1741             break;
1742         case ARM_IWMMXT_wCGR0:
1743         case ARM_IWMMXT_wCGR1:
1744         case ARM_IWMMXT_wCGR2:
1745         case ARM_IWMMXT_wCGR3:
1746             gen_op_iwmmxt_set_cup(s);
1747             tmp = load_reg(s, rd);
1748             iwmmxt_store_creg(s, wrd, tmp);
1749             break;
1750         default:
1751             return 1;
1752         }
1753         break;
1754     case 0x100:                     /* WXOR */
1755         wrd = (insn >> 12) & 0xf;
1756         rd0 = (insn >> 0) & 0xf;
1757         rd1 = (insn >> 16) & 0xf;
1758         gen_op_iwmmxt_movq_M0_wRn(s, rd0);
1759         gen_op_iwmmxt_xorq_M0_wRn(s, rd1);
1760         gen_op_iwmmxt_setpsr_nz(s);
1761         gen_op_iwmmxt_movq_wRn_M0(s, wrd);
1762         gen_op_iwmmxt_set_mup(s);
1763         gen_op_iwmmxt_set_cup(s);
1764         break;
1765     case 0x111:                     /* TMRC */
1766         if (insn & 0xf)
1767             return 1;
1768         rd = (insn >> 12) & 0xf;
1769         wrd = (insn >> 16) & 0xf;
1770         tmp = iwmmxt_load_creg(s, wrd);
1771         store_reg(s, rd, tmp);
1772         break;
1773     case 0x300:                     /* WANDN */
1774         wrd = (insn >> 12) & 0xf;
1775         rd0 = (insn >> 0) & 0xf;
1776         rd1 = (insn >> 16) & 0xf;
1777         gen_op_iwmmxt_movq_M0_wRn(s, rd0);
1778         tcg_gen_neg_i64(tcg_ctx, tcg_ctx->cpu_M0, tcg_ctx->cpu_M0);
1779         gen_op_iwmmxt_andq_M0_wRn(s, rd1);
1780         gen_op_iwmmxt_setpsr_nz(s);
1781         gen_op_iwmmxt_movq_wRn_M0(s, wrd);
1782         gen_op_iwmmxt_set_mup(s);
1783         gen_op_iwmmxt_set_cup(s);
1784         break;
1785     case 0x200:                     /* WAND */
1786         wrd = (insn >> 12) & 0xf;
1787         rd0 = (insn >> 0) & 0xf;
1788         rd1 = (insn >> 16) & 0xf;
1789         gen_op_iwmmxt_movq_M0_wRn(s, rd0);
1790         gen_op_iwmmxt_andq_M0_wRn(s, rd1);
1791         gen_op_iwmmxt_setpsr_nz(s);
1792         gen_op_iwmmxt_movq_wRn_M0(s, wrd);
1793         gen_op_iwmmxt_set_mup(s);
1794         gen_op_iwmmxt_set_cup(s);
1795         break;
1796     case 0x810: case 0xa10:             /* WMADD */
1797         wrd = (insn >> 12) & 0xf;
1798         rd0 = (insn >> 0) & 0xf;
1799         rd1 = (insn >> 16) & 0xf;
1800         gen_op_iwmmxt_movq_M0_wRn(s, rd0);
1801         if (insn & (1 << 21))
1802             gen_op_iwmmxt_maddsq_M0_wRn(s, rd1);
1803         else
1804             gen_op_iwmmxt_madduq_M0_wRn(s, rd1);
1805         gen_op_iwmmxt_movq_wRn_M0(s, wrd);
1806         gen_op_iwmmxt_set_mup(s);
1807         break;
1808     case 0x10e: case 0x50e: case 0x90e: case 0xd0e: /* WUNPCKIL */
1809         wrd = (insn >> 12) & 0xf;
1810         rd0 = (insn >> 16) & 0xf;
1811         rd1 = (insn >> 0) & 0xf;
1812         gen_op_iwmmxt_movq_M0_wRn(s, rd0);
1813         switch ((insn >> 22) & 3) {
1814         case 0:
1815             gen_op_iwmmxt_unpacklb_M0_wRn(s, rd1);
1816             break;
1817         case 1:
1818             gen_op_iwmmxt_unpacklw_M0_wRn(s, rd1);
1819             break;
1820         case 2:
1821             gen_op_iwmmxt_unpackll_M0_wRn(s, rd1);
1822             break;
1823         case 3:
1824             return 1;
1825         }
1826         gen_op_iwmmxt_movq_wRn_M0(s, wrd);
1827         gen_op_iwmmxt_set_mup(s);
1828         gen_op_iwmmxt_set_cup(s);
1829         break;
1830     case 0x10c: case 0x50c: case 0x90c: case 0xd0c: /* WUNPCKIH */
1831         wrd = (insn >> 12) & 0xf;
1832         rd0 = (insn >> 16) & 0xf;
1833         rd1 = (insn >> 0) & 0xf;
1834         gen_op_iwmmxt_movq_M0_wRn(s, rd0);
1835         switch ((insn >> 22) & 3) {
1836         case 0:
1837             gen_op_iwmmxt_unpackhb_M0_wRn(s, rd1);
1838             break;
1839         case 1:
1840             gen_op_iwmmxt_unpackhw_M0_wRn(s, rd1);
1841             break;
1842         case 2:
1843             gen_op_iwmmxt_unpackhl_M0_wRn(s, rd1);
1844             break;
1845         case 3:
1846             return 1;
1847         }
1848         gen_op_iwmmxt_movq_wRn_M0(s, wrd);
1849         gen_op_iwmmxt_set_mup(s);
1850         gen_op_iwmmxt_set_cup(s);
1851         break;
1852     case 0x012: case 0x112: case 0x412: case 0x512: /* WSAD */
1853         wrd = (insn >> 12) & 0xf;
1854         rd0 = (insn >> 16) & 0xf;
1855         rd1 = (insn >> 0) & 0xf;
1856         gen_op_iwmmxt_movq_M0_wRn(s, rd0);
1857         if (insn & (1 << 22))
1858             gen_op_iwmmxt_sadw_M0_wRn(s, rd1);
1859         else
1860             gen_op_iwmmxt_sadb_M0_wRn(s, rd1);
1861         if (!(insn & (1 << 20)))
1862             gen_op_iwmmxt_addl_M0_wRn(s, wrd);
1863         gen_op_iwmmxt_movq_wRn_M0(s, wrd);
1864         gen_op_iwmmxt_set_mup(s);
1865         break;
1866     case 0x010: case 0x110: case 0x210: case 0x310: /* WMUL */
1867         wrd = (insn >> 12) & 0xf;
1868         rd0 = (insn >> 16) & 0xf;
1869         rd1 = (insn >> 0) & 0xf;
1870         gen_op_iwmmxt_movq_M0_wRn(s, rd0);
1871         if (insn & (1 << 21)) {
1872             if (insn & (1 << 20))
1873                 gen_op_iwmmxt_mulshw_M0_wRn(s, rd1);
1874             else
1875                 gen_op_iwmmxt_mulslw_M0_wRn(s, rd1);
1876         } else {
1877             if (insn & (1 << 20))
1878                 gen_op_iwmmxt_muluhw_M0_wRn(s, rd1);
1879             else
1880                 gen_op_iwmmxt_mululw_M0_wRn(s, rd1);
1881         }
1882         gen_op_iwmmxt_movq_wRn_M0(s, wrd);
1883         gen_op_iwmmxt_set_mup(s);
1884         break;
1885     case 0x410: case 0x510: case 0x610: case 0x710: /* WMAC */
1886         wrd = (insn >> 12) & 0xf;
1887         rd0 = (insn >> 16) & 0xf;
1888         rd1 = (insn >> 0) & 0xf;
1889         gen_op_iwmmxt_movq_M0_wRn(s, rd0);
1890         if (insn & (1 << 21))
1891             gen_op_iwmmxt_macsw_M0_wRn(s, rd1);
1892         else
1893             gen_op_iwmmxt_macuw_M0_wRn(s, rd1);
1894         if (!(insn & (1 << 20))) {
1895             iwmmxt_load_reg(s, tcg_ctx->cpu_V1, wrd);
1896             tcg_gen_add_i64(tcg_ctx, tcg_ctx->cpu_M0, tcg_ctx->cpu_M0, tcg_ctx->cpu_V1);
1897         }
1898         gen_op_iwmmxt_movq_wRn_M0(s, wrd);
1899         gen_op_iwmmxt_set_mup(s);
1900         break;
1901     case 0x006: case 0x406: case 0x806: case 0xc06: /* WCMPEQ */
1902         wrd = (insn >> 12) & 0xf;
1903         rd0 = (insn >> 16) & 0xf;
1904         rd1 = (insn >> 0) & 0xf;
1905         gen_op_iwmmxt_movq_M0_wRn(s, rd0);
1906         switch ((insn >> 22) & 3) {
1907         case 0:
1908             gen_op_iwmmxt_cmpeqb_M0_wRn(s, rd1);
1909             break;
1910         case 1:
1911             gen_op_iwmmxt_cmpeqw_M0_wRn(s, rd1);
1912             break;
1913         case 2:
1914             gen_op_iwmmxt_cmpeql_M0_wRn(s, rd1);
1915             break;
1916         case 3:
1917             return 1;
1918         }
1919         gen_op_iwmmxt_movq_wRn_M0(s, wrd);
1920         gen_op_iwmmxt_set_mup(s);
1921         gen_op_iwmmxt_set_cup(s);
1922         break;
1923     case 0x800: case 0x900: case 0xc00: case 0xd00: /* WAVG2 */
1924         wrd = (insn >> 12) & 0xf;
1925         rd0 = (insn >> 16) & 0xf;
1926         rd1 = (insn >> 0) & 0xf;
1927         gen_op_iwmmxt_movq_M0_wRn(s, rd0);
1928         if (insn & (1 << 22)) {
1929             if (insn & (1 << 20))
1930                 gen_op_iwmmxt_avgw1_M0_wRn(s, rd1);
1931             else
1932                 gen_op_iwmmxt_avgw0_M0_wRn(s, rd1);
1933         } else {
1934             if (insn & (1 << 20))
1935                 gen_op_iwmmxt_avgb1_M0_wRn(s, rd1);
1936             else
1937                 gen_op_iwmmxt_avgb0_M0_wRn(s, rd1);
1938         }
1939         gen_op_iwmmxt_movq_wRn_M0(s, wrd);
1940         gen_op_iwmmxt_set_mup(s);
1941         gen_op_iwmmxt_set_cup(s);
1942         break;
1943     case 0x802: case 0x902: case 0xa02: case 0xb02: /* WALIGNR */
1944         wrd = (insn >> 12) & 0xf;
1945         rd0 = (insn >> 16) & 0xf;
1946         rd1 = (insn >> 0) & 0xf;
1947         gen_op_iwmmxt_movq_M0_wRn(s, rd0);
1948         tmp = iwmmxt_load_creg(s, ARM_IWMMXT_wCGR0 + ((insn >> 20) & 3));
1949         tcg_gen_andi_i32(tcg_ctx, tmp, tmp, 7);
1950         iwmmxt_load_reg(s, tcg_ctx->cpu_V1, rd1);
1951         gen_helper_iwmmxt_align(tcg_ctx, tcg_ctx->cpu_M0, tcg_ctx->cpu_M0, tcg_ctx->cpu_V1, tmp);
1952         tcg_temp_free_i32(tcg_ctx, tmp);
1953         gen_op_iwmmxt_movq_wRn_M0(s, wrd);
1954         gen_op_iwmmxt_set_mup(s);
1955         break;
1956     case 0x601: case 0x605: case 0x609: case 0x60d: /* TINSR */
1957         if (((insn >> 6) & 3) == 3)
1958             return 1;
1959         rd = (insn >> 12) & 0xf;
1960         wrd = (insn >> 16) & 0xf;
1961         tmp = load_reg(s, rd);
1962         gen_op_iwmmxt_movq_M0_wRn(s, wrd);
1963         switch ((insn >> 6) & 3) {
1964         case 0:
1965             tmp2 = tcg_const_i32(tcg_ctx, 0xff);
1966             tmp3 = tcg_const_i32(tcg_ctx, (insn & 7) << 3);
1967             break;
1968         case 1:
1969             tmp2 = tcg_const_i32(tcg_ctx, 0xffff);
1970             tmp3 = tcg_const_i32(tcg_ctx, (insn & 3) << 4);
1971             break;
1972         case 2:
1973             tmp2 = tcg_const_i32(tcg_ctx, 0xffffffff);
1974             tmp3 = tcg_const_i32(tcg_ctx, (insn & 1) << 5);
1975             break;
1976         default:
1977             TCGV_UNUSED_I32(tmp2);
1978             TCGV_UNUSED_I32(tmp3);
1979         }
1980         gen_helper_iwmmxt_insr(tcg_ctx, tcg_ctx->cpu_M0, tcg_ctx->cpu_M0, tmp, tmp2, tmp3);
1981         tcg_temp_free_i32(tcg_ctx, tmp3);
1982         tcg_temp_free_i32(tcg_ctx, tmp2);
1983         tcg_temp_free_i32(tcg_ctx, tmp);
1984         gen_op_iwmmxt_movq_wRn_M0(s, wrd);
1985         gen_op_iwmmxt_set_mup(s);
1986         break;
1987     case 0x107: case 0x507: case 0x907: case 0xd07: /* TEXTRM */
1988         rd = (insn >> 12) & 0xf;
1989         wrd = (insn >> 16) & 0xf;
1990         if (rd == 15 || ((insn >> 22) & 3) == 3)
1991             return 1;
1992         gen_op_iwmmxt_movq_M0_wRn(s, wrd);
1993         tmp = tcg_temp_new_i32(tcg_ctx);
1994         switch ((insn >> 22) & 3) {
1995         case 0:
1996             tcg_gen_shri_i64(tcg_ctx, tcg_ctx->cpu_M0, tcg_ctx->cpu_M0, (insn & 7) << 3);
1997             tcg_gen_trunc_i64_i32(tcg_ctx, tmp, tcg_ctx->cpu_M0);
1998             if (insn & 8) {
1999                 tcg_gen_ext8s_i32(tcg_ctx, tmp, tmp);
2000             } else {
2001                 tcg_gen_andi_i32(tcg_ctx, tmp, tmp, 0xff);
2002             }
2003             break;
2004         case 1:
2005             tcg_gen_shri_i64(tcg_ctx, tcg_ctx->cpu_M0, tcg_ctx->cpu_M0, (insn & 3) << 4);
2006             tcg_gen_trunc_i64_i32(tcg_ctx, tmp, tcg_ctx->cpu_M0);
2007             if (insn & 8) {
2008                 tcg_gen_ext16s_i32(tcg_ctx, tmp, tmp);
2009             } else {
2010                 tcg_gen_andi_i32(tcg_ctx, tmp, tmp, 0xffff);
2011             }
2012             break;
2013         case 2:
2014             tcg_gen_shri_i64(tcg_ctx, tcg_ctx->cpu_M0, tcg_ctx->cpu_M0, (insn & 1) << 5);
2015             tcg_gen_trunc_i64_i32(tcg_ctx, tmp, tcg_ctx->cpu_M0);
2016             break;
2017         }
2018         store_reg(s, rd, tmp);
2019         break;
2020     case 0x117: case 0x517: case 0x917: case 0xd17: /* TEXTRC */
2021         if ((insn & 0x000ff008) != 0x0003f000 || ((insn >> 22) & 3) == 3)
2022             return 1;
2023         tmp = iwmmxt_load_creg(s, ARM_IWMMXT_wCASF);
2024         switch ((insn >> 22) & 3) {
2025         case 0:
2026             tcg_gen_shri_i32(tcg_ctx, tmp, tmp, ((insn & 7) << 2) + 0);
2027             break;
2028         case 1:
2029             tcg_gen_shri_i32(tcg_ctx, tmp, tmp, ((insn & 3) << 3) + 4);
2030             break;
2031         case 2:
2032             tcg_gen_shri_i32(tcg_ctx, tmp, tmp, ((insn & 1) << 4) + 12);
2033             break;
2034         }
2035         tcg_gen_shli_i32(tcg_ctx, tmp, tmp, 28);
2036         gen_set_nzcv(s, tmp);
2037         tcg_temp_free_i32(tcg_ctx, tmp);
2038         break;
2039     case 0x401: case 0x405: case 0x409: case 0x40d: /* TBCST */
2040         if (((insn >> 6) & 3) == 3)
2041             return 1;
2042         rd = (insn >> 12) & 0xf;
2043         wrd = (insn >> 16) & 0xf;
2044         tmp = load_reg(s, rd);
2045         switch ((insn >> 6) & 3) {
2046         case 0:
2047             gen_helper_iwmmxt_bcstb(tcg_ctx, tcg_ctx->cpu_M0, tmp);
2048             break;
2049         case 1:
2050             gen_helper_iwmmxt_bcstw(tcg_ctx, tcg_ctx->cpu_M0, tmp);
2051             break;
2052         case 2:
2053             gen_helper_iwmmxt_bcstl(tcg_ctx, tcg_ctx->cpu_M0, tmp);
2054             break;
2055         }
2056         tcg_temp_free_i32(tcg_ctx, tmp);
2057         gen_op_iwmmxt_movq_wRn_M0(s, wrd);
2058         gen_op_iwmmxt_set_mup(s);
2059         break;
2060     case 0x113: case 0x513: case 0x913: case 0xd13: /* TANDC */
2061         if ((insn & 0x000ff00f) != 0x0003f000 || ((insn >> 22) & 3) == 3)
2062             return 1;
2063         tmp = iwmmxt_load_creg(s, ARM_IWMMXT_wCASF);
2064         tmp2 = tcg_temp_new_i32(tcg_ctx);
2065         tcg_gen_mov_i32(tcg_ctx, tmp2, tmp);
2066         switch ((insn >> 22) & 3) {
2067         case 0:
2068             for (i = 0; i < 7; i ++) {
2069                 tcg_gen_shli_i32(tcg_ctx, tmp2, tmp2, 4);
2070                 tcg_gen_and_i32(tcg_ctx, tmp, tmp, tmp2);
2071             }
2072             break;
2073         case 1:
2074             for (i = 0; i < 3; i ++) {
2075                 tcg_gen_shli_i32(tcg_ctx, tmp2, tmp2, 8);
2076                 tcg_gen_and_i32(tcg_ctx, tmp, tmp, tmp2);
2077             }
2078             break;
2079         case 2:
2080             tcg_gen_shli_i32(tcg_ctx, tmp2, tmp2, 16);
2081             tcg_gen_and_i32(tcg_ctx, tmp, tmp, tmp2);
2082             break;
2083         }
2084         gen_set_nzcv(s, tmp);
2085         tcg_temp_free_i32(tcg_ctx, tmp2);
2086         tcg_temp_free_i32(tcg_ctx, tmp);
2087         break;
2088     case 0x01c: case 0x41c: case 0x81c: case 0xc1c: /* WACC */
2089         wrd = (insn >> 12) & 0xf;
2090         rd0 = (insn >> 16) & 0xf;
2091         gen_op_iwmmxt_movq_M0_wRn(s, rd0);
2092         switch ((insn >> 22) & 3) {
2093         case 0:
2094             gen_helper_iwmmxt_addcb(tcg_ctx, tcg_ctx->cpu_M0, tcg_ctx->cpu_M0);
2095             break;
2096         case 1:
2097             gen_helper_iwmmxt_addcw(tcg_ctx, tcg_ctx->cpu_M0, tcg_ctx->cpu_M0);
2098             break;
2099         case 2:
2100             gen_helper_iwmmxt_addcl(tcg_ctx, tcg_ctx->cpu_M0, tcg_ctx->cpu_M0);
2101             break;
2102         case 3:
2103             return 1;
2104         }
2105         gen_op_iwmmxt_movq_wRn_M0(s, wrd);
2106         gen_op_iwmmxt_set_mup(s);
2107         break;
2108     case 0x115: case 0x515: case 0x915: case 0xd15: /* TORC */
2109         if ((insn & 0x000ff00f) != 0x0003f000 || ((insn >> 22) & 3) == 3)
2110             return 1;
2111         tmp = iwmmxt_load_creg(s, ARM_IWMMXT_wCASF);
2112         tmp2 = tcg_temp_new_i32(tcg_ctx);
2113         tcg_gen_mov_i32(tcg_ctx, tmp2, tmp);
2114         switch ((insn >> 22) & 3) {
2115         case 0:
2116             for (i = 0; i < 7; i ++) {
2117                 tcg_gen_shli_i32(tcg_ctx, tmp2, tmp2, 4);
2118                 tcg_gen_or_i32(tcg_ctx, tmp, tmp, tmp2);
2119             }
2120             break;
2121         case 1:
2122             for (i = 0; i < 3; i ++) {
2123                 tcg_gen_shli_i32(tcg_ctx, tmp2, tmp2, 8);
2124                 tcg_gen_or_i32(tcg_ctx, tmp, tmp, tmp2);
2125             }
2126             break;
2127         case 2:
2128             tcg_gen_shli_i32(tcg_ctx, tmp2, tmp2, 16);
2129             tcg_gen_or_i32(tcg_ctx, tmp, tmp, tmp2);
2130             break;
2131         }
2132         gen_set_nzcv(s, tmp);
2133         tcg_temp_free_i32(tcg_ctx, tmp2);
2134         tcg_temp_free_i32(tcg_ctx, tmp);
2135         break;
2136     case 0x103: case 0x503: case 0x903: case 0xd03: /* TMOVMSK */
2137         rd = (insn >> 12) & 0xf;
2138         rd0 = (insn >> 16) & 0xf;
2139         if ((insn & 0xf) != 0 || ((insn >> 22) & 3) == 3)
2140             return 1;
2141         gen_op_iwmmxt_movq_M0_wRn(s, rd0);
2142         tmp = tcg_temp_new_i32(tcg_ctx);
2143         switch ((insn >> 22) & 3) {
2144         case 0:
2145             gen_helper_iwmmxt_msbb(tcg_ctx, tmp, tcg_ctx->cpu_M0);
2146             break;
2147         case 1:
2148             gen_helper_iwmmxt_msbw(tcg_ctx, tmp, tcg_ctx->cpu_M0);
2149             break;
2150         case 2:
2151             gen_helper_iwmmxt_msbl(tcg_ctx, tmp, tcg_ctx->cpu_M0);
2152             break;
2153         }
2154         store_reg(s, rd, tmp);
2155         break;
2156     case 0x106: case 0x306: case 0x506: case 0x706: /* WCMPGT */
2157     case 0x906: case 0xb06: case 0xd06: case 0xf06:
2158         wrd = (insn >> 12) & 0xf;
2159         rd0 = (insn >> 16) & 0xf;
2160         rd1 = (insn >> 0) & 0xf;
2161         gen_op_iwmmxt_movq_M0_wRn(s, rd0);
2162         switch ((insn >> 22) & 3) {
2163         case 0:
2164             if (insn & (1 << 21))
2165                 gen_op_iwmmxt_cmpgtsb_M0_wRn(s, rd1);
2166             else
2167                 gen_op_iwmmxt_cmpgtub_M0_wRn(s, rd1);
2168             break;
2169         case 1:
2170             if (insn & (1 << 21))
2171                 gen_op_iwmmxt_cmpgtsw_M0_wRn(s, rd1);
2172             else
2173                 gen_op_iwmmxt_cmpgtuw_M0_wRn(s, rd1);
2174             break;
2175         case 2:
2176             if (insn & (1 << 21))
2177                 gen_op_iwmmxt_cmpgtsl_M0_wRn(s, rd1);
2178             else
2179                 gen_op_iwmmxt_cmpgtul_M0_wRn(s, rd1);
2180             break;
2181         case 3:
2182             return 1;
2183         }
2184         gen_op_iwmmxt_movq_wRn_M0(s, wrd);
2185         gen_op_iwmmxt_set_mup(s);
2186         gen_op_iwmmxt_set_cup(s);
2187         break;
2188     case 0x00e: case 0x20e: case 0x40e: case 0x60e: /* WUNPCKEL */
2189     case 0x80e: case 0xa0e: case 0xc0e: case 0xe0e:
2190         wrd = (insn >> 12) & 0xf;
2191         rd0 = (insn >> 16) & 0xf;
2192         gen_op_iwmmxt_movq_M0_wRn(s, rd0);
2193         switch ((insn >> 22) & 3) {
2194         case 0:
2195             if (insn & (1 << 21))
2196                 gen_op_iwmmxt_unpacklsb_M0(s);
2197             else
2198                 gen_op_iwmmxt_unpacklub_M0(s);
2199             break;
2200         case 1:
2201             if (insn & (1 << 21))
2202                 gen_op_iwmmxt_unpacklsw_M0(s);
2203             else
2204                 gen_op_iwmmxt_unpackluw_M0(s);
2205             break;
2206         case 2:
2207             if (insn & (1 << 21))
2208                 gen_op_iwmmxt_unpacklsl_M0(s);
2209             else
2210                 gen_op_iwmmxt_unpacklul_M0(s);
2211             break;
2212         case 3:
2213             return 1;
2214         }
2215         gen_op_iwmmxt_movq_wRn_M0(s, wrd);
2216         gen_op_iwmmxt_set_mup(s);
2217         gen_op_iwmmxt_set_cup(s);
2218         break;
2219     case 0x00c: case 0x20c: case 0x40c: case 0x60c: /* WUNPCKEH */
2220     case 0x80c: case 0xa0c: case 0xc0c: case 0xe0c:
2221         wrd = (insn >> 12) & 0xf;
2222         rd0 = (insn >> 16) & 0xf;
2223         gen_op_iwmmxt_movq_M0_wRn(s, rd0);
2224         switch ((insn >> 22) & 3) {
2225         case 0:
2226             if (insn & (1 << 21))
2227                 gen_op_iwmmxt_unpackhsb_M0(s);
2228             else
2229                 gen_op_iwmmxt_unpackhub_M0(s);
2230             break;
2231         case 1:
2232             if (insn & (1 << 21))
2233                 gen_op_iwmmxt_unpackhsw_M0(s);
2234             else
2235                 gen_op_iwmmxt_unpackhuw_M0(s);
2236             break;
2237         case 2:
2238             if (insn & (1 << 21))
2239                 gen_op_iwmmxt_unpackhsl_M0(s);
2240             else
2241                 gen_op_iwmmxt_unpackhul_M0(s);
2242             break;
2243         case 3:
2244             return 1;
2245         }
2246         gen_op_iwmmxt_movq_wRn_M0(s, wrd);
2247         gen_op_iwmmxt_set_mup(s);
2248         gen_op_iwmmxt_set_cup(s);
2249         break;
2250     case 0x204: case 0x604: case 0xa04: case 0xe04: /* WSRL */
2251     case 0x214: case 0x614: case 0xa14: case 0xe14:
2252         if (((insn >> 22) & 3) == 0)
2253             return 1;
2254         wrd = (insn >> 12) & 0xf;
2255         rd0 = (insn >> 16) & 0xf;
2256         gen_op_iwmmxt_movq_M0_wRn(s, rd0);
2257         tmp = tcg_temp_new_i32(tcg_ctx);
2258         if (gen_iwmmxt_shift(s, insn, 0xff, tmp)) {
2259             tcg_temp_free_i32(tcg_ctx, tmp);
2260             return 1;
2261         }
2262         switch ((insn >> 22) & 3) {
2263         case 1:
2264             gen_helper_iwmmxt_srlw(tcg_ctx, tcg_ctx->cpu_M0, tcg_ctx->cpu_env, tcg_ctx->cpu_M0, tmp);
2265             break;
2266         case 2:
2267             gen_helper_iwmmxt_srll(tcg_ctx, tcg_ctx->cpu_M0, tcg_ctx->cpu_env, tcg_ctx->cpu_M0, tmp);
2268             break;
2269         case 3:
2270             gen_helper_iwmmxt_srlq(tcg_ctx, tcg_ctx->cpu_M0, tcg_ctx->cpu_env, tcg_ctx->cpu_M0, tmp);
2271             break;
2272         }
2273         tcg_temp_free_i32(tcg_ctx, tmp);
2274         gen_op_iwmmxt_movq_wRn_M0(s, wrd);
2275         gen_op_iwmmxt_set_mup(s);
2276         gen_op_iwmmxt_set_cup(s);
2277         break;
2278     case 0x004: case 0x404: case 0x804: case 0xc04: /* WSRA */
2279     case 0x014: case 0x414: case 0x814: case 0xc14:
2280         if (((insn >> 22) & 3) == 0)
2281             return 1;
2282         wrd = (insn >> 12) & 0xf;
2283         rd0 = (insn >> 16) & 0xf;
2284         gen_op_iwmmxt_movq_M0_wRn(s, rd0);
2285         tmp = tcg_temp_new_i32(tcg_ctx);
2286         if (gen_iwmmxt_shift(s, insn, 0xff, tmp)) {
2287             tcg_temp_free_i32(tcg_ctx, tmp);
2288             return 1;
2289         }
2290         switch ((insn >> 22) & 3) {
2291         case 1:
2292             gen_helper_iwmmxt_sraw(tcg_ctx, tcg_ctx->cpu_M0, tcg_ctx->cpu_env, tcg_ctx->cpu_M0, tmp);
2293             break;
2294         case 2:
2295             gen_helper_iwmmxt_sral(tcg_ctx, tcg_ctx->cpu_M0, tcg_ctx->cpu_env, tcg_ctx->cpu_M0, tmp);
2296             break;
2297         case 3:
2298             gen_helper_iwmmxt_sraq(tcg_ctx, tcg_ctx->cpu_M0, tcg_ctx->cpu_env, tcg_ctx->cpu_M0, tmp);
2299             break;
2300         }
2301         tcg_temp_free_i32(tcg_ctx, tmp);
2302         gen_op_iwmmxt_movq_wRn_M0(s, wrd);
2303         gen_op_iwmmxt_set_mup(s);
2304         gen_op_iwmmxt_set_cup(s);
2305         break;
2306     case 0x104: case 0x504: case 0x904: case 0xd04: /* WSLL */
2307     case 0x114: case 0x514: case 0x914: case 0xd14:
2308         if (((insn >> 22) & 3) == 0)
2309             return 1;
2310         wrd = (insn >> 12) & 0xf;
2311         rd0 = (insn >> 16) & 0xf;
2312         gen_op_iwmmxt_movq_M0_wRn(s, rd0);
2313         tmp = tcg_temp_new_i32(tcg_ctx);
2314         if (gen_iwmmxt_shift(s, insn, 0xff, tmp)) {
2315             tcg_temp_free_i32(tcg_ctx, tmp);
2316             return 1;
2317         }
2318         switch ((insn >> 22) & 3) {
2319         case 1:
2320             gen_helper_iwmmxt_sllw(tcg_ctx, tcg_ctx->cpu_M0, tcg_ctx->cpu_env, tcg_ctx->cpu_M0, tmp);
2321             break;
2322         case 2:
2323             gen_helper_iwmmxt_slll(tcg_ctx, tcg_ctx->cpu_M0, tcg_ctx->cpu_env, tcg_ctx->cpu_M0, tmp);
2324             break;
2325         case 3:
2326             gen_helper_iwmmxt_sllq(tcg_ctx, tcg_ctx->cpu_M0, tcg_ctx->cpu_env, tcg_ctx->cpu_M0, tmp);
2327             break;
2328         }
2329         tcg_temp_free_i32(tcg_ctx, tmp);
2330         gen_op_iwmmxt_movq_wRn_M0(s, wrd);
2331         gen_op_iwmmxt_set_mup(s);
2332         gen_op_iwmmxt_set_cup(s);
2333         break;
2334     case 0x304: case 0x704: case 0xb04: case 0xf04: /* WROR */
2335     case 0x314: case 0x714: case 0xb14: case 0xf14:
2336         if (((insn >> 22) & 3) == 0)
2337             return 1;
2338         wrd = (insn >> 12) & 0xf;
2339         rd0 = (insn >> 16) & 0xf;
2340         gen_op_iwmmxt_movq_M0_wRn(s, rd0);
2341         tmp = tcg_temp_new_i32(tcg_ctx);
2342         switch ((insn >> 22) & 3) {
2343         case 1:
2344             if (gen_iwmmxt_shift(s, insn, 0xf, tmp)) {
2345                 tcg_temp_free_i32(tcg_ctx, tmp);
2346                 return 1;
2347             }
2348             gen_helper_iwmmxt_rorw(tcg_ctx, tcg_ctx->cpu_M0, tcg_ctx->cpu_env, tcg_ctx->cpu_M0, tmp);
2349             break;
2350         case 2:
2351             if (gen_iwmmxt_shift(s, insn, 0x1f, tmp)) {
2352                 tcg_temp_free_i32(tcg_ctx, tmp);
2353                 return 1;
2354             }
2355             gen_helper_iwmmxt_rorl(tcg_ctx, tcg_ctx->cpu_M0, tcg_ctx->cpu_env, tcg_ctx->cpu_M0, tmp);
2356             break;
2357         case 3:
2358             if (gen_iwmmxt_shift(s, insn, 0x3f, tmp)) {
2359                 tcg_temp_free_i32(tcg_ctx, tmp);
2360                 return 1;
2361             }
2362             gen_helper_iwmmxt_rorq(tcg_ctx, tcg_ctx->cpu_M0, tcg_ctx->cpu_env, tcg_ctx->cpu_M0, tmp);
2363             break;
2364         }
2365         tcg_temp_free_i32(tcg_ctx, tmp);
2366         gen_op_iwmmxt_movq_wRn_M0(s, wrd);
2367         gen_op_iwmmxt_set_mup(s);
2368         gen_op_iwmmxt_set_cup(s);
2369         break;
2370     case 0x116: case 0x316: case 0x516: case 0x716: /* WMIN */
2371     case 0x916: case 0xb16: case 0xd16: case 0xf16:
2372         wrd = (insn >> 12) & 0xf;
2373         rd0 = (insn >> 16) & 0xf;
2374         rd1 = (insn >> 0) & 0xf;
2375         gen_op_iwmmxt_movq_M0_wRn(s, rd0);
2376         switch ((insn >> 22) & 3) {
2377         case 0:
2378             if (insn & (1 << 21))
2379                 gen_op_iwmmxt_minsb_M0_wRn(s, rd1);
2380             else
2381                 gen_op_iwmmxt_minub_M0_wRn(s, rd1);
2382             break;
2383         case 1:
2384             if (insn & (1 << 21))
2385                 gen_op_iwmmxt_minsw_M0_wRn(s, rd1);
2386             else
2387                 gen_op_iwmmxt_minuw_M0_wRn(s, rd1);
2388             break;
2389         case 2:
2390             if (insn & (1 << 21))
2391                 gen_op_iwmmxt_minsl_M0_wRn(s, rd1);
2392             else
2393                 gen_op_iwmmxt_minul_M0_wRn(s, rd1);
2394             break;
2395         case 3:
2396             return 1;
2397         }
2398         gen_op_iwmmxt_movq_wRn_M0(s, wrd);
2399         gen_op_iwmmxt_set_mup(s);
2400         break;
2401     case 0x016: case 0x216: case 0x416: case 0x616: /* WMAX */
2402     case 0x816: case 0xa16: case 0xc16: case 0xe16:
2403         wrd = (insn >> 12) & 0xf;
2404         rd0 = (insn >> 16) & 0xf;
2405         rd1 = (insn >> 0) & 0xf;
2406         gen_op_iwmmxt_movq_M0_wRn(s, rd0);
2407         switch ((insn >> 22) & 3) {
2408         case 0:
2409             if (insn & (1 << 21))
2410                 gen_op_iwmmxt_maxsb_M0_wRn(s, rd1);
2411             else
2412                 gen_op_iwmmxt_maxub_M0_wRn(s, rd1);
2413             break;
2414         case 1:
2415             if (insn & (1 << 21))
2416                 gen_op_iwmmxt_maxsw_M0_wRn(s, rd1);
2417             else
2418                 gen_op_iwmmxt_maxuw_M0_wRn(s, rd1);
2419             break;
2420         case 2:
2421             if (insn & (1 << 21))
2422                 gen_op_iwmmxt_maxsl_M0_wRn(s, rd1);
2423             else
2424                 gen_op_iwmmxt_maxul_M0_wRn(s, rd1);
2425             break;
2426         case 3:
2427             return 1;
2428         }
2429         gen_op_iwmmxt_movq_wRn_M0(s, wrd);
2430         gen_op_iwmmxt_set_mup(s);
2431         break;
2432     case 0x002: case 0x102: case 0x202: case 0x302: /* WALIGNI */
2433     case 0x402: case 0x502: case 0x602: case 0x702:
2434         wrd = (insn >> 12) & 0xf;
2435         rd0 = (insn >> 16) & 0xf;
2436         rd1 = (insn >> 0) & 0xf;
2437         gen_op_iwmmxt_movq_M0_wRn(s, rd0);
2438         tmp = tcg_const_i32(tcg_ctx, (insn >> 20) & 3);
2439         iwmmxt_load_reg(s, tcg_ctx->cpu_V1, rd1);
2440         gen_helper_iwmmxt_align(tcg_ctx, tcg_ctx->cpu_M0, tcg_ctx->cpu_M0, tcg_ctx->cpu_V1, tmp);
2441         tcg_temp_free_i32(tcg_ctx, tmp);
2442         gen_op_iwmmxt_movq_wRn_M0(s, wrd);
2443         gen_op_iwmmxt_set_mup(s);
2444         break;
2445     case 0x01a: case 0x11a: case 0x21a: case 0x31a: /* WSUB */
2446     case 0x41a: case 0x51a: case 0x61a: case 0x71a:
2447     case 0x81a: case 0x91a: case 0xa1a: case 0xb1a:
2448     case 0xc1a: case 0xd1a: case 0xe1a: case 0xf1a:
2449         wrd = (insn >> 12) & 0xf;
2450         rd0 = (insn >> 16) & 0xf;
2451         rd1 = (insn >> 0) & 0xf;
2452         gen_op_iwmmxt_movq_M0_wRn(s, rd0);
2453         switch ((insn >> 20) & 0xf) {
2454         case 0x0:
2455             gen_op_iwmmxt_subnb_M0_wRn(s, rd1);
2456             break;
2457         case 0x1:
2458             gen_op_iwmmxt_subub_M0_wRn(s, rd1);
2459             break;
2460         case 0x3:
2461             gen_op_iwmmxt_subsb_M0_wRn(s, rd1);
2462             break;
2463         case 0x4:
2464             gen_op_iwmmxt_subnw_M0_wRn(s, rd1);
2465             break;
2466         case 0x5:
2467             gen_op_iwmmxt_subuw_M0_wRn(s, rd1);
2468             break;
2469         case 0x7:
2470             gen_op_iwmmxt_subsw_M0_wRn(s, rd1);
2471             break;
2472         case 0x8:
2473             gen_op_iwmmxt_subnl_M0_wRn(s, rd1);
2474             break;
2475         case 0x9:
2476             gen_op_iwmmxt_subul_M0_wRn(s, rd1);
2477             break;
2478         case 0xb:
2479             gen_op_iwmmxt_subsl_M0_wRn(s, rd1);
2480             break;
2481         default:
2482             return 1;
2483         }
2484         gen_op_iwmmxt_movq_wRn_M0(s, wrd);
2485         gen_op_iwmmxt_set_mup(s);
2486         gen_op_iwmmxt_set_cup(s);
2487         break;
2488     case 0x01e: case 0x11e: case 0x21e: case 0x31e: /* WSHUFH */
2489     case 0x41e: case 0x51e: case 0x61e: case 0x71e:
2490     case 0x81e: case 0x91e: case 0xa1e: case 0xb1e:
2491     case 0xc1e: case 0xd1e: case 0xe1e: case 0xf1e:
2492         wrd = (insn >> 12) & 0xf;
2493         rd0 = (insn >> 16) & 0xf;
2494         gen_op_iwmmxt_movq_M0_wRn(s, rd0);
2495         tmp = tcg_const_i32(tcg_ctx, ((insn >> 16) & 0xf0) | (insn & 0x0f));
2496         gen_helper_iwmmxt_shufh(tcg_ctx, tcg_ctx->cpu_M0, tcg_ctx->cpu_env, tcg_ctx->cpu_M0, tmp);
2497         tcg_temp_free_i32(tcg_ctx, tmp);
2498         gen_op_iwmmxt_movq_wRn_M0(s, wrd);
2499         gen_op_iwmmxt_set_mup(s);
2500         gen_op_iwmmxt_set_cup(s);
2501         break;
2502     case 0x018: case 0x118: case 0x218: case 0x318: /* WADD */
2503     case 0x418: case 0x518: case 0x618: case 0x718:
2504     case 0x818: case 0x918: case 0xa18: case 0xb18:
2505     case 0xc18: case 0xd18: case 0xe18: case 0xf18:
2506         wrd = (insn >> 12) & 0xf;
2507         rd0 = (insn >> 16) & 0xf;
2508         rd1 = (insn >> 0) & 0xf;
2509         gen_op_iwmmxt_movq_M0_wRn(s, rd0);
2510         switch ((insn >> 20) & 0xf) {
2511         case 0x0:
2512             gen_op_iwmmxt_addnb_M0_wRn(s, rd1);
2513             break;
2514         case 0x1:
2515             gen_op_iwmmxt_addub_M0_wRn(s, rd1);
2516             break;
2517         case 0x3:
2518             gen_op_iwmmxt_addsb_M0_wRn(s, rd1);
2519             break;
2520         case 0x4:
2521             gen_op_iwmmxt_addnw_M0_wRn(s, rd1);
2522             break;
2523         case 0x5:
2524             gen_op_iwmmxt_adduw_M0_wRn(s, rd1);
2525             break;
2526         case 0x7:
2527             gen_op_iwmmxt_addsw_M0_wRn(s, rd1);
2528             break;
2529         case 0x8:
2530             gen_op_iwmmxt_addnl_M0_wRn(s, rd1);
2531             break;
2532         case 0x9:
2533             gen_op_iwmmxt_addul_M0_wRn(s, rd1);
2534             break;
2535         case 0xb:
2536             gen_op_iwmmxt_addsl_M0_wRn(s, rd1);
2537             break;
2538         default:
2539             return 1;
2540         }
2541         gen_op_iwmmxt_movq_wRn_M0(s, wrd);
2542         gen_op_iwmmxt_set_mup(s);
2543         gen_op_iwmmxt_set_cup(s);
2544         break;
2545     case 0x008: case 0x108: case 0x208: case 0x308: /* WPACK */
2546     case 0x408: case 0x508: case 0x608: case 0x708:
2547     case 0x808: case 0x908: case 0xa08: case 0xb08:
2548     case 0xc08: case 0xd08: case 0xe08: case 0xf08:
2549         if (!(insn & (1 << 20)) || ((insn >> 22) & 3) == 0)
2550             return 1;
2551         wrd = (insn >> 12) & 0xf;
2552         rd0 = (insn >> 16) & 0xf;
2553         rd1 = (insn >> 0) & 0xf;
2554         gen_op_iwmmxt_movq_M0_wRn(s, rd0);
2555         switch ((insn >> 22) & 3) {
2556         case 1:
2557             if (insn & (1 << 21))
2558                 gen_op_iwmmxt_packsw_M0_wRn(s, rd1);
2559             else
2560                 gen_op_iwmmxt_packuw_M0_wRn(s, rd1);
2561             break;
2562         case 2:
2563             if (insn & (1 << 21))
2564                 gen_op_iwmmxt_packsl_M0_wRn(s, rd1);
2565             else
2566                 gen_op_iwmmxt_packul_M0_wRn(s, rd1);
2567             break;
2568         case 3:
2569             if (insn & (1 << 21))
2570                 gen_op_iwmmxt_packsq_M0_wRn(s, rd1);
2571             else
2572                 gen_op_iwmmxt_packuq_M0_wRn(s, rd1);
2573             break;
2574         }
2575         gen_op_iwmmxt_movq_wRn_M0(s, wrd);
2576         gen_op_iwmmxt_set_mup(s);
2577         gen_op_iwmmxt_set_cup(s);
2578         break;
2579     case 0x201: case 0x203: case 0x205: case 0x207:
2580     case 0x209: case 0x20b: case 0x20d: case 0x20f:
2581     case 0x211: case 0x213: case 0x215: case 0x217:
2582     case 0x219: case 0x21b: case 0x21d: case 0x21f:
2583         wrd = (insn >> 5) & 0xf;
2584         rd0 = (insn >> 12) & 0xf;
2585         rd1 = (insn >> 0) & 0xf;
2586         if (rd0 == 0xf || rd1 == 0xf)
2587             return 1;
2588         gen_op_iwmmxt_movq_M0_wRn(s, wrd);
2589         tmp = load_reg(s, rd0);
2590         tmp2 = load_reg(s, rd1);
2591         switch ((insn >> 16) & 0xf) {
2592         case 0x0:                   /* TMIA */
2593             gen_helper_iwmmxt_muladdsl(tcg_ctx, tcg_ctx->cpu_M0, tcg_ctx->cpu_M0, tmp, tmp2);
2594             break;
2595         case 0x8:                   /* TMIAPH */
2596             gen_helper_iwmmxt_muladdsw(tcg_ctx, tcg_ctx->cpu_M0, tcg_ctx->cpu_M0, tmp, tmp2);
2597             break;
2598         case 0xc: case 0xd: case 0xe: case 0xf:     /* TMIAxy */
2599             if (insn & (1 << 16))
2600                 tcg_gen_shri_i32(tcg_ctx, tmp, tmp, 16);
2601             if (insn & (1 << 17))
2602                 tcg_gen_shri_i32(tcg_ctx, tmp2, tmp2, 16);
2603             gen_helper_iwmmxt_muladdswl(tcg_ctx, tcg_ctx->cpu_M0, tcg_ctx->cpu_M0, tmp, tmp2);
2604             break;
2605         default:
2606             tcg_temp_free_i32(tcg_ctx, tmp2);
2607             tcg_temp_free_i32(tcg_ctx, tmp);
2608             return 1;
2609         }
2610         tcg_temp_free_i32(tcg_ctx, tmp2);
2611         tcg_temp_free_i32(tcg_ctx, tmp);
2612         gen_op_iwmmxt_movq_wRn_M0(s, wrd);
2613         gen_op_iwmmxt_set_mup(s);
2614         break;
2615     default:
2616         return 1;
2617     }
2618 
2619     return 0;
2620 }
2621 
2622 /* Disassemble an XScale DSP instruction.  Returns nonzero if an error occurred
2623    (ie. an undefined instruction).  */
disas_dsp_insn(DisasContext * s,uint32_t insn)2624 static int disas_dsp_insn(DisasContext *s, uint32_t insn)
2625 {
2626     TCGContext *tcg_ctx = s->uc->tcg_ctx;
2627     int acc, rd0, rd1, rdhi, rdlo;
2628     TCGv_i32 tmp, tmp2;
2629 
2630     if ((insn & 0x0ff00f10) == 0x0e200010) {
2631         /* Multiply with Internal Accumulate Format */
2632         rd0 = (insn >> 12) & 0xf;
2633         rd1 = insn & 0xf;
2634         acc = (insn >> 5) & 7;
2635 
2636         if (acc != 0)
2637             return 1;
2638 
2639         tmp = load_reg(s, rd0);
2640         tmp2 = load_reg(s, rd1);
2641         switch ((insn >> 16) & 0xf) {
2642         case 0x0:                   /* MIA */
2643             gen_helper_iwmmxt_muladdsl(tcg_ctx, tcg_ctx->cpu_M0, tcg_ctx->cpu_M0, tmp, tmp2);
2644             break;
2645         case 0x8:                   /* MIAPH */
2646             gen_helper_iwmmxt_muladdsw(tcg_ctx, tcg_ctx->cpu_M0, tcg_ctx->cpu_M0, tmp, tmp2);
2647             break;
2648         case 0xc:                   /* MIABB */
2649         case 0xd:                   /* MIABT */
2650         case 0xe:                   /* MIATB */
2651         case 0xf:                   /* MIATT */
2652             if (insn & (1 << 16))
2653                 tcg_gen_shri_i32(tcg_ctx, tmp, tmp, 16);
2654             if (insn & (1 << 17))
2655                 tcg_gen_shri_i32(tcg_ctx, tmp2, tmp2, 16);
2656             gen_helper_iwmmxt_muladdswl(tcg_ctx, tcg_ctx->cpu_M0, tcg_ctx->cpu_M0, tmp, tmp2);
2657             break;
2658         default:
2659             return 1;
2660         }
2661         tcg_temp_free_i32(tcg_ctx, tmp2);
2662         tcg_temp_free_i32(tcg_ctx, tmp);
2663 
2664         gen_op_iwmmxt_movq_wRn_M0(s, acc);
2665         return 0;
2666     }
2667 
2668     if ((insn & 0x0fe00ff8) == 0x0c400000) {
2669         /* Internal Accumulator Access Format */
2670         rdhi = (insn >> 16) & 0xf;
2671         rdlo = (insn >> 12) & 0xf;
2672         acc = insn & 7;
2673 
2674         if (acc != 0)
2675             return 1;
2676 
2677         if (insn & ARM_CP_RW_BIT) {         /* MRA */
2678             iwmmxt_load_reg(s, tcg_ctx->cpu_V0, acc);
2679             tcg_gen_trunc_i64_i32(tcg_ctx, tcg_ctx->cpu_R[rdlo], tcg_ctx->cpu_V0);
2680             tcg_gen_shri_i64(tcg_ctx, tcg_ctx->cpu_V0, tcg_ctx->cpu_V0, 32);
2681             tcg_gen_trunc_i64_i32(tcg_ctx, tcg_ctx->cpu_R[rdhi], tcg_ctx->cpu_V0);
2682             tcg_gen_andi_i32(tcg_ctx, tcg_ctx->cpu_R[rdhi], tcg_ctx->cpu_R[rdhi], (1 << (40 - 32)) - 1);
2683         } else {                    /* MAR */
2684             tcg_gen_concat_i32_i64(tcg_ctx, tcg_ctx->cpu_V0, tcg_ctx->cpu_R[rdlo], tcg_ctx->cpu_R[rdhi]);
2685             iwmmxt_store_reg(s, tcg_ctx->cpu_V0, acc);
2686         }
2687         return 0;
2688     }
2689 
2690     return 1;
2691 }
2692 
2693 // this causes "warning C4293: shift count negative or too big, undefined behavior"
2694 // on msvc, so is replaced with separate versions for the shift to perform.
2695 //#define VFP_REG_SHR(x, n) (((n) > 0) ? (x) >> (n) : (x) << -(n))
2696 #if 0
2697 #define VFP_SREG(insn, bigbit, smallbit) \
2698   ((VFP_REG_SHR(insn, bigbit - 1) & 0x1e) | (((insn) >> (smallbit)) & 1))
2699 #endif
2700 
2701 #define VFP_REG_SHR_NEG(insn, n) ((insn) << -(n))
2702 #define VFP_SREG_NEG(insn, bigbit, smallbit) \
2703   ((VFP_REG_SHR_NEG(insn, bigbit - 1) & 0x1e) | (((insn) >> (smallbit)) & 1))
2704 
2705 #define VFP_REG_SHR_POS(x, n) ((insn) >> (n))
2706 #define VFP_SREG_POS(insn, bigbit, smallbit) \
2707   ((VFP_REG_SHR_POS(insn, bigbit - 1) & 0x1e) | (((insn) >> (smallbit)) & 1))
2708 
2709 #define VFP_DREG(reg, insn, bigbit, smallbit) do { \
2710     if (arm_dc_feature(s, ARM_FEATURE_VFP3)) { \
2711         reg = (((insn) >> (bigbit)) & 0x0f) \
2712               | (((insn) >> ((smallbit) - 4)) & 0x10); \
2713     } else { \
2714         if (insn & (1 << (smallbit))) \
2715             return 1; \
2716         reg = ((insn) >> (bigbit)) & 0x0f; \
2717     }} while (0)
2718 
2719 #define VFP_SREG_D(insn) VFP_SREG_POS(insn, 12, 22)
2720 #define VFP_DREG_D(reg, insn) VFP_DREG(reg, insn, 12, 22)
2721 #define VFP_SREG_N(insn) VFP_SREG_POS(insn, 16,  7)
2722 #define VFP_DREG_N(reg, insn) VFP_DREG(reg, insn, 16,  7)
2723 #define VFP_SREG_M(insn) VFP_SREG_NEG(insn,  0,  5)
2724 #define VFP_DREG_M(reg, insn) VFP_DREG(reg, insn,  0,  5)
2725 
2726 /* Move between integer and VFP cores.  */
gen_vfp_mrs(DisasContext * s)2727 static TCGv_i32 gen_vfp_mrs(DisasContext *s)
2728 {
2729     TCGContext *tcg_ctx = s->uc->tcg_ctx;
2730     TCGv_i32 tmp = tcg_temp_new_i32(tcg_ctx);
2731     tcg_gen_mov_i32(tcg_ctx, tmp, tcg_ctx->cpu_F0s);
2732     return tmp;
2733 }
2734 
gen_vfp_msr(DisasContext * s,TCGv_i32 tmp)2735 static void gen_vfp_msr(DisasContext *s, TCGv_i32 tmp)
2736 {
2737     TCGContext *tcg_ctx = s->uc->tcg_ctx;
2738     tcg_gen_mov_i32(tcg_ctx, tcg_ctx->cpu_F0s, tmp);
2739     tcg_temp_free_i32(tcg_ctx, tmp);
2740 }
2741 
gen_neon_dup_u8(DisasContext * s,TCGv_i32 var,int shift)2742 static void gen_neon_dup_u8(DisasContext *s, TCGv_i32 var, int shift)
2743 {
2744     TCGContext *tcg_ctx = s->uc->tcg_ctx;
2745     TCGv_i32 tmp = tcg_temp_new_i32(tcg_ctx);
2746     if (shift)
2747         tcg_gen_shri_i32(tcg_ctx, var, var, shift);
2748     tcg_gen_ext8u_i32(tcg_ctx, var, var);
2749     tcg_gen_shli_i32(tcg_ctx, tmp, var, 8);
2750     tcg_gen_or_i32(tcg_ctx, var, var, tmp);
2751     tcg_gen_shli_i32(tcg_ctx, tmp, var, 16);
2752     tcg_gen_or_i32(tcg_ctx, var, var, tmp);
2753     tcg_temp_free_i32(tcg_ctx, tmp);
2754 }
2755 
gen_neon_dup_low16(DisasContext * s,TCGv_i32 var)2756 static void gen_neon_dup_low16(DisasContext *s, TCGv_i32 var)
2757 {
2758     TCGContext *tcg_ctx = s->uc->tcg_ctx;
2759     TCGv_i32 tmp = tcg_temp_new_i32(tcg_ctx);
2760     tcg_gen_ext16u_i32(tcg_ctx, var, var);
2761     tcg_gen_shli_i32(tcg_ctx, tmp, var, 16);
2762     tcg_gen_or_i32(tcg_ctx, var, var, tmp);
2763     tcg_temp_free_i32(tcg_ctx, tmp);
2764 }
2765 
gen_neon_dup_high16(DisasContext * s,TCGv_i32 var)2766 static void gen_neon_dup_high16(DisasContext *s, TCGv_i32 var)
2767 {
2768     TCGContext *tcg_ctx = s->uc->tcg_ctx;
2769     TCGv_i32 tmp = tcg_temp_new_i32(tcg_ctx);
2770     tcg_gen_andi_i32(tcg_ctx, var, var, 0xffff0000);
2771     tcg_gen_shri_i32(tcg_ctx, tmp, var, 16);
2772     tcg_gen_or_i32(tcg_ctx, var, var, tmp);
2773     tcg_temp_free_i32(tcg_ctx, tmp);
2774 }
2775 
gen_load_and_replicate(DisasContext * s,TCGv_i32 addr,int size)2776 static TCGv_i32 gen_load_and_replicate(DisasContext *s, TCGv_i32 addr, int size)
2777 {
2778     /* Load a single Neon element and replicate into a 32 bit TCG reg */
2779     TCGContext *tcg_ctx = s->uc->tcg_ctx;
2780     TCGv_i32 tmp = tcg_temp_new_i32(tcg_ctx);
2781     switch (size) {
2782     case 0:
2783         gen_aa32_ld8u(s, tmp, addr, get_mem_index(s));
2784         gen_neon_dup_u8(s, tmp, 0);
2785         break;
2786     case 1:
2787         gen_aa32_ld16u(s, tmp, addr, get_mem_index(s));
2788         gen_neon_dup_low16(s, tmp);
2789         break;
2790     case 2:
2791         gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
2792         break;
2793     default: /* Avoid compiler warnings.  */
2794         abort();
2795     }
2796     return tmp;
2797 }
2798 
handle_vsel(DisasContext * s,uint32_t insn,uint32_t rd,uint32_t rn,uint32_t rm,uint32_t dp)2799 static int handle_vsel(DisasContext *s, uint32_t insn, uint32_t rd, uint32_t rn, uint32_t rm,
2800                        uint32_t dp)
2801 {
2802     TCGContext *tcg_ctx = s->uc->tcg_ctx;
2803     uint32_t cc = extract32(insn, 20, 2);
2804 
2805     if (dp) {
2806         TCGv_i64 frn, frm, dest;
2807         TCGv_i64 tmp, zero, zf, nf, vf;
2808 
2809         zero = tcg_const_i64(tcg_ctx, 0);
2810 
2811         frn = tcg_temp_new_i64(tcg_ctx);
2812         frm = tcg_temp_new_i64(tcg_ctx);
2813         dest = tcg_temp_new_i64(tcg_ctx);
2814 
2815         zf = tcg_temp_new_i64(tcg_ctx);
2816         nf = tcg_temp_new_i64(tcg_ctx);
2817         vf = tcg_temp_new_i64(tcg_ctx);
2818 
2819         tcg_gen_extu_i32_i64(tcg_ctx, zf, tcg_ctx->cpu_ZF);
2820         tcg_gen_ext_i32_i64(tcg_ctx, nf, tcg_ctx->cpu_NF);
2821         tcg_gen_ext_i32_i64(tcg_ctx, vf, tcg_ctx->cpu_VF);
2822 
2823         tcg_gen_ld_f64(tcg_ctx, frn, tcg_ctx->cpu_env, vfp_reg_offset(dp, rn));
2824         tcg_gen_ld_f64(tcg_ctx, frm, tcg_ctx->cpu_env, vfp_reg_offset(dp, rm));
2825         switch (cc) {
2826         case 0: /* eq: Z */
2827             tcg_gen_movcond_i64(tcg_ctx, TCG_COND_EQ, dest, zf, zero,
2828                                 frn, frm);
2829             break;
2830         case 1: /* vs: V */
2831             tcg_gen_movcond_i64(tcg_ctx, TCG_COND_LT, dest, vf, zero,
2832                                 frn, frm);
2833             break;
2834         case 2: /* ge: N == V -> N ^ V == 0 */
2835             tmp = tcg_temp_new_i64(tcg_ctx);
2836             tcg_gen_xor_i64(tcg_ctx, tmp, vf, nf);
2837             tcg_gen_movcond_i64(tcg_ctx, TCG_COND_GE, dest, tmp, zero,
2838                                 frn, frm);
2839             tcg_temp_free_i64(tcg_ctx, tmp);
2840             break;
2841         case 3: /* gt: !Z && N == V */
2842             tcg_gen_movcond_i64(tcg_ctx, TCG_COND_NE, dest, zf, zero,
2843                                 frn, frm);
2844             tmp = tcg_temp_new_i64(tcg_ctx);
2845             tcg_gen_xor_i64(tcg_ctx, tmp, vf, nf);
2846             tcg_gen_movcond_i64(tcg_ctx, TCG_COND_GE, dest, tmp, zero,
2847                                 dest, frm);
2848             tcg_temp_free_i64(tcg_ctx, tmp);
2849             break;
2850         }
2851         tcg_gen_st_f64(tcg_ctx, dest, tcg_ctx->cpu_env, vfp_reg_offset(dp, rd));
2852         tcg_temp_free_i64(tcg_ctx, frn);
2853         tcg_temp_free_i64(tcg_ctx, frm);
2854         tcg_temp_free_i64(tcg_ctx, dest);
2855 
2856         tcg_temp_free_i64(tcg_ctx, zf);
2857         tcg_temp_free_i64(tcg_ctx, nf);
2858         tcg_temp_free_i64(tcg_ctx, vf);
2859 
2860         tcg_temp_free_i64(tcg_ctx, zero);
2861     } else {
2862         TCGv_i32 frn, frm, dest;
2863         TCGv_i32 tmp, zero;
2864 
2865         zero = tcg_const_i32(tcg_ctx, 0);
2866 
2867         frn = tcg_temp_new_i32(tcg_ctx);
2868         frm = tcg_temp_new_i32(tcg_ctx);
2869         dest = tcg_temp_new_i32(tcg_ctx);
2870         tcg_gen_ld_f32(tcg_ctx, frn, tcg_ctx->cpu_env, vfp_reg_offset(dp, rn));
2871         tcg_gen_ld_f32(tcg_ctx, frm, tcg_ctx->cpu_env, vfp_reg_offset(dp, rm));
2872         switch (cc) {
2873         case 0: /* eq: Z */
2874             tcg_gen_movcond_i32(tcg_ctx, TCG_COND_EQ, dest, tcg_ctx->cpu_ZF, zero,
2875                                 frn, frm);
2876             break;
2877         case 1: /* vs: V */
2878             tcg_gen_movcond_i32(tcg_ctx, TCG_COND_LT, dest, tcg_ctx->cpu_VF, zero,
2879                                 frn, frm);
2880             break;
2881         case 2: /* ge: N == V -> N ^ V == 0 */
2882             tmp = tcg_temp_new_i32(tcg_ctx);
2883             tcg_gen_xor_i32(tcg_ctx, tmp, tcg_ctx->cpu_VF, tcg_ctx->cpu_NF);
2884             tcg_gen_movcond_i32(tcg_ctx, TCG_COND_GE, dest, tmp, zero,
2885                                 frn, frm);
2886             tcg_temp_free_i32(tcg_ctx, tmp);
2887             break;
2888         case 3: /* gt: !Z && N == V */
2889             tcg_gen_movcond_i32(tcg_ctx, TCG_COND_NE, dest, tcg_ctx->cpu_ZF, zero,
2890                                 frn, frm);
2891             tmp = tcg_temp_new_i32(tcg_ctx);
2892             tcg_gen_xor_i32(tcg_ctx, tmp, tcg_ctx->cpu_VF, tcg_ctx->cpu_NF);
2893             tcg_gen_movcond_i32(tcg_ctx, TCG_COND_GE, dest, tmp, zero,
2894                                 dest, frm);
2895             tcg_temp_free_i32(tcg_ctx, tmp);
2896             break;
2897         }
2898         tcg_gen_st_f32(tcg_ctx, dest, tcg_ctx->cpu_env, vfp_reg_offset(dp, rd));
2899         tcg_temp_free_i32(tcg_ctx, frn);
2900         tcg_temp_free_i32(tcg_ctx, frm);
2901         tcg_temp_free_i32(tcg_ctx, dest);
2902 
2903         tcg_temp_free_i32(tcg_ctx, zero);
2904     }
2905 
2906     return 0;
2907 }
2908 
handle_vminmaxnm(DisasContext * s,uint32_t insn,uint32_t rd,uint32_t rn,uint32_t rm,uint32_t dp)2909 static int handle_vminmaxnm(DisasContext *s, uint32_t insn, uint32_t rd, uint32_t rn,
2910                             uint32_t rm, uint32_t dp)
2911 {
2912     TCGContext *tcg_ctx = s->uc->tcg_ctx;
2913     uint32_t vmin = extract32(insn, 6, 1);
2914     TCGv_ptr fpst = get_fpstatus_ptr(s, 0);
2915 
2916     if (dp) {
2917         TCGv_i64 frn, frm, dest;
2918 
2919         frn = tcg_temp_new_i64(tcg_ctx);
2920         frm = tcg_temp_new_i64(tcg_ctx);
2921         dest = tcg_temp_new_i64(tcg_ctx);
2922 
2923         tcg_gen_ld_f64(tcg_ctx, frn, tcg_ctx->cpu_env, vfp_reg_offset(dp, rn));
2924         tcg_gen_ld_f64(tcg_ctx, frm, tcg_ctx->cpu_env, vfp_reg_offset(dp, rm));
2925         if (vmin) {
2926             gen_helper_vfp_minnumd(tcg_ctx, dest, frn, frm, fpst);
2927         } else {
2928             gen_helper_vfp_maxnumd(tcg_ctx, dest, frn, frm, fpst);
2929         }
2930         tcg_gen_st_f64(tcg_ctx, dest, tcg_ctx->cpu_env, vfp_reg_offset(dp, rd));
2931         tcg_temp_free_i64(tcg_ctx, frn);
2932         tcg_temp_free_i64(tcg_ctx, frm);
2933         tcg_temp_free_i64(tcg_ctx, dest);
2934     } else {
2935         TCGv_i32 frn, frm, dest;
2936 
2937         frn = tcg_temp_new_i32(tcg_ctx);
2938         frm = tcg_temp_new_i32(tcg_ctx);
2939         dest = tcg_temp_new_i32(tcg_ctx);
2940 
2941         tcg_gen_ld_f32(tcg_ctx, frn, tcg_ctx->cpu_env, vfp_reg_offset(dp, rn));
2942         tcg_gen_ld_f32(tcg_ctx, frm, tcg_ctx->cpu_env, vfp_reg_offset(dp, rm));
2943         if (vmin) {
2944             gen_helper_vfp_minnums(tcg_ctx, dest, frn, frm, fpst);
2945         } else {
2946             gen_helper_vfp_maxnums(tcg_ctx, dest, frn, frm, fpst);
2947         }
2948         tcg_gen_st_f32(tcg_ctx, dest, tcg_ctx->cpu_env, vfp_reg_offset(dp, rd));
2949         tcg_temp_free_i32(tcg_ctx, frn);
2950         tcg_temp_free_i32(tcg_ctx, frm);
2951         tcg_temp_free_i32(tcg_ctx, dest);
2952     }
2953 
2954     tcg_temp_free_ptr(tcg_ctx, fpst);
2955     return 0;
2956 }
2957 
handle_vrint(DisasContext * s,uint32_t insn,uint32_t rd,uint32_t rm,uint32_t dp,int rounding)2958 static int handle_vrint(DisasContext *s, uint32_t insn, uint32_t rd, uint32_t rm, uint32_t dp,
2959                         int rounding)
2960 {
2961     TCGContext *tcg_ctx = s->uc->tcg_ctx;
2962     TCGv_ptr fpst = get_fpstatus_ptr(s, 0);
2963     TCGv_i32 tcg_rmode;
2964 
2965     tcg_rmode = tcg_const_i32(tcg_ctx, arm_rmode_to_sf(rounding));
2966     gen_helper_set_rmode(tcg_ctx, tcg_rmode, tcg_rmode, tcg_ctx->cpu_env);
2967 
2968     if (dp) {
2969         TCGv_i64 tcg_op;
2970         TCGv_i64 tcg_res;
2971         tcg_op = tcg_temp_new_i64(tcg_ctx);
2972         tcg_res = tcg_temp_new_i64(tcg_ctx);
2973         tcg_gen_ld_f64(tcg_ctx, tcg_op, tcg_ctx->cpu_env, vfp_reg_offset(dp, rm));
2974         gen_helper_rintd(tcg_ctx, tcg_res, tcg_op, fpst);
2975         tcg_gen_st_f64(tcg_ctx, tcg_res, tcg_ctx->cpu_env, vfp_reg_offset(dp, rd));
2976         tcg_temp_free_i64(tcg_ctx, tcg_op);
2977         tcg_temp_free_i64(tcg_ctx, tcg_res);
2978     } else {
2979         TCGv_i32 tcg_op;
2980         TCGv_i32 tcg_res;
2981         tcg_op = tcg_temp_new_i32(tcg_ctx);
2982         tcg_res = tcg_temp_new_i32(tcg_ctx);
2983         tcg_gen_ld_f32(tcg_ctx, tcg_op, tcg_ctx->cpu_env, vfp_reg_offset(dp, rm));
2984         gen_helper_rints(tcg_ctx, tcg_res, tcg_op, fpst);
2985         tcg_gen_st_f32(tcg_ctx, tcg_res, tcg_ctx->cpu_env, vfp_reg_offset(dp, rd));
2986         tcg_temp_free_i32(tcg_ctx, tcg_op);
2987         tcg_temp_free_i32(tcg_ctx, tcg_res);
2988     }
2989 
2990     gen_helper_set_rmode(tcg_ctx, tcg_rmode, tcg_rmode, tcg_ctx->cpu_env);
2991     tcg_temp_free_i32(tcg_ctx, tcg_rmode);
2992 
2993     tcg_temp_free_ptr(tcg_ctx, fpst);
2994     return 0;
2995 }
2996 
handle_vcvt(DisasContext * s,uint32_t insn,uint32_t rd,uint32_t rm,uint32_t dp,int rounding)2997 static int handle_vcvt(DisasContext *s, uint32_t insn, uint32_t rd, uint32_t rm, uint32_t dp,
2998                        int rounding)
2999 {
3000     TCGContext *tcg_ctx = s->uc->tcg_ctx;
3001     bool is_signed = extract32(insn, 7, 1);
3002     TCGv_ptr fpst = get_fpstatus_ptr(s, 0);
3003     TCGv_i32 tcg_rmode, tcg_shift;
3004 
3005     tcg_shift = tcg_const_i32(tcg_ctx, 0);
3006 
3007     tcg_rmode = tcg_const_i32(tcg_ctx, arm_rmode_to_sf(rounding));
3008     gen_helper_set_rmode(tcg_ctx, tcg_rmode, tcg_rmode, tcg_ctx->cpu_env);
3009 
3010     if (dp) {
3011         TCGv_i64 tcg_double, tcg_res;
3012         TCGv_i32 tcg_tmp;
3013         /* Rd is encoded as a single precision register even when the source
3014          * is double precision.
3015          */
3016         rd = ((rd << 1) & 0x1e) | ((rd >> 4) & 0x1);
3017         tcg_double = tcg_temp_new_i64(tcg_ctx);
3018         tcg_res = tcg_temp_new_i64(tcg_ctx);
3019         tcg_tmp = tcg_temp_new_i32(tcg_ctx);
3020         tcg_gen_ld_f64(tcg_ctx, tcg_double, tcg_ctx->cpu_env, vfp_reg_offset(1, rm));
3021         if (is_signed) {
3022             gen_helper_vfp_tosld(tcg_ctx, tcg_res, tcg_double, tcg_shift, fpst);
3023         } else {
3024             gen_helper_vfp_tould(tcg_ctx, tcg_res, tcg_double, tcg_shift, fpst);
3025         }
3026         tcg_gen_trunc_i64_i32(tcg_ctx, tcg_tmp, tcg_res);
3027         tcg_gen_st_f32(tcg_ctx, tcg_tmp, tcg_ctx->cpu_env, vfp_reg_offset(0, rd));
3028         tcg_temp_free_i32(tcg_ctx, tcg_tmp);
3029         tcg_temp_free_i64(tcg_ctx, tcg_res);
3030         tcg_temp_free_i64(tcg_ctx, tcg_double);
3031     } else {
3032         TCGv_i32 tcg_single, tcg_res;
3033         tcg_single = tcg_temp_new_i32(tcg_ctx);
3034         tcg_res = tcg_temp_new_i32(tcg_ctx);
3035         tcg_gen_ld_f32(tcg_ctx, tcg_single, tcg_ctx->cpu_env, vfp_reg_offset(0, rm));
3036         if (is_signed) {
3037             gen_helper_vfp_tosls(tcg_ctx, tcg_res, tcg_single, tcg_shift, fpst);
3038         } else {
3039             gen_helper_vfp_touls(tcg_ctx, tcg_res, tcg_single, tcg_shift, fpst);
3040         }
3041         tcg_gen_st_f32(tcg_ctx, tcg_res, tcg_ctx->cpu_env, vfp_reg_offset(0, rd));
3042         tcg_temp_free_i32(tcg_ctx, tcg_res);
3043         tcg_temp_free_i32(tcg_ctx, tcg_single);
3044     }
3045 
3046     gen_helper_set_rmode(tcg_ctx, tcg_rmode, tcg_rmode, tcg_ctx->cpu_env);
3047     tcg_temp_free_i32(tcg_ctx, tcg_rmode);
3048 
3049     tcg_temp_free_i32(tcg_ctx, tcg_shift);
3050 
3051     tcg_temp_free_ptr(tcg_ctx, fpst);
3052 
3053     return 0;
3054 }
3055 
3056 /* Table for converting the most common AArch32 encoding of
3057  * rounding mode to arm_fprounding order (which matches the
3058  * common AArch64 order); see ARM ARM pseudocode FPDecodeRM().
3059  */
3060 static const uint8_t fp_decode_rm[] = {
3061     FPROUNDING_TIEAWAY,
3062     FPROUNDING_TIEEVEN,
3063     FPROUNDING_POSINF,
3064     FPROUNDING_NEGINF,
3065 };
3066 
disas_vfp_v8_insn(DisasContext * s,uint32_t insn)3067 static int disas_vfp_v8_insn(DisasContext *s, uint32_t insn)
3068 {
3069     uint32_t rd, rn, rm, dp = extract32(insn, 8, 1);
3070 
3071     if (!arm_dc_feature(s, ARM_FEATURE_V8)) {
3072         return 1;
3073     }
3074 
3075     if (dp) {
3076         VFP_DREG_D(rd, insn);
3077         VFP_DREG_N(rn, insn);
3078         VFP_DREG_M(rm, insn);
3079     } else {
3080         rd = VFP_SREG_D(insn);
3081         rn = VFP_SREG_N(insn);
3082         rm = VFP_SREG_M(insn);
3083     }
3084 
3085     if ((insn & 0x0f800e50) == 0x0e000a00) {
3086         return handle_vsel(s, insn, rd, rn, rm, dp);
3087     } else if ((insn & 0x0fb00e10) == 0x0e800a00) {
3088         return handle_vminmaxnm(s, insn, rd, rn, rm, dp);
3089     } else if ((insn & 0x0fbc0ed0) == 0x0eb80a40) {
3090         /* VRINTA, VRINTN, VRINTP, VRINTM */
3091         int rounding = fp_decode_rm[extract32(insn, 16, 2)];
3092         return handle_vrint(s, insn, rd, rm, dp, rounding);
3093     } else if ((insn & 0x0fbc0e50) == 0x0ebc0a40) {
3094         /* VCVTA, VCVTN, VCVTP, VCVTM */
3095         int rounding = fp_decode_rm[extract32(insn, 16, 2)];
3096         return handle_vcvt(s, insn, rd, rm, dp, rounding);
3097     }
3098     return 1;
3099 }
3100 
3101 /* Disassemble a VFP instruction.  Returns nonzero if an error occurred
3102    (ie. an undefined instruction).  */
disas_vfp_insn(DisasContext * s,uint32_t insn)3103 static int disas_vfp_insn(DisasContext *s, uint32_t insn)
3104 {
3105     TCGContext *tcg_ctx = s->uc->tcg_ctx;
3106     uint32_t rd, rn, rm, op, i, n, offset, delta_d, delta_m, bank_mask;
3107     int dp, veclen;
3108     TCGv_i32 addr;
3109     TCGv_i32 tmp;
3110     TCGv_i32 tmp2;
3111 
3112     if (!arm_dc_feature(s, ARM_FEATURE_VFP)) {
3113         return 1;
3114     }
3115 
3116     /* FIXME: this access check should not take precedence over UNDEF
3117      * for invalid encodings; we will generate incorrect syndrome information
3118      * for attempts to execute invalid vfp/neon encodings with FP disabled.
3119      */
3120     if (!s->cpacr_fpen) {
3121         gen_exception_insn(s, 4, EXCP_UDEF,
3122                            syn_fp_access_trap(1, 0xe, s->thumb));
3123         return 0;
3124     }
3125 
3126     if (!s->vfp_enabled) {
3127         /* VFP disabled.  Only allow fmxr/fmrx to/from some control regs.  */
3128         if ((insn & 0x0fe00fff) != 0x0ee00a10)
3129             return 1;
3130         rn = (insn >> 16) & 0xf;
3131         if (rn != ARM_VFP_FPSID && rn != ARM_VFP_FPEXC && rn != ARM_VFP_MVFR2
3132             && rn != ARM_VFP_MVFR1 && rn != ARM_VFP_MVFR0) {
3133             return 1;
3134         }
3135     }
3136 
3137     if (extract32(insn, 28, 4) == 0xf) {
3138         /* Encodings with T=1 (Thumb) or unconditional (ARM):
3139          * only used in v8 and above.
3140          */
3141         return disas_vfp_v8_insn(s, insn);
3142     }
3143 
3144     dp = ((insn & 0xf00) == 0xb00);
3145     switch ((insn >> 24) & 0xf) {
3146     case 0xe:
3147         if (insn & (1 << 4)) {
3148             /* single register transfer */
3149             rd = (insn >> 12) & 0xf;
3150             if (dp) {
3151                 int size;
3152                 int pass;
3153 
3154                 VFP_DREG_N(rn, insn);
3155                 if (insn & 0xf)
3156                     return 1;
3157                 if (insn & 0x00c00060
3158                     && !arm_dc_feature(s, ARM_FEATURE_NEON)) {
3159                     return 1;
3160                 }
3161 
3162                 pass = (insn >> 21) & 1;
3163                 if (insn & (1 << 22)) {
3164                     size = 0;
3165                     offset = ((insn >> 5) & 3) * 8;
3166                 } else if (insn & (1 << 5)) {
3167                     size = 1;
3168                     offset = (insn & (1 << 6)) ? 16 : 0;
3169                 } else {
3170                     size = 2;
3171                     offset = 0;
3172                 }
3173                 if (insn & ARM_CP_RW_BIT) {
3174                     /* vfp->arm */
3175                     tmp = neon_load_reg(tcg_ctx, rn, pass);
3176                     switch (size) {
3177                     case 0:
3178                         if (offset)
3179                             tcg_gen_shri_i32(tcg_ctx, tmp, tmp, offset);
3180                         if (insn & (1 << 23))
3181                             gen_uxtb(tmp);
3182                         else
3183                             gen_sxtb(tmp);
3184                         break;
3185                     case 1:
3186                         if (insn & (1 << 23)) {
3187                             if (offset) {
3188                                 tcg_gen_shri_i32(tcg_ctx, tmp, tmp, 16);
3189                             } else {
3190                                 gen_uxth(tmp);
3191                             }
3192                         } else {
3193                             if (offset) {
3194                                 tcg_gen_sari_i32(tcg_ctx, tmp, tmp, 16);
3195                             } else {
3196                                 gen_sxth(tmp);
3197                             }
3198                         }
3199                         break;
3200                     case 2:
3201                         break;
3202                     }
3203                     store_reg(s, rd, tmp);
3204                 } else {
3205                     /* arm->vfp */
3206                     tmp = load_reg(s, rd);
3207                     if (insn & (1 << 23)) {
3208                         /* VDUP */
3209                         if (size == 0) {
3210                             gen_neon_dup_u8(s, tmp, 0);
3211                         } else if (size == 1) {
3212                             gen_neon_dup_low16(s, tmp);
3213                         }
3214                         for (n = 0; n <= pass * 2; n++) {
3215                             tmp2 = tcg_temp_new_i32(tcg_ctx);
3216                             tcg_gen_mov_i32(tcg_ctx, tmp2, tmp);
3217                             neon_store_reg(tcg_ctx, rn, n, tmp2);
3218                         }
3219                         neon_store_reg(tcg_ctx, rn, n, tmp);
3220                     } else {
3221                         /* VMOV */
3222                         switch (size) {
3223                         case 0:
3224                             tmp2 = neon_load_reg(tcg_ctx, rn, pass);
3225                             tcg_gen_deposit_i32(tcg_ctx, tmp, tmp2, tmp, offset, 8);
3226                             tcg_temp_free_i32(tcg_ctx, tmp2);
3227                             break;
3228                         case 1:
3229                             tmp2 = neon_load_reg(tcg_ctx, rn, pass);
3230                             tcg_gen_deposit_i32(tcg_ctx, tmp, tmp2, tmp, offset, 16);
3231                             tcg_temp_free_i32(tcg_ctx, tmp2);
3232                             break;
3233                         case 2:
3234                             break;
3235                         }
3236                         neon_store_reg(tcg_ctx, rn, pass, tmp);
3237                     }
3238                 }
3239             } else { /* !dp */
3240                 if ((insn & 0x6f) != 0x00)
3241                     return 1;
3242                 rn = VFP_SREG_N(insn);
3243                 if (insn & ARM_CP_RW_BIT) {
3244                     /* vfp->arm */
3245                     if (insn & (1 << 21)) {
3246                         /* system register */
3247                         rn >>= 1;
3248 
3249                         switch (rn) {
3250                         case ARM_VFP_FPSID:
3251                             /* VFP2 allows access to FSID from userspace.
3252                                VFP3 restricts all id registers to privileged
3253                                accesses.  */
3254                             if (IS_USER(s)
3255                                 && arm_dc_feature(s, ARM_FEATURE_VFP3)) {
3256                                 return 1;
3257                             }
3258                             tmp = load_cpu_field(s->uc, vfp.xregs[rn]);
3259                             break;
3260                         case ARM_VFP_FPEXC:
3261                             if (IS_USER(s))
3262                                 return 1;
3263                             tmp = load_cpu_field(s->uc, vfp.xregs[rn]);
3264                             break;
3265                         case ARM_VFP_FPINST:
3266                         case ARM_VFP_FPINST2:
3267                             /* Not present in VFP3.  */
3268                             if (IS_USER(s)
3269                                 || arm_dc_feature(s, ARM_FEATURE_VFP3)) {
3270                                 return 1;
3271                             }
3272                             tmp = load_cpu_field(s->uc, vfp.xregs[rn]);
3273                             break;
3274                         case ARM_VFP_FPSCR:
3275                             if (rd == 15) {
3276                                 tmp = load_cpu_field(s->uc, vfp.xregs[ARM_VFP_FPSCR]);
3277                                 tcg_gen_andi_i32(tcg_ctx, tmp, tmp, 0xf0000000);
3278                             } else {
3279                                 tmp = tcg_temp_new_i32(tcg_ctx);
3280                                 gen_helper_vfp_get_fpscr(tcg_ctx, tmp, tcg_ctx->cpu_env);
3281                             }
3282                             break;
3283                         case ARM_VFP_MVFR2:
3284                             if (!arm_dc_feature(s, ARM_FEATURE_V8)) {
3285                                 return 1;
3286                             }
3287                             /* fall through */
3288                         case ARM_VFP_MVFR0:
3289                         case ARM_VFP_MVFR1:
3290                             if (IS_USER(s)
3291                                 || !arm_dc_feature(s, ARM_FEATURE_MVFR)) {
3292                                 return 1;
3293                             }
3294                             tmp = load_cpu_field(s->uc, vfp.xregs[rn]);
3295                             break;
3296                         default:
3297                             return 1;
3298                         }
3299                     } else {
3300                         gen_mov_F0_vreg(s, 0, rn);
3301                         tmp = gen_vfp_mrs(s);
3302                     }
3303                     if (rd == 15) {
3304                         /* Set the 4 flag bits in the CPSR.  */
3305                         gen_set_nzcv(s, tmp);
3306                         tcg_temp_free_i32(tcg_ctx, tmp);
3307                     } else {
3308                         store_reg(s, rd, tmp);
3309                     }
3310                 } else {
3311                     /* arm->vfp */
3312                     if (insn & (1 << 21)) {
3313                         rn >>= 1;
3314                         /* system register */
3315                         switch (rn) {
3316                         case ARM_VFP_FPSID:
3317                         case ARM_VFP_MVFR0:
3318                         case ARM_VFP_MVFR1:
3319                             /* Writes are ignored.  */
3320                             break;
3321                         case ARM_VFP_FPSCR:
3322                             tmp = load_reg(s, rd);
3323                             gen_helper_vfp_set_fpscr(tcg_ctx, tcg_ctx->cpu_env, tmp);
3324                             tcg_temp_free_i32(tcg_ctx, tmp);
3325                             gen_lookup_tb(s);
3326                             break;
3327                         case ARM_VFP_FPEXC:
3328                             if (IS_USER(s))
3329                                 return 1;
3330                             /* TODO: VFP subarchitecture support.
3331                              * For now, keep the EN bit only */
3332                             tmp = load_reg(s, rd);
3333                             tcg_gen_andi_i32(tcg_ctx, tmp, tmp, 1 << 30);
3334                             store_cpu_field(tcg_ctx, tmp, vfp.xregs[rn]);
3335                             gen_lookup_tb(s);
3336                             break;
3337                         case ARM_VFP_FPINST:
3338                         case ARM_VFP_FPINST2:
3339                             if (IS_USER(s)) {
3340                                 return 1;
3341                             }
3342                             tmp = load_reg(s, rd);
3343                             store_cpu_field(tcg_ctx, tmp, vfp.xregs[rn]);
3344                             break;
3345                         default:
3346                             return 1;
3347                         }
3348                     } else {
3349                         tmp = load_reg(s, rd);
3350                         gen_vfp_msr(s, tmp);
3351                         gen_mov_vreg_F0(s, 0, rn);
3352                     }
3353                 }
3354             }
3355         } else {
3356             /* data processing */
3357             /* The opcode is in bits 23, 21, 20 and 6.  */
3358             op = ((insn >> 20) & 8) | ((insn >> 19) & 6) | ((insn >> 6) & 1);
3359             if (dp) {
3360                 if (op == 15) {
3361                     /* rn is opcode */
3362                     rn = ((insn >> 15) & 0x1e) | ((insn >> 7) & 1);
3363                 } else {
3364                     /* rn is register number */
3365                     VFP_DREG_N(rn, insn);
3366                 }
3367 
3368                 if (op == 15 && (rn == 15 || ((rn & 0x1c) == 0x18) ||
3369                                  ((rn & 0x1e) == 0x6))) {
3370                     /* Integer or single/half precision destination.  */
3371                     rd = VFP_SREG_D(insn);
3372                 } else {
3373                     VFP_DREG_D(rd, insn);
3374                 }
3375                 if (op == 15 &&
3376                     (((rn & 0x1c) == 0x10) || ((rn & 0x14) == 0x14) ||
3377                      ((rn & 0x1e) == 0x4))) {
3378                     /* VCVT from int or half precision is always from S reg
3379                      * regardless of dp bit. VCVT with immediate frac_bits
3380                      * has same format as SREG_M.
3381                      */
3382                     rm = VFP_SREG_M(insn);
3383                 } else {
3384                     VFP_DREG_M(rm, insn);
3385                 }
3386             } else {
3387                 rn = VFP_SREG_N(insn);
3388                 if (op == 15 && rn == 15) {
3389                     /* Double precision destination.  */
3390                     VFP_DREG_D(rd, insn);
3391                 } else {
3392                     rd = VFP_SREG_D(insn);
3393                 }
3394                 /* NB that we implicitly rely on the encoding for the frac_bits
3395                  * in VCVT of fixed to float being the same as that of an SREG_M
3396                  */
3397                 rm = VFP_SREG_M(insn);
3398             }
3399 
3400             veclen = s->vec_len;
3401             if (op == 15 && rn > 3)
3402                 veclen = 0;
3403 
3404             /* Shut up compiler warnings.  */
3405             delta_m = 0;
3406             delta_d = 0;
3407             bank_mask = 0;
3408 
3409             if (veclen > 0) {
3410                 if (dp)
3411                     bank_mask = 0xc;
3412                 else
3413                     bank_mask = 0x18;
3414 
3415                 /* Figure out what type of vector operation this is.  */
3416                 if ((rd & bank_mask) == 0) {
3417                     /* scalar */
3418                     veclen = 0;
3419                 } else {
3420                     if (dp)
3421                         delta_d = (s->vec_stride >> 1) + 1;
3422                     else
3423                         delta_d = s->vec_stride + 1;
3424 
3425                     if ((rm & bank_mask) == 0) {
3426                         /* mixed scalar/vector */
3427                         delta_m = 0;
3428                     } else {
3429                         /* vector */
3430                         delta_m = delta_d;
3431                     }
3432                 }
3433             }
3434 
3435             /* Load the initial operands.  */
3436             if (op == 15) {
3437                 switch (rn) {
3438                 case 16:
3439                 case 17:
3440                     /* Integer source */
3441                     gen_mov_F0_vreg(s, 0, rm);
3442                     break;
3443                 case 8:
3444                 case 9:
3445                     /* Compare */
3446                     gen_mov_F0_vreg(s, dp, rd);
3447                     gen_mov_F1_vreg(s, dp, rm);
3448                     break;
3449                 case 10:
3450                 case 11:
3451                     /* Compare with zero */
3452                     gen_mov_F0_vreg(s, dp, rd);
3453                     gen_vfp_F1_ld0(s, dp);
3454                     break;
3455                 case 20:
3456                 case 21:
3457                 case 22:
3458                 case 23:
3459                 case 28:
3460                 case 29:
3461                 case 30:
3462                 case 31:
3463                     /* Source and destination the same.  */
3464                     gen_mov_F0_vreg(s, dp, rd);
3465                     break;
3466                 case 4:
3467                 case 5:
3468                 case 6:
3469                 case 7:
3470                     /* VCVTB, VCVTT: only present with the halfprec extension
3471                      * UNPREDICTABLE if bit 8 is set prior to ARMv8
3472                      * (we choose to UNDEF)
3473                      */
3474                     if ((dp && !arm_dc_feature(s, ARM_FEATURE_V8)) ||
3475                         !arm_dc_feature(s, ARM_FEATURE_VFP_FP16)) {
3476                         return 1;
3477                     }
3478                     if (!extract32(rn, 1, 1)) {
3479                         /* Half precision source.  */
3480                         gen_mov_F0_vreg(s, 0, rm);
3481                         break;
3482                     }
3483                     /* Otherwise fall through */
3484                 default:
3485                     /* One source operand.  */
3486                     gen_mov_F0_vreg(s, dp, rm);
3487                     break;
3488                 }
3489             } else {
3490                 /* Two source operands.  */
3491                 gen_mov_F0_vreg(s, dp, rn);
3492                 gen_mov_F1_vreg(s, dp, rm);
3493             }
3494 
3495             for (;;) {
3496                 /* Perform the calculation.  */
3497                 switch (op) {
3498                 case 0: /* VMLA: fd + (fn * fm) */
3499                     /* Note that order of inputs to the add matters for NaNs */
3500                     gen_vfp_F1_mul(s, dp);
3501                     gen_mov_F0_vreg(s, dp, rd);
3502                     gen_vfp_add(s, dp);
3503                     break;
3504                 case 1: /* VMLS: fd + -(fn * fm) */
3505                     gen_vfp_mul(s, dp);
3506                     gen_vfp_F1_neg(s, dp);
3507                     gen_mov_F0_vreg(s, dp, rd);
3508                     gen_vfp_add(s, dp);
3509                     break;
3510                 case 2: /* VNMLS: -fd + (fn * fm) */
3511                     /* Note that it isn't valid to replace (-A + B) with (B - A)
3512                      * or similar plausible looking simplifications
3513                      * because this will give wrong results for NaNs.
3514                      */
3515                     gen_vfp_F1_mul(s, dp);
3516                     gen_mov_F0_vreg(s, dp, rd);
3517                     gen_vfp_neg(s, dp);
3518                     gen_vfp_add(s, dp);
3519                     break;
3520                 case 3: /* VNMLA: -fd + -(fn * fm) */
3521                     gen_vfp_mul(s, dp);
3522                     gen_vfp_F1_neg(s, dp);
3523                     gen_mov_F0_vreg(s, dp, rd);
3524                     gen_vfp_neg(s, dp);
3525                     gen_vfp_add(s, dp);
3526                     break;
3527                 case 4: /* mul: fn * fm */
3528                     gen_vfp_mul(s, dp);
3529                     break;
3530                 case 5: /* nmul: -(fn * fm) */
3531                     gen_vfp_mul(s, dp);
3532                     gen_vfp_neg(s, dp);
3533                     break;
3534                 case 6: /* add: fn + fm */
3535                     gen_vfp_add(s, dp);
3536                     break;
3537                 case 7: /* sub: fn - fm */
3538                     gen_vfp_sub(s, dp);
3539                     break;
3540                 case 8: /* div: fn / fm */
3541                     gen_vfp_div(s, dp);
3542                     break;
3543                 case 10: /* VFNMA : fd = muladd(-fd,  fn, fm) */
3544                 case 11: /* VFNMS : fd = muladd(-fd, -fn, fm) */
3545                 case 12: /* VFMA  : fd = muladd( fd,  fn, fm) */
3546                 case 13: /* VFMS  : fd = muladd( fd, -fn, fm) */
3547                     /* These are fused multiply-add, and must be done as one
3548                      * floating point operation with no rounding between the
3549                      * multiplication and addition steps.
3550                      * NB that doing the negations here as separate steps is
3551                      * correct : an input NaN should come out with its sign bit
3552                      * flipped if it is a negated-input.
3553                      */
3554                     if (!arm_dc_feature(s, ARM_FEATURE_VFP4)) {
3555                         return 1;
3556                     }
3557                     if (dp) {
3558                         TCGv_ptr fpst;
3559                         TCGv_i64 frd;
3560                         if (op & 1) {
3561                             /* VFNMS, VFMS */
3562                             gen_helper_vfp_negd(tcg_ctx, tcg_ctx->cpu_F0d, tcg_ctx->cpu_F0d);
3563                         }
3564                         frd = tcg_temp_new_i64(tcg_ctx);
3565                         tcg_gen_ld_f64(tcg_ctx, frd, tcg_ctx->cpu_env, vfp_reg_offset(dp, rd));
3566                         if (op & 2) {
3567                             /* VFNMA, VFNMS */
3568                             gen_helper_vfp_negd(tcg_ctx, frd, frd);
3569                         }
3570                         fpst = get_fpstatus_ptr(s, 0);
3571                         gen_helper_vfp_muladdd(tcg_ctx, tcg_ctx->cpu_F0d, tcg_ctx->cpu_F0d,
3572                                                tcg_ctx->cpu_F1d, frd, fpst);
3573                         tcg_temp_free_ptr(tcg_ctx, fpst);
3574                         tcg_temp_free_i64(tcg_ctx, frd);
3575                     } else {
3576                         TCGv_ptr fpst;
3577                         TCGv_i32 frd;
3578                         if (op & 1) {
3579                             /* VFNMS, VFMS */
3580                             gen_helper_vfp_negs(tcg_ctx, tcg_ctx->cpu_F0s, tcg_ctx->cpu_F0s);
3581                         }
3582                         frd = tcg_temp_new_i32(tcg_ctx);
3583                         tcg_gen_ld_f32(tcg_ctx, frd, tcg_ctx->cpu_env, vfp_reg_offset(dp, rd));
3584                         if (op & 2) {
3585                             gen_helper_vfp_negs(tcg_ctx, frd, frd);
3586                         }
3587                         fpst = get_fpstatus_ptr(s, 0);
3588                         gen_helper_vfp_muladds(tcg_ctx, tcg_ctx->cpu_F0s, tcg_ctx->cpu_F0s,
3589                                                tcg_ctx->cpu_F1s, frd, fpst);
3590                         tcg_temp_free_ptr(tcg_ctx, fpst);
3591                         tcg_temp_free_i32(tcg_ctx, frd);
3592                     }
3593                     break;
3594                 case 14: /* fconst */
3595                     if (!arm_dc_feature(s, ARM_FEATURE_VFP3)) {
3596                         return 1;
3597                     }
3598 
3599                     n = (insn << 12) & 0x80000000;
3600                     i = ((insn >> 12) & 0x70) | (insn & 0xf);
3601                     if (dp) {
3602                         if (i & 0x40)
3603                             i |= 0x3f80;
3604                         else
3605                             i |= 0x4000;
3606                         n |= i << 16;
3607                         tcg_gen_movi_i64(tcg_ctx, tcg_ctx->cpu_F0d, ((uint64_t)n) << 32);
3608                     } else {
3609                         if (i & 0x40)
3610                             i |= 0x780;
3611                         else
3612                             i |= 0x800;
3613                         n |= i << 19;
3614                         tcg_gen_movi_i32(tcg_ctx, tcg_ctx->cpu_F0s, n);
3615                     }
3616                     break;
3617                 case 15: /* extension space */
3618                     switch (rn) {
3619                     case 0: /* cpy */
3620                         /* no-op */
3621                         break;
3622                     case 1: /* abs */
3623                         gen_vfp_abs(s, dp);
3624                         break;
3625                     case 2: /* neg */
3626                         gen_vfp_neg(s, dp);
3627                         break;
3628                     case 3: /* sqrt */
3629                         gen_vfp_sqrt(s, dp);
3630                         break;
3631                     case 4: /* vcvtb.f32.f16, vcvtb.f64.f16 */
3632                         tmp = gen_vfp_mrs(s);
3633                         tcg_gen_ext16u_i32(tcg_ctx, tmp, tmp);
3634                         if (dp) {
3635                             gen_helper_vfp_fcvt_f16_to_f64(tcg_ctx, tcg_ctx->cpu_F0d, tmp,
3636                                                            tcg_ctx->cpu_env);
3637                         } else {
3638                             gen_helper_vfp_fcvt_f16_to_f32(tcg_ctx, tcg_ctx->cpu_F0s, tmp,
3639                                                            tcg_ctx->cpu_env);
3640                         }
3641                         tcg_temp_free_i32(tcg_ctx, tmp);
3642                         break;
3643                     case 5: /* vcvtt.f32.f16, vcvtt.f64.f16 */
3644                         tmp = gen_vfp_mrs(s);
3645                         tcg_gen_shri_i32(tcg_ctx, tmp, tmp, 16);
3646                         if (dp) {
3647                             gen_helper_vfp_fcvt_f16_to_f64(tcg_ctx, tcg_ctx->cpu_F0d, tmp,
3648                                                            tcg_ctx->cpu_env);
3649                         } else {
3650                             gen_helper_vfp_fcvt_f16_to_f32(tcg_ctx, tcg_ctx->cpu_F0s, tmp,
3651                                                            tcg_ctx->cpu_env);
3652                         }
3653                         tcg_temp_free_i32(tcg_ctx, tmp);
3654                         break;
3655                     case 6: /* vcvtb.f16.f32, vcvtb.f16.f64 */
3656                         tmp = tcg_temp_new_i32(tcg_ctx);
3657                         if (dp) {
3658                             gen_helper_vfp_fcvt_f64_to_f16(tcg_ctx, tmp, tcg_ctx->cpu_F0d,
3659                                                            tcg_ctx->cpu_env);
3660                         } else {
3661                             gen_helper_vfp_fcvt_f32_to_f16(tcg_ctx, tmp, tcg_ctx->cpu_F0s,
3662                                                            tcg_ctx->cpu_env);
3663                         }
3664                         gen_mov_F0_vreg(s, 0, rd);
3665                         tmp2 = gen_vfp_mrs(s);
3666                         tcg_gen_andi_i32(tcg_ctx, tmp2, tmp2, 0xffff0000);
3667                         tcg_gen_or_i32(tcg_ctx, tmp, tmp, tmp2);
3668                         tcg_temp_free_i32(tcg_ctx, tmp2);
3669                         gen_vfp_msr(s, tmp);
3670                         break;
3671                     case 7: /* vcvtt.f16.f32, vcvtt.f16.f64 */
3672                         tmp = tcg_temp_new_i32(tcg_ctx);
3673                         if (dp) {
3674                             gen_helper_vfp_fcvt_f64_to_f16(tcg_ctx, tmp, tcg_ctx->cpu_F0d,
3675                                                            tcg_ctx->cpu_env);
3676                         } else {
3677                             gen_helper_vfp_fcvt_f32_to_f16(tcg_ctx, tmp, tcg_ctx->cpu_F0s,
3678                                                            tcg_ctx->cpu_env);
3679                         }
3680                         tcg_gen_shli_i32(tcg_ctx, tmp, tmp, 16);
3681                         gen_mov_F0_vreg(s, 0, rd);
3682                         tmp2 = gen_vfp_mrs(s);
3683                         tcg_gen_ext16u_i32(tcg_ctx, tmp2, tmp2);
3684                         tcg_gen_or_i32(tcg_ctx, tmp, tmp, tmp2);
3685                         tcg_temp_free_i32(tcg_ctx, tmp2);
3686                         gen_vfp_msr(s, tmp);
3687                         break;
3688                     case 8: /* cmp */
3689                         gen_vfp_cmp(s, dp);
3690                         break;
3691                     case 9: /* cmpe */
3692                         gen_vfp_cmpe(s, dp);
3693                         break;
3694                     case 10: /* cmpz */
3695                         gen_vfp_cmp(s, dp);
3696                         break;
3697                     case 11: /* cmpez */
3698                         gen_vfp_F1_ld0(s, dp);
3699                         gen_vfp_cmpe(s, dp);
3700                         break;
3701                     case 12: /* vrintr */
3702                     {
3703                         TCGv_ptr fpst = get_fpstatus_ptr(s, 0);
3704                         if (dp) {
3705                             gen_helper_rintd(tcg_ctx, tcg_ctx->cpu_F0d, tcg_ctx->cpu_F0d, fpst);
3706                         } else {
3707                             gen_helper_rints(tcg_ctx, tcg_ctx->cpu_F0s, tcg_ctx->cpu_F0s, fpst);
3708                         }
3709                         tcg_temp_free_ptr(tcg_ctx, fpst);
3710                         break;
3711                     }
3712                     case 13: /* vrintz */
3713                     {
3714                         TCGv_ptr fpst = get_fpstatus_ptr(s, 0);
3715                         TCGv_i32 tcg_rmode;
3716                         tcg_rmode = tcg_const_i32(tcg_ctx, float_round_to_zero);
3717                         gen_helper_set_rmode(tcg_ctx, tcg_rmode, tcg_rmode, tcg_ctx->cpu_env);
3718                         if (dp) {
3719                             gen_helper_rintd(tcg_ctx, tcg_ctx->cpu_F0d, tcg_ctx->cpu_F0d, fpst);
3720                         } else {
3721                             gen_helper_rints(tcg_ctx, tcg_ctx->cpu_F0s, tcg_ctx->cpu_F0s, fpst);
3722                         }
3723                         gen_helper_set_rmode(tcg_ctx, tcg_rmode, tcg_rmode, tcg_ctx->cpu_env);
3724                         tcg_temp_free_i32(tcg_ctx, tcg_rmode);
3725                         tcg_temp_free_ptr(tcg_ctx, fpst);
3726                         break;
3727                     }
3728                     case 14: /* vrintx */
3729                     {
3730                         TCGv_ptr fpst = get_fpstatus_ptr(s, 0);
3731                         if (dp) {
3732                             gen_helper_rintd_exact(tcg_ctx, tcg_ctx->cpu_F0d, tcg_ctx->cpu_F0d, fpst);
3733                         } else {
3734                             gen_helper_rints_exact(tcg_ctx, tcg_ctx->cpu_F0s, tcg_ctx->cpu_F0s, fpst);
3735                         }
3736                         tcg_temp_free_ptr(tcg_ctx, fpst);
3737                         break;
3738                     }
3739                     case 15: /* single<->double conversion */
3740                         if (dp)
3741                             gen_helper_vfp_fcvtsd(tcg_ctx, tcg_ctx->cpu_F0s, tcg_ctx->cpu_F0d, tcg_ctx->cpu_env);
3742                         else
3743                             gen_helper_vfp_fcvtds(tcg_ctx, tcg_ctx->cpu_F0d, tcg_ctx->cpu_F0s, tcg_ctx->cpu_env);
3744                         break;
3745                     case 16: /* fuito */
3746                         gen_vfp_uito(s, dp, 0);
3747                         break;
3748                     case 17: /* fsito */
3749                         gen_vfp_sito(s, dp, 0);
3750                         break;
3751                     case 20: /* fshto */
3752                         if (!arm_dc_feature(s, ARM_FEATURE_VFP3)) {
3753                             return 1;
3754                         }
3755                         gen_vfp_shto(s, dp, 16 - rm, 0);
3756                         break;
3757                     case 21: /* fslto */
3758                         if (!arm_dc_feature(s, ARM_FEATURE_VFP3)) {
3759                             return 1;
3760                         }
3761                         gen_vfp_slto(s, dp, 32 - rm, 0);
3762                         break;
3763                     case 22: /* fuhto */
3764                         if (!arm_dc_feature(s, ARM_FEATURE_VFP3)) {
3765                             return 1;
3766                         }
3767                         gen_vfp_uhto(s, dp, 16 - rm, 0);
3768                         break;
3769                     case 23: /* fulto */
3770                         if (!arm_dc_feature(s, ARM_FEATURE_VFP3)) {
3771                             return 1;
3772                         }
3773                         gen_vfp_ulto(s, dp, 32 - rm, 0);
3774                         break;
3775                     case 24: /* ftoui */
3776                         gen_vfp_toui(s, dp, 0);
3777                         break;
3778                     case 25: /* ftouiz */
3779                         gen_vfp_touiz(s, dp, 0);
3780                         break;
3781                     case 26: /* ftosi */
3782                         gen_vfp_tosi(s, dp, 0);
3783                         break;
3784                     case 27: /* ftosiz */
3785                         gen_vfp_tosiz(s, dp, 0);
3786                         break;
3787                     case 28: /* ftosh */
3788                         if (!arm_dc_feature(s, ARM_FEATURE_VFP3)) {
3789                             return 1;
3790                         }
3791                         gen_vfp_tosh(s, dp, 16 - rm, 0);
3792                         break;
3793                     case 29: /* ftosl */
3794                         if (!arm_dc_feature(s, ARM_FEATURE_VFP3)) {
3795                             return 1;
3796                         }
3797                         gen_vfp_tosl(s, dp, 32 - rm, 0);
3798                         break;
3799                     case 30: /* ftouh */
3800                         if (!arm_dc_feature(s, ARM_FEATURE_VFP3)) {
3801                             return 1;
3802                         }
3803                         gen_vfp_touh(s, dp, 16 - rm, 0);
3804                         break;
3805                     case 31: /* ftoul */
3806                         if (!arm_dc_feature(s, ARM_FEATURE_VFP3)) {
3807                             return 1;
3808                         }
3809                         gen_vfp_toul(s, dp, 32 - rm, 0);
3810                         break;
3811                     default: /* undefined */
3812                         return 1;
3813                     }
3814                     break;
3815                 default: /* undefined */
3816                     return 1;
3817                 }
3818 
3819                 /* Write back the result.  */
3820                 if (op == 15 && (rn >= 8 && rn <= 11)) {
3821                     /* Comparison, do nothing.  */
3822                 } else if (op == 15 && dp && ((rn & 0x1c) == 0x18 ||
3823                                               (rn & 0x1e) == 0x6)) {
3824                     /* VCVT double to int: always integer result.
3825                      * VCVT double to half precision is always a single
3826                      * precision result.
3827                      */
3828                     gen_mov_vreg_F0(s, 0, rd);
3829                 } else if (op == 15 && rn == 15) {
3830                     /* conversion */
3831                     gen_mov_vreg_F0(s, !dp, rd);
3832                 } else {
3833                     gen_mov_vreg_F0(s, dp, rd);
3834                 }
3835 
3836                 /* break out of the loop if we have finished  */
3837                 if (veclen == 0)
3838                     break;
3839 
3840                 if (op == 15 && delta_m == 0) {
3841                     /* single source one-many */
3842                     while (veclen--) {
3843                         rd = ((rd + delta_d) & (bank_mask - 1))
3844                              | (rd & bank_mask);
3845                         gen_mov_vreg_F0(s, dp, rd);
3846                     }
3847                     break;
3848                 }
3849                 /* Setup the next operands.  */
3850                 veclen--;
3851                 rd = ((rd + delta_d) & (bank_mask - 1))
3852                      | (rd & bank_mask);
3853 
3854                 if (op == 15) {
3855                     /* One source operand.  */
3856                     rm = ((rm + delta_m) & (bank_mask - 1))
3857                          | (rm & bank_mask);
3858                     gen_mov_F0_vreg(s, dp, rm);
3859                 } else {
3860                     /* Two source operands.  */
3861                     rn = ((rn + delta_d) & (bank_mask - 1))
3862                          | (rn & bank_mask);
3863                     gen_mov_F0_vreg(s, dp, rn);
3864                     if (delta_m) {
3865                         rm = ((rm + delta_m) & (bank_mask - 1))
3866                              | (rm & bank_mask);
3867                         gen_mov_F1_vreg(s, dp, rm);
3868                     }
3869                 }
3870             }
3871         }
3872         break;
3873     case 0xc:
3874     case 0xd:
3875         if ((insn & 0x03e00000) == 0x00400000) {
3876             /* two-register transfer */
3877             rn = (insn >> 16) & 0xf;
3878             rd = (insn >> 12) & 0xf;
3879             if (dp) {
3880                 VFP_DREG_M(rm, insn);
3881             } else {
3882                 rm = VFP_SREG_M(insn);
3883             }
3884 
3885             if (insn & ARM_CP_RW_BIT) {
3886                 /* vfp->arm */
3887                 if (dp) {
3888                     gen_mov_F0_vreg(s, 0, rm * 2);
3889                     tmp = gen_vfp_mrs(s);
3890                     store_reg(s, rd, tmp);
3891                     gen_mov_F0_vreg(s, 0, rm * 2 + 1);
3892                     tmp = gen_vfp_mrs(s);
3893                     store_reg(s, rn, tmp);
3894                 } else {
3895                     gen_mov_F0_vreg(s, 0, rm);
3896                     tmp = gen_vfp_mrs(s);
3897                     store_reg(s, rd, tmp);
3898                     gen_mov_F0_vreg(s, 0, rm + 1);
3899                     tmp = gen_vfp_mrs(s);
3900                     store_reg(s, rn, tmp);
3901                 }
3902             } else {
3903                 /* arm->vfp */
3904                 if (dp) {
3905                     tmp = load_reg(s, rd);
3906                     gen_vfp_msr(s, tmp);
3907                     gen_mov_vreg_F0(s, 0, rm * 2);
3908                     tmp = load_reg(s, rn);
3909                     gen_vfp_msr(s, tmp);
3910                     gen_mov_vreg_F0(s, 0, rm * 2 + 1);
3911                 } else {
3912                     tmp = load_reg(s, rd);
3913                     gen_vfp_msr(s, tmp);
3914                     gen_mov_vreg_F0(s, 0, rm);
3915                     tmp = load_reg(s, rn);
3916                     gen_vfp_msr(s, tmp);
3917                     gen_mov_vreg_F0(s, 0, rm + 1);
3918                 }
3919             }
3920         } else {
3921             /* Load/store */
3922             rn = (insn >> 16) & 0xf;
3923             if (dp)
3924                 VFP_DREG_D(rd, insn);
3925             else
3926                 rd = VFP_SREG_D(insn);
3927             if ((insn & 0x01200000) == 0x01000000) {
3928                 /* Single load/store */
3929                 offset = (insn & 0xff) << 2;
3930                 if ((insn & (1 << 23)) == 0)
3931                     offset = 0-offset;
3932                 if (s->thumb && rn == 15) {
3933                     /* This is actually UNPREDICTABLE */
3934                     addr = tcg_temp_new_i32(tcg_ctx);
3935                     tcg_gen_movi_i32(tcg_ctx, addr, s->pc & ~2);
3936                 } else {
3937                     addr = load_reg(s, rn);
3938                 }
3939                 tcg_gen_addi_i32(tcg_ctx, addr, addr, offset);
3940                 if (insn & (1 << 20)) {
3941                     gen_vfp_ld(s, dp, addr);
3942                     gen_mov_vreg_F0(s, dp, rd);
3943                 } else {
3944                     gen_mov_F0_vreg(s, dp, rd);
3945                     gen_vfp_st(s, dp, addr);
3946                 }
3947                 tcg_temp_free_i32(tcg_ctx, addr);
3948             } else {
3949                 /* load/store multiple */
3950                 int w = insn & (1 << 21);
3951                 if (dp)
3952                     n = (insn >> 1) & 0x7f;
3953                 else
3954                     n = insn & 0xff;
3955 
3956                 if (w && !(((insn >> 23) ^ (insn >> 24)) & 1)) {
3957                     /* P == U , W == 1  => UNDEF */
3958                     return 1;
3959                 }
3960                 if (n == 0 || (rd + n) > 32 || (dp && n > 16)) {
3961                     /* UNPREDICTABLE cases for bad immediates: we choose to
3962                      * UNDEF to avoid generating huge numbers of TCG ops
3963                      */
3964                     return 1;
3965                 }
3966                 if (rn == 15 && w) {
3967                     /* writeback to PC is UNPREDICTABLE, we choose to UNDEF */
3968                     return 1;
3969                 }
3970 
3971                 if (s->thumb && rn == 15) {
3972                     /* This is actually UNPREDICTABLE */
3973                     addr = tcg_temp_new_i32(tcg_ctx);
3974                     tcg_gen_movi_i32(tcg_ctx, addr, s->pc & ~2);
3975                 } else {
3976                     addr = load_reg(s, rn);
3977                 }
3978                 if (insn & (1 << 24)) /* pre-decrement */
3979                     tcg_gen_addi_i32(tcg_ctx, addr, addr, 0-((insn & 0xff) << 2));
3980 
3981                 if (dp)
3982                     offset = 8;
3983                 else
3984                     offset = 4;
3985                 for (i = 0; i < n; i++) {
3986                     if (insn & ARM_CP_RW_BIT) {
3987                         /* load */
3988                         gen_vfp_ld(s, dp, addr);
3989                         gen_mov_vreg_F0(s, dp, rd + i);
3990                     } else {
3991                         /* store */
3992                         gen_mov_F0_vreg(s, dp, rd + i);
3993                         gen_vfp_st(s, dp, addr);
3994                     }
3995                     tcg_gen_addi_i32(tcg_ctx, addr, addr, offset);
3996                 }
3997                 if (w) {
3998                     /* writeback */
3999                     if (insn & (1 << 24))
4000                         offset = (0-offset) * n;
4001                     else if (dp && (insn & 1))
4002                         offset = 4;
4003                     else
4004                         offset = 0;
4005 
4006                     if (offset != 0)
4007                         tcg_gen_addi_i32(tcg_ctx, addr, addr, offset);
4008                     store_reg(s, rn, addr);
4009                 } else {
4010                     tcg_temp_free_i32(tcg_ctx, addr);
4011                 }
4012             }
4013         }
4014         break;
4015     default:
4016         /* Should never happen.  */
4017         return 1;
4018     }
4019     return 0;
4020 }
4021 
gen_goto_tb(DisasContext * s,int n,target_ulong dest)4022 static inline void gen_goto_tb(DisasContext *s, int n, target_ulong dest)
4023 {
4024     TCGContext *tcg_ctx = s->uc->tcg_ctx;
4025     TranslationBlock *tb;
4026 
4027     tb = s->tb;
4028     if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK)) {
4029         tcg_gen_goto_tb(tcg_ctx, n);
4030         gen_set_pc_im(s, dest);
4031         tcg_gen_exit_tb(tcg_ctx, (uintptr_t)tb + n);
4032     } else {
4033         gen_set_pc_im(s, dest);
4034         tcg_gen_exit_tb(tcg_ctx, 0);
4035     }
4036 }
4037 
gen_jmp(DisasContext * s,uint32_t dest)4038 static inline void gen_jmp(DisasContext *s, uint32_t dest)
4039 {
4040     if (unlikely(s->singlestep_enabled || s->ss_active)) {
4041         /* An indirect jump so that we still trigger the debug exception.  */
4042         if (s->thumb)
4043             dest |= 1;
4044         gen_bx_im(s, dest);
4045     } else {
4046         gen_goto_tb(s, 0, dest);
4047         s->is_jmp = DISAS_TB_JUMP;
4048     }
4049 }
4050 
gen_mulxy(DisasContext * s,TCGv_i32 t0,TCGv_i32 t1,int x,int y)4051 static inline void gen_mulxy(DisasContext *s, TCGv_i32 t0, TCGv_i32 t1, int x, int y)
4052 {
4053     TCGContext *tcg_ctx = s->uc->tcg_ctx;
4054     if (x)
4055         tcg_gen_sari_i32(tcg_ctx, t0, t0, 16);
4056     else
4057         gen_sxth(t0);
4058     if (y)
4059         tcg_gen_sari_i32(tcg_ctx, t1, t1, 16);
4060     else
4061         gen_sxth(t1);
4062     tcg_gen_mul_i32(tcg_ctx, t0, t0, t1);
4063 }
4064 
4065 /* Return the mask of PSR bits set by a MSR instruction.  */
msr_mask(DisasContext * s,int flags,int spsr)4066 static uint32_t msr_mask(DisasContext *s, int flags, int spsr)
4067 {
4068     uint32_t mask;
4069 
4070     mask = 0;
4071     if (flags & (1 << 0))
4072         mask |= 0xff;
4073     if (flags & (1 << 1))
4074         mask |= 0xff00;
4075     if (flags & (1 << 2))
4076         mask |= 0xff0000;
4077     if (flags & (1 << 3))
4078         mask |= 0xff000000;
4079 
4080     /* Mask out undefined bits.  */
4081     mask &= ~CPSR_RESERVED;
4082     if (!arm_dc_feature(s, ARM_FEATURE_V4T)) {
4083         mask &= ~CPSR_T;
4084     }
4085     if (!arm_dc_feature(s, ARM_FEATURE_V5)) {
4086         mask &= ~CPSR_Q; /* V5TE in reality*/
4087     }
4088     if (!arm_dc_feature(s, ARM_FEATURE_V6)) {
4089         mask &= ~(CPSR_E | CPSR_GE);
4090     }
4091     if (!arm_dc_feature(s, ARM_FEATURE_THUMB2)) {
4092         mask &= ~CPSR_IT;
4093     }
4094     /* Mask out execution state and reserved bits.  */
4095     if (!spsr) {
4096         mask &= ~(CPSR_EXEC | CPSR_RESERVED);
4097     }
4098     /* Mask out privileged bits.  */
4099     if (IS_USER(s))
4100         mask &= CPSR_USER;
4101     return mask;
4102 }
4103 
4104 /* Returns nonzero if access to the PSR is not permitted. Marks t0 as dead. */
gen_set_psr(DisasContext * s,uint32_t mask,int spsr,TCGv_i32 t0)4105 static int gen_set_psr(DisasContext *s, uint32_t mask, int spsr, TCGv_i32 t0)
4106 {
4107     TCGContext *tcg_ctx = s->uc->tcg_ctx;
4108     TCGv_i32 tmp;
4109     if (spsr) {
4110         /* ??? This is also undefined in system mode.  */
4111         if (IS_USER(s))
4112             return 1;
4113 
4114         tmp = load_cpu_field(s->uc, spsr);
4115         tcg_gen_andi_i32(tcg_ctx, tmp, tmp, ~mask);
4116         tcg_gen_andi_i32(tcg_ctx, t0, t0, mask);
4117         tcg_gen_or_i32(tcg_ctx, tmp, tmp, t0);
4118         store_cpu_field(tcg_ctx, tmp, spsr);
4119     } else {
4120         gen_set_cpsr(s, t0, mask);
4121     }
4122     tcg_temp_free_i32(tcg_ctx, t0);
4123     gen_lookup_tb(s);
4124     return 0;
4125 }
4126 
4127 /* Returns nonzero if access to the PSR is not permitted.  */
gen_set_psr_im(DisasContext * s,uint32_t mask,int spsr,uint32_t val)4128 static int gen_set_psr_im(DisasContext *s, uint32_t mask, int spsr, uint32_t val)
4129 {
4130     TCGContext *tcg_ctx = s->uc->tcg_ctx;
4131     TCGv_i32 tmp;
4132     tmp = tcg_temp_new_i32(tcg_ctx);
4133     tcg_gen_movi_i32(tcg_ctx, tmp, val);
4134     return gen_set_psr(s, mask, spsr, tmp);
4135 }
4136 
4137 /* Generate an old-style exception return. Marks pc as dead. */
gen_exception_return(DisasContext * s,TCGv_i32 pc)4138 static void gen_exception_return(DisasContext *s, TCGv_i32 pc)
4139 {
4140     TCGContext *tcg_ctx = s->uc->tcg_ctx;
4141     TCGv_i32 tmp;
4142     store_reg(s, 15, pc);
4143     tmp = load_cpu_field(s->uc, spsr);
4144     gen_set_cpsr(s, tmp, CPSR_ERET_MASK);
4145     tcg_temp_free_i32(tcg_ctx, tmp);
4146     s->is_jmp = DISAS_UPDATE;
4147 }
4148 
4149 /* Generate a v6 exception return.  Marks both values as dead.  */
gen_rfe(DisasContext * s,TCGv_i32 pc,TCGv_i32 cpsr)4150 static void gen_rfe(DisasContext *s, TCGv_i32 pc, TCGv_i32 cpsr)
4151 {
4152     TCGContext *tcg_ctx = s->uc->tcg_ctx;
4153     gen_set_cpsr(s, cpsr, CPSR_ERET_MASK);
4154     tcg_temp_free_i32(tcg_ctx, cpsr);
4155     store_reg(s, 15, pc);
4156     s->is_jmp = DISAS_UPDATE;
4157 }
4158 
gen_nop_hint(DisasContext * s,int val)4159 static void gen_nop_hint(DisasContext *s, int val)
4160 {
4161     switch (val) {
4162     case 3: /* wfi */
4163         gen_set_pc_im(s, s->pc);
4164         s->is_jmp = DISAS_WFI;
4165         break;
4166     case 2: /* wfe */
4167         gen_set_pc_im(s, s->pc);
4168         s->is_jmp = DISAS_WFE;
4169         break;
4170     case 4: /* sev */
4171     case 5: /* sevl */
4172         /* TODO: Implement SEV, SEVL and WFE.  May help SMP performance.  */
4173     default: /* nop */
4174         break;
4175     }
4176 }
4177 
4178 #define CPU_V001 tcg_ctx->cpu_V0, tcg_ctx->cpu_V0, tcg_ctx->cpu_V1
4179 
gen_neon_add(DisasContext * s,int size,TCGv_i32 t0,TCGv_i32 t1)4180 static inline void gen_neon_add(DisasContext *s, int size, TCGv_i32 t0, TCGv_i32 t1)
4181 {
4182     TCGContext *tcg_ctx = s->uc->tcg_ctx;
4183     switch (size) {
4184     case 0: gen_helper_neon_add_u8(tcg_ctx, t0, t0, t1); break;
4185     case 1: gen_helper_neon_add_u16(tcg_ctx, t0, t0, t1); break;
4186     case 2: tcg_gen_add_i32(tcg_ctx, t0, t0, t1); break;
4187     default: abort();
4188     }
4189 }
4190 
gen_neon_rsb(DisasContext * s,int size,TCGv_i32 t0,TCGv_i32 t1)4191 static inline void gen_neon_rsb(DisasContext *s, int size, TCGv_i32 t0, TCGv_i32 t1)
4192 {
4193     TCGContext *tcg_ctx = s->uc->tcg_ctx;
4194     switch (size) {
4195     case 0: gen_helper_neon_sub_u8(tcg_ctx, t0, t1, t0); break;
4196     case 1: gen_helper_neon_sub_u16(tcg_ctx, t0, t1, t0); break;
4197     case 2: tcg_gen_sub_i32(tcg_ctx, t0, t1, t0); break;
4198     default: return;
4199     }
4200 }
4201 
4202 /* 32-bit pairwise ops end up the same as the elementwise versions.  */
4203 #define gen_helper_neon_pmax_s32  gen_helper_neon_max_s32
4204 #define gen_helper_neon_pmax_u32  gen_helper_neon_max_u32
4205 #define gen_helper_neon_pmin_s32  gen_helper_neon_min_s32
4206 #define gen_helper_neon_pmin_u32  gen_helper_neon_min_u32
4207 
4208 #define GEN_NEON_INTEGER_OP_ENV(name) do { \
4209     switch ((size << 1) | u) { \
4210     case 0: \
4211         gen_helper_neon_##name##_s8(tcg_ctx, tmp, tcg_ctx->cpu_env, tmp, tmp2); \
4212         break; \
4213     case 1: \
4214         gen_helper_neon_##name##_u8(tcg_ctx, tmp, tcg_ctx->cpu_env, tmp, tmp2); \
4215         break; \
4216     case 2: \
4217         gen_helper_neon_##name##_s16(tcg_ctx, tmp, tcg_ctx->cpu_env, tmp, tmp2); \
4218         break; \
4219     case 3: \
4220         gen_helper_neon_##name##_u16(tcg_ctx, tmp, tcg_ctx->cpu_env, tmp, tmp2); \
4221         break; \
4222     case 4: \
4223         gen_helper_neon_##name##_s32(tcg_ctx, tmp, tcg_ctx->cpu_env, tmp, tmp2); \
4224         break; \
4225     case 5: \
4226         gen_helper_neon_##name##_u32(tcg_ctx, tmp, tcg_ctx->cpu_env, tmp, tmp2); \
4227         break; \
4228     default: return 1; \
4229     }} while (0)
4230 
4231 #define GEN_NEON_INTEGER_OP(name) do { \
4232     switch ((size << 1) | u) { \
4233     case 0: \
4234         gen_helper_neon_##name##_s8(tcg_ctx, tmp, tmp, tmp2); \
4235         break; \
4236     case 1: \
4237         gen_helper_neon_##name##_u8(tcg_ctx, tmp, tmp, tmp2); \
4238         break; \
4239     case 2: \
4240         gen_helper_neon_##name##_s16(tcg_ctx, tmp, tmp, tmp2); \
4241         break; \
4242     case 3: \
4243         gen_helper_neon_##name##_u16(tcg_ctx, tmp, tmp, tmp2); \
4244         break; \
4245     case 4: \
4246         gen_helper_neon_##name##_s32(tcg_ctx, tmp, tmp, tmp2); \
4247         break; \
4248     case 5: \
4249         gen_helper_neon_##name##_u32(tcg_ctx, tmp, tmp, tmp2); \
4250         break; \
4251     default: return 1; \
4252     }} while (0)
4253 
neon_load_scratch(TCGContext * tcg_ctx,int scratch)4254 static TCGv_i32 neon_load_scratch(TCGContext *tcg_ctx, int scratch)
4255 {
4256     TCGv_i32 tmp = tcg_temp_new_i32(tcg_ctx);
4257     tcg_gen_ld_i32(tcg_ctx, tmp, tcg_ctx->cpu_env, offsetof(CPUARMState, vfp.scratch[scratch]));
4258     return tmp;
4259 }
4260 
neon_store_scratch(TCGContext * tcg_ctx,int scratch,TCGv_i32 var)4261 static void neon_store_scratch(TCGContext *tcg_ctx, int scratch, TCGv_i32 var)
4262 {
4263     tcg_gen_st_i32(tcg_ctx, var, tcg_ctx->cpu_env, offsetof(CPUARMState, vfp.scratch[scratch]));
4264     tcg_temp_free_i32(tcg_ctx, var);
4265 }
4266 
neon_get_scalar(DisasContext * s,int size,int reg)4267 static inline TCGv_i32 neon_get_scalar(DisasContext *s, int size, int reg)
4268 {
4269     TCGContext *tcg_ctx = s->uc->tcg_ctx;
4270     TCGv_i32 tmp;
4271     if (size == 1) {
4272         tmp = neon_load_reg(tcg_ctx, reg & 7, reg >> 4);
4273         if (reg & 8) {
4274             gen_neon_dup_high16(s, tmp);
4275         } else {
4276             gen_neon_dup_low16(s, tmp);
4277         }
4278     } else {
4279         tmp = neon_load_reg(tcg_ctx, reg & 15, reg >> 4);
4280     }
4281     return tmp;
4282 }
4283 
gen_neon_unzip(TCGContext * tcg_ctx,int rd,int rm,int size,int q)4284 static int gen_neon_unzip(TCGContext *tcg_ctx, int rd, int rm, int size, int q)
4285 {
4286     TCGv_i32 tmp, tmp2;
4287     if (!q && size == 2) {
4288         return 1;
4289     }
4290     tmp = tcg_const_i32(tcg_ctx, rd);
4291     tmp2 = tcg_const_i32(tcg_ctx, rm);
4292     if (q) {
4293         switch (size) {
4294         case 0:
4295             gen_helper_neon_qunzip8(tcg_ctx, tcg_ctx->cpu_env, tmp, tmp2);
4296             break;
4297         case 1:
4298             gen_helper_neon_qunzip16(tcg_ctx, tcg_ctx->cpu_env, tmp, tmp2);
4299             break;
4300         case 2:
4301             gen_helper_neon_qunzip32(tcg_ctx, tcg_ctx->cpu_env, tmp, tmp2);
4302             break;
4303         default:
4304             abort();
4305         }
4306     } else {
4307         switch (size) {
4308         case 0:
4309             gen_helper_neon_unzip8(tcg_ctx, tcg_ctx->cpu_env, tmp, tmp2);
4310             break;
4311         case 1:
4312             gen_helper_neon_unzip16(tcg_ctx, tcg_ctx->cpu_env, tmp, tmp2);
4313             break;
4314         default:
4315             abort();
4316         }
4317     }
4318     tcg_temp_free_i32(tcg_ctx, tmp);
4319     tcg_temp_free_i32(tcg_ctx, tmp2);
4320     return 0;
4321 }
4322 
gen_neon_zip(TCGContext * tcg_ctx,int rd,int rm,int size,int q)4323 static int gen_neon_zip(TCGContext *tcg_ctx, int rd, int rm, int size, int q)
4324 {
4325     TCGv_i32 tmp, tmp2;
4326     if (!q && size == 2) {
4327         return 1;
4328     }
4329     tmp = tcg_const_i32(tcg_ctx, rd);
4330     tmp2 = tcg_const_i32(tcg_ctx, rm);
4331     if (q) {
4332         switch (size) {
4333         case 0:
4334             gen_helper_neon_qzip8(tcg_ctx, tcg_ctx->cpu_env, tmp, tmp2);
4335             break;
4336         case 1:
4337             gen_helper_neon_qzip16(tcg_ctx, tcg_ctx->cpu_env, tmp, tmp2);
4338             break;
4339         case 2:
4340             gen_helper_neon_qzip32(tcg_ctx, tcg_ctx->cpu_env, tmp, tmp2);
4341             break;
4342         default:
4343             abort();
4344         }
4345     } else {
4346         switch (size) {
4347         case 0:
4348             gen_helper_neon_zip8(tcg_ctx, tcg_ctx->cpu_env, tmp, tmp2);
4349             break;
4350         case 1:
4351             gen_helper_neon_zip16(tcg_ctx, tcg_ctx->cpu_env, tmp, tmp2);
4352             break;
4353         default:
4354             abort();
4355         }
4356     }
4357     tcg_temp_free_i32(tcg_ctx, tmp);
4358     tcg_temp_free_i32(tcg_ctx, tmp2);
4359     return 0;
4360 }
4361 
gen_neon_trn_u8(TCGContext * tcg_ctx,TCGv_i32 t0,TCGv_i32 t1)4362 static void gen_neon_trn_u8(TCGContext *tcg_ctx, TCGv_i32 t0, TCGv_i32 t1)
4363 {
4364     TCGv_i32 rd, tmp;
4365 
4366     rd = tcg_temp_new_i32(tcg_ctx);
4367     tmp = tcg_temp_new_i32(tcg_ctx);
4368 
4369     tcg_gen_shli_i32(tcg_ctx, rd, t0, 8);
4370     tcg_gen_andi_i32(tcg_ctx, rd, rd, 0xff00ff00);
4371     tcg_gen_andi_i32(tcg_ctx, tmp, t1, 0x00ff00ff);
4372     tcg_gen_or_i32(tcg_ctx, rd, rd, tmp);
4373 
4374     tcg_gen_shri_i32(tcg_ctx, t1, t1, 8);
4375     tcg_gen_andi_i32(tcg_ctx, t1, t1, 0x00ff00ff);
4376     tcg_gen_andi_i32(tcg_ctx, tmp, t0, 0xff00ff00);
4377     tcg_gen_or_i32(tcg_ctx, t1, t1, tmp);
4378     tcg_gen_mov_i32(tcg_ctx, t0, rd);
4379 
4380     tcg_temp_free_i32(tcg_ctx, tmp);
4381     tcg_temp_free_i32(tcg_ctx, rd);
4382 }
4383 
gen_neon_trn_u16(TCGContext * tcg_ctx,TCGv_i32 t0,TCGv_i32 t1)4384 static void gen_neon_trn_u16(TCGContext *tcg_ctx, TCGv_i32 t0, TCGv_i32 t1)
4385 {
4386     TCGv_i32 rd, tmp;
4387 
4388     rd = tcg_temp_new_i32(tcg_ctx);
4389     tmp = tcg_temp_new_i32(tcg_ctx);
4390 
4391     tcg_gen_shli_i32(tcg_ctx, rd, t0, 16);
4392     tcg_gen_andi_i32(tcg_ctx, tmp, t1, 0xffff);
4393     tcg_gen_or_i32(tcg_ctx, rd, rd, tmp);
4394     tcg_gen_shri_i32(tcg_ctx, t1, t1, 16);
4395     tcg_gen_andi_i32(tcg_ctx, tmp, t0, 0xffff0000);
4396     tcg_gen_or_i32(tcg_ctx, t1, t1, tmp);
4397     tcg_gen_mov_i32(tcg_ctx, t0, rd);
4398 
4399     tcg_temp_free_i32(tcg_ctx, tmp);
4400     tcg_temp_free_i32(tcg_ctx, rd);
4401 }
4402 
4403 
4404 static struct {
4405     int nregs;
4406     int interleave;
4407     int spacing;
4408 } neon_ls_element_type[11] = {
4409     {4, 4, 1},
4410     {4, 4, 2},
4411     {4, 1, 1},
4412     {4, 2, 1},
4413     {3, 3, 1},
4414     {3, 3, 2},
4415     {3, 1, 1},
4416     {1, 1, 1},
4417     {2, 2, 1},
4418     {2, 2, 2},
4419     {2, 1, 1}
4420 };
4421 
4422 /* Translate a NEON load/store element instruction.  Return nonzero if the
4423    instruction is invalid.  */
disas_neon_ls_insn(DisasContext * s,uint32_t insn)4424 static int disas_neon_ls_insn(DisasContext *s, uint32_t insn)
4425 {
4426     TCGContext *tcg_ctx = s->uc->tcg_ctx;
4427     int rd, rn, rm;
4428     int op;
4429     int nregs;
4430     int interleave;
4431     int spacing;
4432     int stride;
4433     int size;
4434     int reg;
4435     int pass;
4436     int load;
4437     int shift;
4438     int n;
4439     TCGv_i32 addr;
4440     TCGv_i32 tmp;
4441     TCGv_i32 tmp2;
4442     TCGv_i64 tmp64;
4443 
4444     /* FIXME: this access check should not take precedence over UNDEF
4445      * for invalid encodings; we will generate incorrect syndrome information
4446      * for attempts to execute invalid vfp/neon encodings with FP disabled.
4447      */
4448     if (!s->cpacr_fpen) {
4449         gen_exception_insn(s, 4, EXCP_UDEF,
4450                            syn_fp_access_trap(1, 0xe, s->thumb));
4451         return 0;
4452     }
4453 
4454     if (!s->vfp_enabled)
4455       return 1;
4456     VFP_DREG_D(rd, insn);
4457     rn = (insn >> 16) & 0xf;
4458     rm = insn & 0xf;
4459     load = (insn & (1 << 21)) != 0;
4460     if ((insn & (1 << 23)) == 0) {
4461         /* Load store all elements.  */
4462         op = (insn >> 8) & 0xf;
4463         size = (insn >> 6) & 3;
4464         if (op > 10)
4465             return 1;
4466         /* Catch UNDEF cases for bad values of align field */
4467         switch (op & 0xc) {
4468         case 4:
4469             if (((insn >> 5) & 1) == 1) {
4470                 return 1;
4471             }
4472             break;
4473         case 8:
4474             if (((insn >> 4) & 3) == 3) {
4475                 return 1;
4476             }
4477             break;
4478         default:
4479             break;
4480         }
4481         nregs = neon_ls_element_type[op].nregs;
4482         interleave = neon_ls_element_type[op].interleave;
4483         spacing = neon_ls_element_type[op].spacing;
4484         if (size == 3 && (interleave | spacing) != 1)
4485             return 1;
4486         addr = tcg_temp_new_i32(tcg_ctx);
4487         load_reg_var(s, addr, rn);
4488         stride = (1 << size) * interleave;
4489         for (reg = 0; reg < nregs; reg++) {
4490             if (interleave > 2 || (interleave == 2 && nregs == 2)) {
4491                 load_reg_var(s, addr, rn);
4492                 tcg_gen_addi_i32(tcg_ctx, addr, addr, (1 << size) * reg);
4493             } else if (interleave == 2 && nregs == 4 && reg == 2) {
4494                 load_reg_var(s, addr, rn);
4495                 tcg_gen_addi_i32(tcg_ctx, addr, addr, 1 << size);
4496             }
4497             if (size == 3) {
4498                 tmp64 = tcg_temp_new_i64(tcg_ctx);
4499                 if (load) {
4500                     gen_aa32_ld64(s, tmp64, addr, get_mem_index(s));
4501                     neon_store_reg64(tcg_ctx, tmp64, rd);
4502                 } else {
4503                     neon_load_reg64(tcg_ctx, tmp64, rd);
4504                     gen_aa32_st64(s, tmp64, addr, get_mem_index(s));
4505                 }
4506                 tcg_temp_free_i64(tcg_ctx, tmp64);
4507                 tcg_gen_addi_i32(tcg_ctx, addr, addr, stride);
4508             } else {
4509                 for (pass = 0; pass < 2; pass++) {
4510                     if (size == 2) {
4511                         if (load) {
4512                             tmp = tcg_temp_new_i32(tcg_ctx);
4513                             gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
4514                             neon_store_reg(tcg_ctx, rd, pass, tmp);
4515                         } else {
4516                             tmp = neon_load_reg(tcg_ctx, rd, pass);
4517                             gen_aa32_st32(s, tmp, addr, get_mem_index(s));
4518                             tcg_temp_free_i32(tcg_ctx, tmp);
4519                         }
4520                         tcg_gen_addi_i32(tcg_ctx, addr, addr, stride);
4521                     } else if (size == 1) {
4522                         if (load) {
4523                             tmp = tcg_temp_new_i32(tcg_ctx);
4524                             gen_aa32_ld16u(s, tmp, addr, get_mem_index(s));
4525                             tcg_gen_addi_i32(tcg_ctx, addr, addr, stride);
4526                             tmp2 = tcg_temp_new_i32(tcg_ctx);
4527                             gen_aa32_ld16u(s, tmp2, addr, get_mem_index(s));
4528                             tcg_gen_addi_i32(tcg_ctx, addr, addr, stride);
4529                             tcg_gen_shli_i32(tcg_ctx, tmp2, tmp2, 16);
4530                             tcg_gen_or_i32(tcg_ctx, tmp, tmp, tmp2);
4531                             tcg_temp_free_i32(tcg_ctx, tmp2);
4532                             neon_store_reg(tcg_ctx, rd, pass, tmp);
4533                         } else {
4534                             tmp = neon_load_reg(tcg_ctx, rd, pass);
4535                             tmp2 = tcg_temp_new_i32(tcg_ctx);
4536                             tcg_gen_shri_i32(tcg_ctx, tmp2, tmp, 16);
4537                             gen_aa32_st16(s, tmp, addr, get_mem_index(s));
4538                             tcg_temp_free_i32(tcg_ctx, tmp);
4539                             tcg_gen_addi_i32(tcg_ctx, addr, addr, stride);
4540                             gen_aa32_st16(s, tmp2, addr, get_mem_index(s));
4541                             tcg_temp_free_i32(tcg_ctx, tmp2);
4542                             tcg_gen_addi_i32(tcg_ctx, addr, addr, stride);
4543                         }
4544                     } else /* size == 0 */ {
4545                         if (load) {
4546                             TCGV_UNUSED_I32(tmp2);
4547                             for (n = 0; n < 4; n++) {
4548                                 tmp = tcg_temp_new_i32(tcg_ctx);
4549                                 gen_aa32_ld8u(s, tmp, addr, get_mem_index(s));
4550                                 tcg_gen_addi_i32(tcg_ctx, addr, addr, stride);
4551                                 if (n == 0) {
4552                                     tmp2 = tmp;
4553                                 } else {
4554                                     tcg_gen_shli_i32(tcg_ctx, tmp, tmp, n * 8);
4555                                     tcg_gen_or_i32(tcg_ctx, tmp2, tmp2, tmp);
4556                                     tcg_temp_free_i32(tcg_ctx, tmp);
4557                                 }
4558                             }
4559                             neon_store_reg(tcg_ctx, rd, pass, tmp2);
4560                         } else {
4561                             tmp2 = neon_load_reg(tcg_ctx, rd, pass);
4562                             for (n = 0; n < 4; n++) {
4563                                 tmp = tcg_temp_new_i32(tcg_ctx);
4564                                 if (n == 0) {
4565                                     tcg_gen_mov_i32(tcg_ctx, tmp, tmp2);
4566                                 } else {
4567                                     tcg_gen_shri_i32(tcg_ctx, tmp, tmp2, n * 8);
4568                                 }
4569                                 gen_aa32_st8(s, tmp, addr, get_mem_index(s));
4570                                 tcg_temp_free_i32(tcg_ctx, tmp);
4571                                 tcg_gen_addi_i32(tcg_ctx, addr, addr, stride);
4572                             }
4573                             tcg_temp_free_i32(tcg_ctx, tmp2);
4574                         }
4575                     }
4576                 }
4577             }
4578             rd += spacing;
4579         }
4580         tcg_temp_free_i32(tcg_ctx, addr);
4581         stride = nregs * 8;
4582     } else {
4583         size = (insn >> 10) & 3;
4584         if (size == 3) {
4585             /* Load single element to all lanes.  */
4586             int a = (insn >> 4) & 1;
4587             if (!load) {
4588                 return 1;
4589             }
4590             size = (insn >> 6) & 3;
4591             nregs = ((insn >> 8) & 3) + 1;
4592 
4593             if (size == 3) {
4594                 if (nregs != 4 || a == 0) {
4595                     return 1;
4596                 }
4597                 /* For VLD4 size==3 a == 1 means 32 bits at 16 byte alignment */
4598                 size = 2;
4599             }
4600             if (nregs == 1 && a == 1 && size == 0) {
4601                 return 1;
4602             }
4603             if (nregs == 3 && a == 1) {
4604                 return 1;
4605             }
4606             addr = tcg_temp_new_i32(tcg_ctx);
4607             load_reg_var(s, addr, rn);
4608             if (nregs == 1) {
4609                 /* VLD1 to all lanes: bit 5 indicates how many Dregs to write */
4610                 tmp = gen_load_and_replicate(s, addr, size);
4611                 tcg_gen_st_i32(tcg_ctx, tmp, tcg_ctx->cpu_env, neon_reg_offset(rd, 0));
4612                 tcg_gen_st_i32(tcg_ctx, tmp, tcg_ctx->cpu_env, neon_reg_offset(rd, 1));
4613                 if (insn & (1 << 5)) {
4614                     tcg_gen_st_i32(tcg_ctx, tmp, tcg_ctx->cpu_env, neon_reg_offset(rd + 1, 0));
4615                     tcg_gen_st_i32(tcg_ctx, tmp, tcg_ctx->cpu_env, neon_reg_offset(rd + 1, 1));
4616                 }
4617                 tcg_temp_free_i32(tcg_ctx, tmp);
4618             } else {
4619                 /* VLD2/3/4 to all lanes: bit 5 indicates register stride */
4620                 stride = (insn & (1 << 5)) ? 2 : 1;
4621                 for (reg = 0; reg < nregs; reg++) {
4622                     tmp = gen_load_and_replicate(s, addr, size);
4623                     tcg_gen_st_i32(tcg_ctx, tmp, tcg_ctx->cpu_env, neon_reg_offset(rd, 0));
4624                     tcg_gen_st_i32(tcg_ctx, tmp, tcg_ctx->cpu_env, neon_reg_offset(rd, 1));
4625                     tcg_temp_free_i32(tcg_ctx, tmp);
4626                     tcg_gen_addi_i32(tcg_ctx, addr, addr, 1 << size);
4627                     rd += stride;
4628                 }
4629             }
4630             tcg_temp_free_i32(tcg_ctx, addr);
4631             stride = (1 << size) * nregs;
4632         } else {
4633             /* Single element.  */
4634             int idx = (insn >> 4) & 0xf;
4635             pass = (insn >> 7) & 1;
4636             switch (size) {
4637             case 0:
4638                 shift = ((insn >> 5) & 3) * 8;
4639                 stride = 1;
4640                 break;
4641             case 1:
4642                 shift = ((insn >> 6) & 1) * 16;
4643                 stride = (insn & (1 << 5)) ? 2 : 1;
4644                 break;
4645             case 2:
4646                 shift = 0;
4647                 stride = (insn & (1 << 6)) ? 2 : 1;
4648                 break;
4649             default:
4650                 abort();
4651             }
4652             nregs = ((insn >> 8) & 3) + 1;
4653             /* Catch the UNDEF cases. This is unavoidably a bit messy. */
4654             switch (nregs) {
4655             case 1:
4656                 if (((idx & (1 << size)) != 0) ||
4657                     (size == 2 && ((idx & 3) == 1 || (idx & 3) == 2))) {
4658                     return 1;
4659                 }
4660                 break;
4661             case 3:
4662                 if ((idx & 1) != 0) {
4663                     return 1;
4664                 }
4665                 /* fall through */
4666             case 2:
4667                 if (size == 2 && (idx & 2) != 0) {
4668                     return 1;
4669                 }
4670                 break;
4671             case 4:
4672                 if ((size == 2) && ((idx & 3) == 3)) {
4673                     return 1;
4674                 }
4675                 break;
4676             default:
4677                 abort();
4678             }
4679             if ((rd + stride * (nregs - 1)) > 31) {
4680                 /* Attempts to write off the end of the register file
4681                  * are UNPREDICTABLE; we choose to UNDEF because otherwise
4682                  * the neon_load_reg() would write off the end of the array.
4683                  */
4684                 return 1;
4685             }
4686             addr = tcg_temp_new_i32(tcg_ctx);
4687             load_reg_var(s, addr, rn);
4688             for (reg = 0; reg < nregs; reg++) {
4689                 if (load) {
4690                     tmp = tcg_temp_new_i32(tcg_ctx);
4691                     switch (size) {
4692                     case 0:
4693                         gen_aa32_ld8u(s, tmp, addr, get_mem_index(s));
4694                         break;
4695                     case 1:
4696                         gen_aa32_ld16u(s, tmp, addr, get_mem_index(s));
4697                         break;
4698                     case 2:
4699                         gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
4700                         break;
4701                     default: /* Avoid compiler warnings.  */
4702                         abort();
4703                     }
4704                     if (size != 2) {
4705                         tmp2 = neon_load_reg(tcg_ctx, rd, pass);
4706                         tcg_gen_deposit_i32(tcg_ctx, tmp, tmp2, tmp,
4707                                             shift, size ? 16 : 8);
4708                         tcg_temp_free_i32(tcg_ctx, tmp2);
4709                     }
4710                     neon_store_reg(tcg_ctx, rd, pass, tmp);
4711                 } else { /* Store */
4712                     tmp = neon_load_reg(tcg_ctx, rd, pass);
4713                     if (shift)
4714                         tcg_gen_shri_i32(tcg_ctx, tmp, tmp, shift);
4715                     switch (size) {
4716                     case 0:
4717                         gen_aa32_st8(s, tmp, addr, get_mem_index(s));
4718                         break;
4719                     case 1:
4720                         gen_aa32_st16(s, tmp, addr, get_mem_index(s));
4721                         break;
4722                     case 2:
4723                         gen_aa32_st32(s, tmp, addr, get_mem_index(s));
4724                         break;
4725                     }
4726                     tcg_temp_free_i32(tcg_ctx, tmp);
4727                 }
4728                 rd += stride;
4729                 tcg_gen_addi_i32(tcg_ctx, addr, addr, 1 << size);
4730             }
4731             tcg_temp_free_i32(tcg_ctx, addr);
4732             stride = nregs * (1 << size);
4733         }
4734     }
4735     if (rm != 15) {
4736         TCGv_i32 base;
4737 
4738         base = load_reg(s, rn);
4739         if (rm == 13) {
4740             tcg_gen_addi_i32(tcg_ctx, base, base, stride);
4741         } else {
4742             TCGv_i32 index;
4743             index = load_reg(s, rm);
4744             tcg_gen_add_i32(tcg_ctx, base, base, index);
4745             tcg_temp_free_i32(tcg_ctx, index);
4746         }
4747         store_reg(s, rn, base);
4748     }
4749     return 0;
4750 }
4751 
4752 /* Bitwise select.  dest = c ? t : f.  Clobbers T and F.  */
gen_neon_bsl(DisasContext * s,TCGv_i32 dest,TCGv_i32 t,TCGv_i32 f,TCGv_i32 c)4753 static void gen_neon_bsl(DisasContext *s, TCGv_i32 dest, TCGv_i32 t, TCGv_i32 f, TCGv_i32 c)
4754 {
4755     TCGContext *tcg_ctx = s->uc->tcg_ctx;
4756     tcg_gen_and_i32(tcg_ctx, t, t, c);
4757     tcg_gen_andc_i32(tcg_ctx, f, f, c);
4758     tcg_gen_or_i32(tcg_ctx, dest, t, f);
4759 }
4760 
gen_neon_narrow(DisasContext * s,int size,TCGv_i32 dest,TCGv_i64 src)4761 static inline void gen_neon_narrow(DisasContext *s, int size, TCGv_i32 dest, TCGv_i64 src)
4762 {
4763     TCGContext *tcg_ctx = s->uc->tcg_ctx;
4764     switch (size) {
4765     case 0: gen_helper_neon_narrow_u8(tcg_ctx, dest, src); break;
4766     case 1: gen_helper_neon_narrow_u16(tcg_ctx, dest, src); break;
4767     case 2: tcg_gen_trunc_i64_i32(tcg_ctx, dest, src); break;
4768     default: abort();
4769     }
4770 }
4771 
gen_neon_narrow_sats(DisasContext * s,int size,TCGv_i32 dest,TCGv_i64 src)4772 static inline void gen_neon_narrow_sats(DisasContext *s, int size, TCGv_i32 dest, TCGv_i64 src)
4773 {
4774     TCGContext *tcg_ctx = s->uc->tcg_ctx;
4775     switch (size) {
4776     case 0: gen_helper_neon_narrow_sat_s8(tcg_ctx, dest, tcg_ctx->cpu_env, src); break;
4777     case 1: gen_helper_neon_narrow_sat_s16(tcg_ctx, dest, tcg_ctx->cpu_env, src); break;
4778     case 2: gen_helper_neon_narrow_sat_s32(tcg_ctx, dest, tcg_ctx->cpu_env, src); break;
4779     default: abort();
4780     }
4781 }
4782 
gen_neon_narrow_satu(DisasContext * s,int size,TCGv_i32 dest,TCGv_i64 src)4783 static inline void gen_neon_narrow_satu(DisasContext *s, int size, TCGv_i32 dest, TCGv_i64 src)
4784 {
4785     TCGContext *tcg_ctx = s->uc->tcg_ctx;
4786     switch (size) {
4787     case 0: gen_helper_neon_narrow_sat_u8(tcg_ctx, dest, tcg_ctx->cpu_env, src); break;
4788     case 1: gen_helper_neon_narrow_sat_u16(tcg_ctx, dest, tcg_ctx->cpu_env, src); break;
4789     case 2: gen_helper_neon_narrow_sat_u32(tcg_ctx, dest, tcg_ctx->cpu_env, src); break;
4790     default: abort();
4791     }
4792 }
4793 
gen_neon_unarrow_sats(DisasContext * s,int size,TCGv_i32 dest,TCGv_i64 src)4794 static inline void gen_neon_unarrow_sats(DisasContext *s, int size, TCGv_i32 dest, TCGv_i64 src)
4795 {
4796     TCGContext *tcg_ctx = s->uc->tcg_ctx;
4797     switch (size) {
4798     case 0: gen_helper_neon_unarrow_sat8(tcg_ctx, dest, tcg_ctx->cpu_env, src); break;
4799     case 1: gen_helper_neon_unarrow_sat16(tcg_ctx, dest, tcg_ctx->cpu_env, src); break;
4800     case 2: gen_helper_neon_unarrow_sat32(tcg_ctx, dest, tcg_ctx->cpu_env, src); break;
4801     default: abort();
4802     }
4803 }
4804 
gen_neon_shift_narrow(DisasContext * s,int size,TCGv_i32 var,TCGv_i32 shift,int q,int u)4805 static inline void gen_neon_shift_narrow(DisasContext *s, int size, TCGv_i32 var, TCGv_i32 shift,
4806                                          int q, int u)
4807 {
4808     TCGContext *tcg_ctx = s->uc->tcg_ctx;
4809     if (q) {
4810         if (u) {
4811             switch (size) {
4812             case 1: gen_helper_neon_rshl_u16(tcg_ctx, var, var, shift); break;
4813             case 2: gen_helper_neon_rshl_u32(tcg_ctx, var, var, shift); break;
4814             default: abort();
4815             }
4816         } else {
4817             switch (size) {
4818             case 1: gen_helper_neon_rshl_s16(tcg_ctx, var, var, shift); break;
4819             case 2: gen_helper_neon_rshl_s32(tcg_ctx, var, var, shift); break;
4820             default: abort();
4821             }
4822         }
4823     } else {
4824         if (u) {
4825             switch (size) {
4826             case 1: gen_helper_neon_shl_u16(tcg_ctx, var, var, shift); break;
4827             case 2: gen_helper_neon_shl_u32(tcg_ctx, var, var, shift); break;
4828             default: abort();
4829             }
4830         } else {
4831             switch (size) {
4832             case 1: gen_helper_neon_shl_s16(tcg_ctx, var, var, shift); break;
4833             case 2: gen_helper_neon_shl_s32(tcg_ctx, var, var, shift); break;
4834             default: abort();
4835             }
4836         }
4837     }
4838 }
4839 
gen_neon_widen(DisasContext * s,TCGv_i64 dest,TCGv_i32 src,int size,int u)4840 static inline void gen_neon_widen(DisasContext *s, TCGv_i64 dest, TCGv_i32 src, int size, int u)
4841 {
4842     TCGContext *tcg_ctx = s->uc->tcg_ctx;
4843     if (u) {
4844         switch (size) {
4845         case 0: gen_helper_neon_widen_u8(tcg_ctx, dest, src); break;
4846         case 1: gen_helper_neon_widen_u16(tcg_ctx, dest, src); break;
4847         case 2: tcg_gen_extu_i32_i64(tcg_ctx, dest, src); break;
4848         default: abort();
4849         }
4850     } else {
4851         switch (size) {
4852         case 0: gen_helper_neon_widen_s8(tcg_ctx, dest, src); break;
4853         case 1: gen_helper_neon_widen_s16(tcg_ctx, dest, src); break;
4854         case 2: tcg_gen_ext_i32_i64(tcg_ctx, dest, src); break;
4855         default: abort();
4856         }
4857     }
4858     tcg_temp_free_i32(tcg_ctx, src);
4859 }
4860 
gen_neon_addl(DisasContext * s,int size)4861 static inline void gen_neon_addl(DisasContext *s, int size)
4862 {
4863     TCGContext *tcg_ctx = s->uc->tcg_ctx;
4864     switch (size) {
4865     case 0: gen_helper_neon_addl_u16(tcg_ctx, CPU_V001); break;
4866     case 1: gen_helper_neon_addl_u32(tcg_ctx, CPU_V001); break;
4867     case 2: tcg_gen_add_i64(tcg_ctx, CPU_V001); break;
4868     default: abort();
4869     }
4870 }
4871 
gen_neon_subl(DisasContext * s,int size)4872 static inline void gen_neon_subl(DisasContext *s, int size)
4873 {
4874     TCGContext *tcg_ctx = s->uc->tcg_ctx;
4875     switch (size) {
4876     case 0: gen_helper_neon_subl_u16(tcg_ctx, CPU_V001); break;
4877     case 1: gen_helper_neon_subl_u32(tcg_ctx, CPU_V001); break;
4878     case 2: tcg_gen_sub_i64(tcg_ctx, CPU_V001); break;
4879     default: abort();
4880     }
4881 }
4882 
gen_neon_negl(DisasContext * s,TCGv_i64 var,int size)4883 static inline void gen_neon_negl(DisasContext *s, TCGv_i64 var, int size)
4884 {
4885     TCGContext *tcg_ctx = s->uc->tcg_ctx;
4886     switch (size) {
4887     case 0: gen_helper_neon_negl_u16(tcg_ctx, var, var); break;
4888     case 1: gen_helper_neon_negl_u32(tcg_ctx, var, var); break;
4889     case 2:
4890         tcg_gen_neg_i64(tcg_ctx, var, var);
4891         break;
4892     default: abort();
4893     }
4894 }
4895 
gen_neon_addl_saturate(DisasContext * s,TCGv_i64 op0,TCGv_i64 op1,int size)4896 static inline void gen_neon_addl_saturate(DisasContext *s, TCGv_i64 op0, TCGv_i64 op1, int size)
4897 {
4898     TCGContext *tcg_ctx = s->uc->tcg_ctx;
4899     switch (size) {
4900     case 1: gen_helper_neon_addl_saturate_s32(tcg_ctx, op0, tcg_ctx->cpu_env, op0, op1); break;
4901     case 2: gen_helper_neon_addl_saturate_s64(tcg_ctx, op0, tcg_ctx->cpu_env, op0, op1); break;
4902     default: abort();
4903     }
4904 }
4905 
gen_neon_mull(DisasContext * s,TCGv_i64 dest,TCGv_i32 a,TCGv_i32 b,int size,int u)4906 static inline void gen_neon_mull(DisasContext *s, TCGv_i64 dest, TCGv_i32 a, TCGv_i32 b,
4907                                  int size, int u)
4908 {
4909     TCGContext *tcg_ctx = s->uc->tcg_ctx;
4910     TCGv_i64 tmp;
4911 
4912     switch ((size << 1) | u) {
4913     case 0: gen_helper_neon_mull_s8(tcg_ctx, dest, a, b); break;
4914     case 1: gen_helper_neon_mull_u8(tcg_ctx, dest, a, b); break;
4915     case 2: gen_helper_neon_mull_s16(tcg_ctx, dest, a, b); break;
4916     case 3: gen_helper_neon_mull_u16(tcg_ctx, dest, a, b); break;
4917     case 4:
4918         tmp = gen_muls_i64_i32(s, a, b);
4919         tcg_gen_mov_i64(tcg_ctx, dest, tmp);
4920         tcg_temp_free_i64(tcg_ctx, tmp);
4921         break;
4922     case 5:
4923         tmp = gen_mulu_i64_i32(s, a, b);
4924         tcg_gen_mov_i64(tcg_ctx, dest, tmp);
4925         tcg_temp_free_i64(tcg_ctx, tmp);
4926         break;
4927     default: abort();
4928     }
4929 
4930     /* gen_helper_neon_mull_[su]{8|16} do not free their parameters.
4931        Don't forget to clean them now.  */
4932     if (size < 2) {
4933         tcg_temp_free_i32(tcg_ctx, a);
4934         tcg_temp_free_i32(tcg_ctx, b);
4935     }
4936 }
4937 
gen_neon_narrow_op(DisasContext * s,int op,int u,int size,TCGv_i32 dest,TCGv_i64 src)4938 static void gen_neon_narrow_op(DisasContext *s, int op, int u, int size,
4939                                TCGv_i32 dest, TCGv_i64 src)
4940 {
4941     if (op) {
4942         if (u) {
4943             gen_neon_unarrow_sats(s, size, dest, src);
4944         } else {
4945             gen_neon_narrow(s, size, dest, src);
4946         }
4947     } else {
4948         if (u) {
4949             gen_neon_narrow_satu(s, size, dest, src);
4950         } else {
4951             gen_neon_narrow_sats(s, size, dest, src);
4952         }
4953     }
4954 }
4955 
4956 /* Symbolic constants for op fields for Neon 3-register same-length.
4957  * The values correspond to bits [11:8,4]; see the ARM ARM DDI0406B
4958  * table A7-9.
4959  */
4960 #define NEON_3R_VHADD 0
4961 #define NEON_3R_VQADD 1
4962 #define NEON_3R_VRHADD 2
4963 #define NEON_3R_LOGIC 3 /* VAND,VBIC,VORR,VMOV,VORN,VEOR,VBIF,VBIT,VBSL */
4964 #define NEON_3R_VHSUB 4
4965 #define NEON_3R_VQSUB 5
4966 #define NEON_3R_VCGT 6
4967 #define NEON_3R_VCGE 7
4968 #define NEON_3R_VSHL 8
4969 #define NEON_3R_VQSHL 9
4970 #define NEON_3R_VRSHL 10
4971 #define NEON_3R_VQRSHL 11
4972 #define NEON_3R_VMAX 12
4973 #define NEON_3R_VMIN 13
4974 #define NEON_3R_VABD 14
4975 #define NEON_3R_VABA 15
4976 #define NEON_3R_VADD_VSUB 16
4977 #define NEON_3R_VTST_VCEQ 17
4978 #define NEON_3R_VML 18 /* VMLA, VMLAL, VMLS, VMLSL */
4979 #define NEON_3R_VMUL 19
4980 #define NEON_3R_VPMAX 20
4981 #define NEON_3R_VPMIN 21
4982 #define NEON_3R_VQDMULH_VQRDMULH 22
4983 #define NEON_3R_VPADD 23
4984 #define NEON_3R_SHA 24 /* SHA1C,SHA1P,SHA1M,SHA1SU0,SHA256H{2},SHA256SU1 */
4985 #define NEON_3R_VFM 25 /* VFMA, VFMS : float fused multiply-add */
4986 #define NEON_3R_FLOAT_ARITH 26 /* float VADD, VSUB, VPADD, VABD */
4987 #define NEON_3R_FLOAT_MULTIPLY 27 /* float VMLA, VMLS, VMUL */
4988 #define NEON_3R_FLOAT_CMP 28 /* float VCEQ, VCGE, VCGT */
4989 #define NEON_3R_FLOAT_ACMP 29 /* float VACGE, VACGT, VACLE, VACLT */
4990 #define NEON_3R_FLOAT_MINMAX 30 /* float VMIN, VMAX */
4991 #define NEON_3R_FLOAT_MISC 31 /* float VRECPS, VRSQRTS, VMAXNM/MINNM */
4992 
4993 static const uint8_t neon_3r_sizes[] = {
4994     /*NEON_3R_VHADD*/ 0x7,
4995     /*NEON_3R_VQADD*/ 0xf,
4996     /*NEON_3R_VRHADD*/ 0x7,
4997     /*NEON_3R_LOGIC*/ 0xf, /* size field encodes op type */
4998     /*NEON_3R_VHSUB*/ 0x7,
4999     /*NEON_3R_VQSUB*/ 0xf,
5000     /*NEON_3R_VCGT*/ 0x7,
5001     /*NEON_3R_VCGE*/ 0x7,
5002     /*NEON_3R_VSHL*/ 0xf,
5003     /*NEON_3R_VQSHL*/ 0xf,
5004     /*NEON_3R_VRSHL*/ 0xf,
5005     /*NEON_3R_VQRSHL*/ 0xf,
5006     /*NEON_3R_VMAX*/ 0x7,
5007     /*NEON_3R_VMIN*/ 0x7,
5008     /*NEON_3R_VABD*/ 0x7,
5009     /*NEON_3R_VABA*/ 0x7,
5010     /*NEON_3R_VADD_VSUB*/ 0xf,
5011     /*NEON_3R_VTST_VCEQ*/ 0x7,
5012     /*NEON_3R_VML*/ 0x7,
5013     /*NEON_3R_VMUL*/ 0x7,
5014     /*NEON_3R_VPMAX*/ 0x7,
5015     /*NEON_3R_VPMIN*/ 0x7,
5016     /*NEON_3R_VQDMULH_VQRDMULH*/ 0x6,
5017     /*NEON_3R_VPADD*/ 0x7,
5018     /*NEON_3R_SHA*/ 0xf, /* size field encodes op type */
5019     /*NEON_3R_VFM*/ 0x5, /* size bit 1 encodes op */
5020     /*NEON_3R_FLOAT_ARITH*/ 0x5, /* size bit 1 encodes op */
5021     /*NEON_3R_FLOAT_MULTIPLY*/ 0x5, /* size bit 1 encodes op */
5022     /*NEON_3R_FLOAT_CMP*/ 0x5, /* size bit 1 encodes op */
5023     /*NEON_3R_FLOAT_ACMP*/ 0x5, /* size bit 1 encodes op */
5024     /*NEON_3R_FLOAT_MINMAX*/ 0x5, /* size bit 1 encodes op */
5025     /*NEON_3R_FLOAT_MISC*/ 0x5, /* size bit 1 encodes op */
5026 };
5027 
5028 /* Symbolic constants for op fields for Neon 2-register miscellaneous.
5029  * The values correspond to bits [17:16,10:7]; see the ARM ARM DDI0406B
5030  * table A7-13.
5031  */
5032 #define NEON_2RM_VREV64 0
5033 #define NEON_2RM_VREV32 1
5034 #define NEON_2RM_VREV16 2
5035 #define NEON_2RM_VPADDL 4
5036 #define NEON_2RM_VPADDL_U 5
5037 #define NEON_2RM_AESE 6 /* Includes AESD */
5038 #define NEON_2RM_AESMC 7 /* Includes AESIMC */
5039 #define NEON_2RM_VCLS 8
5040 #define NEON_2RM_VCLZ 9
5041 #define NEON_2RM_VCNT 10
5042 #define NEON_2RM_VMVN 11
5043 #define NEON_2RM_VPADAL 12
5044 #define NEON_2RM_VPADAL_U 13
5045 #define NEON_2RM_VQABS 14
5046 #define NEON_2RM_VQNEG 15
5047 #define NEON_2RM_VCGT0 16
5048 #define NEON_2RM_VCGE0 17
5049 #define NEON_2RM_VCEQ0 18
5050 #define NEON_2RM_VCLE0 19
5051 #define NEON_2RM_VCLT0 20
5052 #define NEON_2RM_SHA1H 21
5053 #define NEON_2RM_VABS 22
5054 #define NEON_2RM_VNEG 23
5055 #define NEON_2RM_VCGT0_F 24
5056 #define NEON_2RM_VCGE0_F 25
5057 #define NEON_2RM_VCEQ0_F 26
5058 #define NEON_2RM_VCLE0_F 27
5059 #define NEON_2RM_VCLT0_F 28
5060 #define NEON_2RM_VABS_F 30
5061 #define NEON_2RM_VNEG_F 31
5062 #define NEON_2RM_VSWP 32
5063 #define NEON_2RM_VTRN 33
5064 #define NEON_2RM_VUZP 34
5065 #define NEON_2RM_VZIP 35
5066 #define NEON_2RM_VMOVN 36 /* Includes VQMOVN, VQMOVUN */
5067 #define NEON_2RM_VQMOVN 37 /* Includes VQMOVUN */
5068 #define NEON_2RM_VSHLL 38
5069 #define NEON_2RM_SHA1SU1 39 /* Includes SHA256SU0 */
5070 #define NEON_2RM_VRINTN 40
5071 #define NEON_2RM_VRINTX 41
5072 #define NEON_2RM_VRINTA 42
5073 #define NEON_2RM_VRINTZ 43
5074 #define NEON_2RM_VCVT_F16_F32 44
5075 #define NEON_2RM_VRINTM 45
5076 #define NEON_2RM_VCVT_F32_F16 46
5077 #define NEON_2RM_VRINTP 47
5078 #define NEON_2RM_VCVTAU 48
5079 #define NEON_2RM_VCVTAS 49
5080 #define NEON_2RM_VCVTNU 50
5081 #define NEON_2RM_VCVTNS 51
5082 #define NEON_2RM_VCVTPU 52
5083 #define NEON_2RM_VCVTPS 53
5084 #define NEON_2RM_VCVTMU 54
5085 #define NEON_2RM_VCVTMS 55
5086 #define NEON_2RM_VRECPE 56
5087 #define NEON_2RM_VRSQRTE 57
5088 #define NEON_2RM_VRECPE_F 58
5089 #define NEON_2RM_VRSQRTE_F 59
5090 #define NEON_2RM_VCVT_FS 60
5091 #define NEON_2RM_VCVT_FU 61
5092 #define NEON_2RM_VCVT_SF 62
5093 #define NEON_2RM_VCVT_UF 63
5094 
neon_2rm_is_float_op(int op)5095 static int neon_2rm_is_float_op(int op)
5096 {
5097     /* Return true if this neon 2reg-misc op is float-to-float */
5098     return (op == NEON_2RM_VABS_F || op == NEON_2RM_VNEG_F ||
5099             (op >= NEON_2RM_VRINTN && op <= NEON_2RM_VRINTZ) ||
5100             op == NEON_2RM_VRINTM ||
5101             (op >= NEON_2RM_VRINTP && op <= NEON_2RM_VCVTMS) ||
5102             op >= NEON_2RM_VRECPE_F);
5103 }
5104 
5105 /* Each entry in this array has bit n set if the insn allows
5106  * size value n (otherwise it will UNDEF). Since unallocated
5107  * op values will have no bits set they always UNDEF.
5108  */
5109 static const uint8_t neon_2rm_sizes[] = {
5110     /*NEON_2RM_VREV64*/ 0x7,
5111     /*NEON_2RM_VREV32*/ 0x3,
5112     /*NEON_2RM_VREV16*/ 0x1,
5113     0,
5114     /*NEON_2RM_VPADDL*/ 0x7,
5115     /*NEON_2RM_VPADDL_U*/ 0x7,
5116     /*NEON_2RM_AESE*/ 0x1,
5117     /*NEON_2RM_AESMC*/ 0x1,
5118     /*NEON_2RM_VCLS*/ 0x7,
5119     /*NEON_2RM_VCLZ*/ 0x7,
5120     /*NEON_2RM_VCNT*/ 0x1,
5121     /*NEON_2RM_VMVN*/ 0x1,
5122     /*NEON_2RM_VPADAL*/ 0x7,
5123     /*NEON_2RM_VPADAL_U*/ 0x7,
5124     /*NEON_2RM_VQABS*/ 0x7,
5125     /*NEON_2RM_VQNEG*/ 0x7,
5126     /*NEON_2RM_VCGT0*/ 0x7,
5127     /*NEON_2RM_VCGE0*/ 0x7,
5128     /*NEON_2RM_VCEQ0*/ 0x7,
5129     /*NEON_2RM_VCLE0*/ 0x7,
5130     /*NEON_2RM_VCLT0*/ 0x7,
5131     /*NEON_2RM_SHA1H*/ 0x4,
5132     /*NEON_2RM_VABS*/ 0x7,
5133     /*NEON_2RM_VNEG*/ 0x7,
5134     /*NEON_2RM_VCGT0_F*/ 0x4,
5135     /*NEON_2RM_VCGE0_F*/ 0x4,
5136     /*NEON_2RM_VCEQ0_F*/ 0x4,
5137     /*NEON_2RM_VCLE0_F*/ 0x4,
5138     /*NEON_2RM_VCLT0_F*/ 0x4,
5139     0,
5140     /*NEON_2RM_VABS_F*/ 0x4,
5141     /*NEON_2RM_VNEG_F*/ 0x4,
5142     /*NEON_2RM_VSWP*/ 0x1,
5143     /*NEON_2RM_VTRN*/ 0x7,
5144     /*NEON_2RM_VUZP*/ 0x7,
5145     /*NEON_2RM_VZIP*/ 0x7,
5146     /*NEON_2RM_VMOVN*/ 0x7,
5147     /*NEON_2RM_VQMOVN*/ 0x7,
5148     /*NEON_2RM_VSHLL*/ 0x7,
5149     /*NEON_2RM_SHA1SU1*/ 0x4,
5150     /*NEON_2RM_VRINTN*/ 0x4,
5151     /*NEON_2RM_VRINTX*/ 0x4,
5152     /*NEON_2RM_VRINTA*/ 0x4,
5153     /*NEON_2RM_VRINTZ*/ 0x4,
5154     /*NEON_2RM_VCVT_F16_F32*/ 0x2,
5155     /*NEON_2RM_VRINTM*/ 0x4,
5156     /*NEON_2RM_VCVT_F32_F16*/ 0x2,
5157     /*NEON_2RM_VRINTP*/ 0x4,
5158     /*NEON_2RM_VCVTAU*/ 0x4,
5159     /*NEON_2RM_VCVTAS*/ 0x4,
5160     /*NEON_2RM_VCVTNU*/ 0x4,
5161     /*NEON_2RM_VCVTNS*/ 0x4,
5162     /*NEON_2RM_VCVTPU*/ 0x4,
5163     /*NEON_2RM_VCVTPS*/ 0x4,
5164     /*NEON_2RM_VCVTMU*/ 0x4,
5165     /*NEON_2RM_VCVTMS*/ 0x4,
5166     /*NEON_2RM_VRECPE*/ 0x4,
5167     /*NEON_2RM_VRSQRTE*/ 0x4,
5168     /*NEON_2RM_VRECPE_F*/ 0x4,
5169     /*NEON_2RM_VRSQRTE_F*/ 0x4,
5170     /*NEON_2RM_VCVT_FS*/ 0x4,
5171     /*NEON_2RM_VCVT_FU*/ 0x4,
5172     /*NEON_2RM_VCVT_SF*/ 0x4,
5173     /*NEON_2RM_VCVT_UF*/ 0x4,
5174 };
5175 
5176 /* Translate a NEON data processing instruction.  Return nonzero if the
5177    instruction is invalid.
5178    We process data in a mixture of 32-bit and 64-bit chunks.
5179    Mostly we use 32-bit chunks so we can use normal scalar instructions.  */
5180 
disas_neon_data_insn(DisasContext * s,uint32_t insn)5181 static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
5182 {
5183     TCGContext *tcg_ctx = s->uc->tcg_ctx;
5184     int op;
5185     int q;
5186     int rd, rn, rm;
5187     int size;
5188     int shift;
5189     int pass;
5190     int count;
5191     int pairwise;
5192     int u;
5193     uint32_t imm, mask;
5194     TCGv_i32 tmp, tmp2, tmp3, tmp4, tmp5;
5195     TCGv_i64 tmp64;
5196 
5197     /* FIXME: this access check should not take precedence over UNDEF
5198      * for invalid encodings; we will generate incorrect syndrome information
5199      * for attempts to execute invalid vfp/neon encodings with FP disabled.
5200      */
5201     if (!s->cpacr_fpen) {
5202         gen_exception_insn(s, 4, EXCP_UDEF,
5203                            syn_fp_access_trap(1, 0xe, s->thumb));
5204         return 0;
5205     }
5206 
5207     if (!s->vfp_enabled)
5208       return 1;
5209     q = (insn & (1 << 6)) != 0;
5210     u = (insn >> 24) & 1;
5211     VFP_DREG_D(rd, insn);
5212     VFP_DREG_N(rn, insn);
5213     VFP_DREG_M(rm, insn);
5214     size = (insn >> 20) & 3;
5215     if ((insn & (1 << 23)) == 0) {
5216         /* Three register same length.  */
5217         op = ((insn >> 7) & 0x1e) | ((insn >> 4) & 1);
5218         /* Catch invalid op and bad size combinations: UNDEF */
5219         if ((neon_3r_sizes[op] & (1 << size)) == 0) {
5220             return 1;
5221         }
5222         /* All insns of this form UNDEF for either this condition or the
5223          * superset of cases "Q==1"; we catch the latter later.
5224          */
5225         if (q && ((rd | rn | rm) & 1)) {
5226             return 1;
5227         }
5228         /*
5229          * The SHA-1/SHA-256 3-register instructions require special treatment
5230          * here, as their size field is overloaded as an op type selector, and
5231          * they all consume their input in a single pass.
5232          */
5233         if (op == NEON_3R_SHA) {
5234             if (!q) {
5235                 return 1;
5236             }
5237             if (!u) { /* SHA-1 */
5238                 if (!arm_dc_feature(s, ARM_FEATURE_V8_SHA1)) {
5239                     return 1;
5240                 }
5241                 tmp = tcg_const_i32(tcg_ctx, rd);
5242                 tmp2 = tcg_const_i32(tcg_ctx, rn);
5243                 tmp3 = tcg_const_i32(tcg_ctx, rm);
5244                 tmp4 = tcg_const_i32(tcg_ctx, size);
5245                 gen_helper_crypto_sha1_3reg(tcg_ctx, tcg_ctx->cpu_env, tmp, tmp2, tmp3, tmp4);
5246                 tcg_temp_free_i32(tcg_ctx, tmp4);
5247             } else { /* SHA-256 */
5248                 if (!arm_dc_feature(s, ARM_FEATURE_V8_SHA256) || size == 3) {
5249                     return 1;
5250                 }
5251                 tmp = tcg_const_i32(tcg_ctx, rd);
5252                 tmp2 = tcg_const_i32(tcg_ctx, rn);
5253                 tmp3 = tcg_const_i32(tcg_ctx, rm);
5254                 switch (size) {
5255                 case 0:
5256                     gen_helper_crypto_sha256h(tcg_ctx, tcg_ctx->cpu_env, tmp, tmp2, tmp3);
5257                     break;
5258                 case 1:
5259                     gen_helper_crypto_sha256h2(tcg_ctx, tcg_ctx->cpu_env, tmp, tmp2, tmp3);
5260                     break;
5261                 case 2:
5262                     gen_helper_crypto_sha256su1(tcg_ctx, tcg_ctx->cpu_env, tmp, tmp2, tmp3);
5263                     break;
5264                 }
5265             }
5266             tcg_temp_free_i32(tcg_ctx, tmp);
5267             tcg_temp_free_i32(tcg_ctx, tmp2);
5268             tcg_temp_free_i32(tcg_ctx, tmp3);
5269             return 0;
5270         }
5271         if (size == 3 && op != NEON_3R_LOGIC) {
5272             /* 64-bit element instructions. */
5273             for (pass = 0; pass < (q ? 2 : 1); pass++) {
5274                 neon_load_reg64(tcg_ctx, tcg_ctx->cpu_V0, rn + pass);
5275                 neon_load_reg64(tcg_ctx, tcg_ctx->cpu_V1, rm + pass);
5276                 switch (op) {
5277                 case NEON_3R_VQADD:
5278                     if (u) {
5279                         gen_helper_neon_qadd_u64(tcg_ctx, tcg_ctx->cpu_V0, tcg_ctx->cpu_env,
5280                                                  tcg_ctx->cpu_V0, tcg_ctx->cpu_V1);
5281                     } else {
5282                         gen_helper_neon_qadd_s64(tcg_ctx, tcg_ctx->cpu_V0, tcg_ctx->cpu_env,
5283                                                  tcg_ctx->cpu_V0, tcg_ctx->cpu_V1);
5284                     }
5285                     break;
5286                 case NEON_3R_VQSUB:
5287                     if (u) {
5288                         gen_helper_neon_qsub_u64(tcg_ctx, tcg_ctx->cpu_V0, tcg_ctx->cpu_env,
5289                                                  tcg_ctx->cpu_V0, tcg_ctx->cpu_V1);
5290                     } else {
5291                         gen_helper_neon_qsub_s64(tcg_ctx, tcg_ctx->cpu_V0, tcg_ctx->cpu_env,
5292                                                  tcg_ctx->cpu_V0, tcg_ctx->cpu_V1);
5293                     }
5294                     break;
5295                 case NEON_3R_VSHL:
5296                     if (u) {
5297                         gen_helper_neon_shl_u64(tcg_ctx, tcg_ctx->cpu_V0, tcg_ctx->cpu_V1, tcg_ctx->cpu_V0);
5298                     } else {
5299                         gen_helper_neon_shl_s64(tcg_ctx, tcg_ctx->cpu_V0, tcg_ctx->cpu_V1, tcg_ctx->cpu_V0);
5300                     }
5301                     break;
5302                 case NEON_3R_VQSHL:
5303                     if (u) {
5304                         gen_helper_neon_qshl_u64(tcg_ctx, tcg_ctx->cpu_V0, tcg_ctx->cpu_env,
5305                                                  tcg_ctx->cpu_V1, tcg_ctx->cpu_V0);
5306                     } else {
5307                         gen_helper_neon_qshl_s64(tcg_ctx, tcg_ctx->cpu_V0, tcg_ctx->cpu_env,
5308                                                  tcg_ctx->cpu_V1, tcg_ctx->cpu_V0);
5309                     }
5310                     break;
5311                 case NEON_3R_VRSHL:
5312                     if (u) {
5313                         gen_helper_neon_rshl_u64(tcg_ctx, tcg_ctx->cpu_V0, tcg_ctx->cpu_V1, tcg_ctx->cpu_V0);
5314                     } else {
5315                         gen_helper_neon_rshl_s64(tcg_ctx, tcg_ctx->cpu_V0, tcg_ctx->cpu_V1, tcg_ctx->cpu_V0);
5316                     }
5317                     break;
5318                 case NEON_3R_VQRSHL:
5319                     if (u) {
5320                         gen_helper_neon_qrshl_u64(tcg_ctx, tcg_ctx->cpu_V0, tcg_ctx->cpu_env,
5321                                                   tcg_ctx->cpu_V1, tcg_ctx->cpu_V0);
5322                     } else {
5323                         gen_helper_neon_qrshl_s64(tcg_ctx, tcg_ctx->cpu_V0, tcg_ctx->cpu_env,
5324                                                   tcg_ctx->cpu_V1, tcg_ctx->cpu_V0);
5325                     }
5326                     break;
5327                 case NEON_3R_VADD_VSUB:
5328                     if (u) {
5329                         tcg_gen_sub_i64(tcg_ctx, CPU_V001);
5330                     } else {
5331                         tcg_gen_add_i64(tcg_ctx, CPU_V001);
5332                     }
5333                     break;
5334                 default:
5335                     abort();
5336                 }
5337                 neon_store_reg64(tcg_ctx, tcg_ctx->cpu_V0, rd + pass);
5338             }
5339             return 0;
5340         }
5341         pairwise = 0;
5342         switch (op) {
5343         case NEON_3R_VSHL:
5344         case NEON_3R_VQSHL:
5345         case NEON_3R_VRSHL:
5346         case NEON_3R_VQRSHL:
5347             {
5348                 int rtmp;
5349                 /* Shift instruction operands are reversed.  */
5350                 rtmp = rn;
5351                 rn = rm;
5352                 rm = rtmp;
5353             }
5354             break;
5355         case NEON_3R_VPADD:
5356             if (u) {
5357                 return 1;
5358             }
5359             /* Fall through */
5360         case NEON_3R_VPMAX:
5361         case NEON_3R_VPMIN:
5362             pairwise = 1;
5363             break;
5364         case NEON_3R_FLOAT_ARITH:
5365             pairwise = (u && size < 2); /* if VPADD (float) */
5366             break;
5367         case NEON_3R_FLOAT_MINMAX:
5368             pairwise = u; /* if VPMIN/VPMAX (float) */
5369             break;
5370         case NEON_3R_FLOAT_CMP:
5371             if (!u && size) {
5372                 /* no encoding for U=0 C=1x */
5373                 return 1;
5374             }
5375             break;
5376         case NEON_3R_FLOAT_ACMP:
5377             if (!u) {
5378                 return 1;
5379             }
5380             break;
5381         case NEON_3R_FLOAT_MISC:
5382             /* VMAXNM/VMINNM in ARMv8 */
5383             if (u && !arm_dc_feature(s, ARM_FEATURE_V8)) {
5384                 return 1;
5385             }
5386             break;
5387         case NEON_3R_VMUL:
5388             if (u && (size != 0)) {
5389                 /* UNDEF on invalid size for polynomial subcase */
5390                 return 1;
5391             }
5392             break;
5393         case NEON_3R_VFM:
5394             if (!arm_dc_feature(s, ARM_FEATURE_VFP4) || u) {
5395                 return 1;
5396             }
5397             break;
5398         default:
5399             break;
5400         }
5401 
5402         if (pairwise && q) {
5403             /* All the pairwise insns UNDEF if Q is set */
5404             return 1;
5405         }
5406 
5407         for (pass = 0; pass < (q ? 4 : 2); pass++) {
5408 
5409         if (pairwise) {
5410             /* Pairwise.  */
5411             if (pass < 1) {
5412                 tmp = neon_load_reg(tcg_ctx, rn, 0);
5413                 tmp2 = neon_load_reg(tcg_ctx, rn, 1);
5414             } else {
5415                 tmp = neon_load_reg(tcg_ctx, rm, 0);
5416                 tmp2 = neon_load_reg(tcg_ctx, rm, 1);
5417             }
5418         } else {
5419             /* Elementwise.  */
5420             tmp = neon_load_reg(tcg_ctx, rn, pass);
5421             tmp2 = neon_load_reg(tcg_ctx, rm, pass);
5422         }
5423         switch (op) {
5424         case NEON_3R_VHADD:
5425             GEN_NEON_INTEGER_OP(hadd);
5426             break;
5427         case NEON_3R_VQADD:
5428             GEN_NEON_INTEGER_OP_ENV(qadd);
5429             break;
5430         case NEON_3R_VRHADD:
5431             GEN_NEON_INTEGER_OP(rhadd);
5432             break;
5433         case NEON_3R_LOGIC: /* Logic ops.  */
5434             switch ((u << 2) | size) {
5435             case 0: /* VAND */
5436                 tcg_gen_and_i32(tcg_ctx, tmp, tmp, tmp2);
5437                 break;
5438             case 1: /* BIC */
5439                 tcg_gen_andc_i32(tcg_ctx, tmp, tmp, tmp2);
5440                 break;
5441             case 2: /* VORR */
5442                 tcg_gen_or_i32(tcg_ctx, tmp, tmp, tmp2);
5443                 break;
5444             case 3: /* VORN */
5445                 tcg_gen_orc_i32(tcg_ctx, tmp, tmp, tmp2);
5446                 break;
5447             case 4: /* VEOR */
5448                 tcg_gen_xor_i32(tcg_ctx, tmp, tmp, tmp2);
5449                 break;
5450             case 5: /* VBSL */
5451                 tmp3 = neon_load_reg(tcg_ctx, rd, pass);
5452                 gen_neon_bsl(s, tmp, tmp, tmp2, tmp3);
5453                 tcg_temp_free_i32(tcg_ctx, tmp3);
5454                 break;
5455             case 6: /* VBIT */
5456                 tmp3 = neon_load_reg(tcg_ctx, rd, pass);
5457                 gen_neon_bsl(s, tmp, tmp, tmp3, tmp2);
5458                 tcg_temp_free_i32(tcg_ctx, tmp3);
5459                 break;
5460             case 7: /* VBIF */
5461                 tmp3 = neon_load_reg(tcg_ctx, rd, pass);
5462                 gen_neon_bsl(s, tmp, tmp3, tmp, tmp2);
5463                 tcg_temp_free_i32(tcg_ctx, tmp3);
5464                 break;
5465             }
5466             break;
5467         case NEON_3R_VHSUB:
5468             GEN_NEON_INTEGER_OP(hsub);
5469             break;
5470         case NEON_3R_VQSUB:
5471             GEN_NEON_INTEGER_OP_ENV(qsub);
5472             break;
5473         case NEON_3R_VCGT:
5474             GEN_NEON_INTEGER_OP(cgt);
5475             break;
5476         case NEON_3R_VCGE:
5477             GEN_NEON_INTEGER_OP(cge);
5478             break;
5479         case NEON_3R_VSHL:
5480             GEN_NEON_INTEGER_OP(shl);
5481             break;
5482         case NEON_3R_VQSHL:
5483             GEN_NEON_INTEGER_OP_ENV(qshl);
5484             break;
5485         case NEON_3R_VRSHL:
5486             GEN_NEON_INTEGER_OP(rshl);
5487             break;
5488         case NEON_3R_VQRSHL:
5489             GEN_NEON_INTEGER_OP_ENV(qrshl);
5490             break;
5491         case NEON_3R_VMAX:
5492             GEN_NEON_INTEGER_OP(max);
5493             break;
5494         case NEON_3R_VMIN:
5495             GEN_NEON_INTEGER_OP(min);
5496             break;
5497         case NEON_3R_VABD:
5498             GEN_NEON_INTEGER_OP(abd);
5499             break;
5500         case NEON_3R_VABA:
5501             GEN_NEON_INTEGER_OP(abd);
5502             tcg_temp_free_i32(tcg_ctx, tmp2);
5503             tmp2 = neon_load_reg(tcg_ctx, rd, pass);
5504             gen_neon_add(s, size, tmp, tmp2);
5505             break;
5506         case NEON_3R_VADD_VSUB:
5507             if (!u) { /* VADD */
5508                 gen_neon_add(s, size, tmp, tmp2);
5509             } else { /* VSUB */
5510                 switch (size) {
5511                 case 0: gen_helper_neon_sub_u8(tcg_ctx, tmp, tmp, tmp2); break;
5512                 case 1: gen_helper_neon_sub_u16(tcg_ctx, tmp, tmp, tmp2); break;
5513                 case 2: tcg_gen_sub_i32(tcg_ctx, tmp, tmp, tmp2); break;
5514                 default: abort();
5515                 }
5516             }
5517             break;
5518         case NEON_3R_VTST_VCEQ:
5519             if (!u) { /* VTST */
5520                 switch (size) {
5521                 case 0: gen_helper_neon_tst_u8(tcg_ctx, tmp, tmp, tmp2); break;
5522                 case 1: gen_helper_neon_tst_u16(tcg_ctx, tmp, tmp, tmp2); break;
5523                 case 2: gen_helper_neon_tst_u32(tcg_ctx, tmp, tmp, tmp2); break;
5524                 default: abort();
5525                 }
5526             } else { /* VCEQ */
5527                 switch (size) {
5528                 case 0: gen_helper_neon_ceq_u8(tcg_ctx, tmp, tmp, tmp2); break;
5529                 case 1: gen_helper_neon_ceq_u16(tcg_ctx, tmp, tmp, tmp2); break;
5530                 case 2: gen_helper_neon_ceq_u32(tcg_ctx, tmp, tmp, tmp2); break;
5531                 default: abort();
5532                 }
5533             }
5534             break;
5535         case NEON_3R_VML: /* VMLA, VMLAL, VMLS,VMLSL */
5536             switch (size) {
5537             case 0: gen_helper_neon_mul_u8(tcg_ctx, tmp, tmp, tmp2); break;
5538             case 1: gen_helper_neon_mul_u16(tcg_ctx, tmp, tmp, tmp2); break;
5539             case 2: tcg_gen_mul_i32(tcg_ctx, tmp, tmp, tmp2); break;
5540             default: abort();
5541             }
5542             tcg_temp_free_i32(tcg_ctx, tmp2);
5543             tmp2 = neon_load_reg(tcg_ctx, rd, pass);
5544             if (u) { /* VMLS */
5545                 gen_neon_rsb(s, size, tmp, tmp2);
5546             } else { /* VMLA */
5547                 gen_neon_add(s, size, tmp, tmp2);
5548             }
5549             break;
5550         case NEON_3R_VMUL:
5551             if (u) { /* polynomial */
5552                 gen_helper_neon_mul_p8(tcg_ctx, tmp, tmp, tmp2);
5553             } else { /* Integer */
5554                 switch (size) {
5555                 case 0: gen_helper_neon_mul_u8(tcg_ctx, tmp, tmp, tmp2); break;
5556                 case 1: gen_helper_neon_mul_u16(tcg_ctx, tmp, tmp, tmp2); break;
5557                 case 2: tcg_gen_mul_i32(tcg_ctx, tmp, tmp, tmp2); break;
5558                 default: abort();
5559                 }
5560             }
5561             break;
5562         case NEON_3R_VPMAX:
5563             GEN_NEON_INTEGER_OP(pmax);
5564             break;
5565         case NEON_3R_VPMIN:
5566             GEN_NEON_INTEGER_OP(pmin);
5567             break;
5568         case NEON_3R_VQDMULH_VQRDMULH: /* Multiply high.  */
5569             if (!u) { /* VQDMULH */
5570                 switch (size) {
5571                 case 1:
5572                     gen_helper_neon_qdmulh_s16(tcg_ctx, tmp, tcg_ctx->cpu_env, tmp, tmp2);
5573                     break;
5574                 case 2:
5575                     gen_helper_neon_qdmulh_s32(tcg_ctx, tmp, tcg_ctx->cpu_env, tmp, tmp2);
5576                     break;
5577                 default: abort();
5578                 }
5579             } else { /* VQRDMULH */
5580                 switch (size) {
5581                 case 1:
5582                     gen_helper_neon_qrdmulh_s16(tcg_ctx, tmp, tcg_ctx->cpu_env, tmp, tmp2);
5583                     break;
5584                 case 2:
5585                     gen_helper_neon_qrdmulh_s32(tcg_ctx, tmp, tcg_ctx->cpu_env, tmp, tmp2);
5586                     break;
5587                 default: abort();
5588                 }
5589             }
5590             break;
5591         case NEON_3R_VPADD:
5592             switch (size) {
5593             case 0: gen_helper_neon_padd_u8(tcg_ctx, tmp, tmp, tmp2); break;
5594             case 1: gen_helper_neon_padd_u16(tcg_ctx, tmp, tmp, tmp2); break;
5595             case 2: tcg_gen_add_i32(tcg_ctx, tmp, tmp, tmp2); break;
5596             default: abort();
5597             }
5598             break;
5599         case NEON_3R_FLOAT_ARITH: /* Floating point arithmetic. */
5600         {
5601             TCGv_ptr fpstatus = get_fpstatus_ptr(s, 1);
5602             switch ((u << 2) | size) {
5603             case 0: /* VADD */
5604             case 4: /* VPADD */
5605                 gen_helper_vfp_adds(tcg_ctx, tmp, tmp, tmp2, fpstatus);
5606                 break;
5607             case 2: /* VSUB */
5608                 gen_helper_vfp_subs(tcg_ctx, tmp, tmp, tmp2, fpstatus);
5609                 break;
5610             case 6: /* VABD */
5611                 gen_helper_neon_abd_f32(tcg_ctx, tmp, tmp, tmp2, fpstatus);
5612                 break;
5613             default:
5614                 abort();
5615             }
5616             tcg_temp_free_ptr(tcg_ctx, fpstatus);
5617             break;
5618         }
5619         case NEON_3R_FLOAT_MULTIPLY:
5620         {
5621             TCGv_ptr fpstatus = get_fpstatus_ptr(s, 1);
5622             gen_helper_vfp_muls(tcg_ctx, tmp, tmp, tmp2, fpstatus);
5623             if (!u) {
5624                 tcg_temp_free_i32(tcg_ctx, tmp2);
5625                 tmp2 = neon_load_reg(tcg_ctx, rd, pass);
5626                 if (size == 0) {
5627                     gen_helper_vfp_adds(tcg_ctx, tmp, tmp, tmp2, fpstatus);
5628                 } else {
5629                     gen_helper_vfp_subs(tcg_ctx, tmp, tmp2, tmp, fpstatus);
5630                 }
5631             }
5632             tcg_temp_free_ptr(tcg_ctx, fpstatus);
5633             break;
5634         }
5635         case NEON_3R_FLOAT_CMP:
5636         {
5637             TCGv_ptr fpstatus = get_fpstatus_ptr(s, 1);
5638             if (!u) {
5639                 gen_helper_neon_ceq_f32(tcg_ctx, tmp, tmp, tmp2, fpstatus);
5640             } else {
5641                 if (size == 0) {
5642                     gen_helper_neon_cge_f32(tcg_ctx, tmp, tmp, tmp2, fpstatus);
5643                 } else {
5644                     gen_helper_neon_cgt_f32(tcg_ctx, tmp, tmp, tmp2, fpstatus);
5645                 }
5646             }
5647             tcg_temp_free_ptr(tcg_ctx, fpstatus);
5648             break;
5649         }
5650         case NEON_3R_FLOAT_ACMP:
5651         {
5652             TCGv_ptr fpstatus = get_fpstatus_ptr(s, 1);
5653             if (size == 0) {
5654                 gen_helper_neon_acge_f32(tcg_ctx, tmp, tmp, tmp2, fpstatus);
5655             } else {
5656                 gen_helper_neon_acgt_f32(tcg_ctx, tmp, tmp, tmp2, fpstatus);
5657             }
5658             tcg_temp_free_ptr(tcg_ctx, fpstatus);
5659             break;
5660         }
5661         case NEON_3R_FLOAT_MINMAX:
5662         {
5663             TCGv_ptr fpstatus = get_fpstatus_ptr(s, 1);
5664             if (size == 0) {
5665                 gen_helper_vfp_maxs(tcg_ctx, tmp, tmp, tmp2, fpstatus);
5666             } else {
5667                 gen_helper_vfp_mins(tcg_ctx, tmp, tmp, tmp2, fpstatus);
5668             }
5669             tcg_temp_free_ptr(tcg_ctx, fpstatus);
5670             break;
5671         }
5672         case NEON_3R_FLOAT_MISC:
5673             if (u) {
5674                 /* VMAXNM/VMINNM */
5675                 TCGv_ptr fpstatus = get_fpstatus_ptr(s, 1);
5676                 if (size == 0) {
5677                     gen_helper_vfp_maxnums(tcg_ctx, tmp, tmp, tmp2, fpstatus);
5678                 } else {
5679                     gen_helper_vfp_minnums(tcg_ctx, tmp, tmp, tmp2, fpstatus);
5680                 }
5681                 tcg_temp_free_ptr(tcg_ctx, fpstatus);
5682             } else {
5683                 if (size == 0) {
5684                     gen_helper_recps_f32(tcg_ctx, tmp, tmp, tmp2, tcg_ctx->cpu_env);
5685                 } else {
5686                     gen_helper_rsqrts_f32(tcg_ctx, tmp, tmp, tmp2, tcg_ctx->cpu_env);
5687               }
5688             }
5689             break;
5690         case NEON_3R_VFM:
5691         {
5692             /* VFMA, VFMS: fused multiply-add */
5693             TCGv_ptr fpstatus = get_fpstatus_ptr(s, 1);
5694             TCGv_i32 tmp3 = neon_load_reg(tcg_ctx, rd, pass);
5695             if (size) {
5696                 /* VFMS */
5697                 gen_helper_vfp_negs(tcg_ctx, tmp, tmp);
5698             }
5699             gen_helper_vfp_muladds(tcg_ctx, tmp, tmp, tmp2, tmp3, fpstatus);
5700             tcg_temp_free_i32(tcg_ctx, tmp3);
5701             tcg_temp_free_ptr(tcg_ctx, fpstatus);
5702             break;
5703         }
5704         default:
5705             abort();
5706         }
5707         tcg_temp_free_i32(tcg_ctx, tmp2);
5708 
5709         /* Save the result.  For elementwise operations we can put it
5710            straight into the destination register.  For pairwise operations
5711            we have to be careful to avoid clobbering the source operands.  */
5712         if (pairwise && rd == rm) {
5713             neon_store_scratch(tcg_ctx, pass, tmp);
5714         } else {
5715             neon_store_reg(tcg_ctx, rd, pass, tmp);
5716         }
5717 
5718         } /* for pass */
5719         if (pairwise && rd == rm) {
5720             for (pass = 0; pass < (q ? 4 : 2); pass++) {
5721                 tmp = neon_load_scratch(tcg_ctx, pass);
5722                 neon_store_reg(tcg_ctx, rd, pass, tmp);
5723             }
5724         }
5725         /* End of 3 register same size operations.  */
5726     } else if (insn & (1 << 4)) {
5727         if ((insn & 0x00380080) != 0) {
5728             /* Two registers and shift.  */
5729             op = (insn >> 8) & 0xf;
5730             if (insn & (1 << 7)) {
5731                 /* 64-bit shift. */
5732                 if (op > 7) {
5733                     return 1;
5734                 }
5735                 size = 3;
5736             } else {
5737                 size = 2;
5738                 while ((insn & (1 << (size + 19))) == 0)
5739                     size--;
5740             }
5741             shift = (insn >> 16) & ((1 << (3 + size)) - 1);
5742             /* To avoid excessive duplication of ops we implement shift
5743                by immediate using the variable shift operations.  */
5744             if (op < 8) {
5745                 /* Shift by immediate:
5746                    VSHR, VSRA, VRSHR, VRSRA, VSRI, VSHL, VQSHL, VQSHLU.  */
5747                 if (q && ((rd | rm) & 1)) {
5748                     return 1;
5749                 }
5750                 if (!u && (op == 4 || op == 6)) {
5751                     return 1;
5752                 }
5753                 /* Right shifts are encoded as N - shift, where N is the
5754                    element size in bits.  */
5755                 if (op <= 4)
5756                     shift = shift - (1 << (size + 3));
5757                 if (size == 3) {
5758                     count = q + 1;
5759                 } else {
5760                     count = q ? 4: 2;
5761                 }
5762                 switch (size) {
5763                 case 0:
5764                     imm = (uint8_t) shift;
5765                     imm |= imm << 8;
5766                     imm |= imm << 16;
5767                     break;
5768                 case 1:
5769                     imm = (uint16_t) shift;
5770                     imm |= imm << 16;
5771                     break;
5772                 case 2:
5773                 case 3:
5774                     imm = shift;
5775                     break;
5776                 default:
5777                     abort();
5778                 }
5779 
5780                 for (pass = 0; pass < count; pass++) {
5781                     if (size == 3) {
5782                         neon_load_reg64(tcg_ctx, tcg_ctx->cpu_V0, rm + pass);
5783                         tcg_gen_movi_i64(tcg_ctx, tcg_ctx->cpu_V1, imm);
5784                         switch (op) {
5785                         case 0:  /* VSHR */
5786                         case 1:  /* VSRA */
5787                             if (u)
5788                                 gen_helper_neon_shl_u64(tcg_ctx, tcg_ctx->cpu_V0, tcg_ctx->cpu_V0, tcg_ctx->cpu_V1);
5789                             else
5790                                 gen_helper_neon_shl_s64(tcg_ctx, tcg_ctx->cpu_V0, tcg_ctx->cpu_V0, tcg_ctx->cpu_V1);
5791                             break;
5792                         case 2: /* VRSHR */
5793                         case 3: /* VRSRA */
5794                             if (u)
5795                                 gen_helper_neon_rshl_u64(tcg_ctx, tcg_ctx->cpu_V0, tcg_ctx->cpu_V0, tcg_ctx->cpu_V1);
5796                             else
5797                                 gen_helper_neon_rshl_s64(tcg_ctx, tcg_ctx->cpu_V0, tcg_ctx->cpu_V0, tcg_ctx->cpu_V1);
5798                             break;
5799                         case 4: /* VSRI */
5800                         case 5: /* VSHL, VSLI */
5801                             gen_helper_neon_shl_u64(tcg_ctx, tcg_ctx->cpu_V0, tcg_ctx->cpu_V0, tcg_ctx->cpu_V1);
5802                             break;
5803                         case 6: /* VQSHLU */
5804                             gen_helper_neon_qshlu_s64(tcg_ctx, tcg_ctx->cpu_V0, tcg_ctx->cpu_env,
5805                                                       tcg_ctx->cpu_V0, tcg_ctx->cpu_V1);
5806                             break;
5807                         case 7: /* VQSHL */
5808                             if (u) {
5809                                 gen_helper_neon_qshl_u64(tcg_ctx, tcg_ctx->cpu_V0, tcg_ctx->cpu_env,
5810                                                          tcg_ctx->cpu_V0, tcg_ctx->cpu_V1);
5811                             } else {
5812                                 gen_helper_neon_qshl_s64(tcg_ctx, tcg_ctx->cpu_V0, tcg_ctx->cpu_env,
5813                                                          tcg_ctx->cpu_V0, tcg_ctx->cpu_V1);
5814                             }
5815                             break;
5816                         }
5817                         if (op == 1 || op == 3) {
5818                             /* Accumulate.  */
5819                             neon_load_reg64(tcg_ctx, tcg_ctx->cpu_V1, rd + pass);
5820                             tcg_gen_add_i64(tcg_ctx, tcg_ctx->cpu_V0, tcg_ctx->cpu_V0, tcg_ctx->cpu_V1);
5821                         } else if (op == 4 || (op == 5 && u)) {
5822                             /* Insert */
5823                             uint64_t mask;
5824                             neon_load_reg64(tcg_ctx, tcg_ctx->cpu_V1, rd + pass);
5825                             if (shift < -63 || shift > 63) {
5826                                 mask = 0;
5827                             } else {
5828                                 if (op == 4) {
5829                                     mask = 0xffffffffffffffffull >> -shift;
5830                                 } else {
5831                                     mask = 0xffffffffffffffffull << shift;
5832                                 }
5833                             }
5834                             tcg_gen_andi_i64(tcg_ctx, tcg_ctx->cpu_V1, tcg_ctx->cpu_V1, ~mask);
5835                             tcg_gen_or_i64(tcg_ctx, tcg_ctx->cpu_V0, tcg_ctx->cpu_V0, tcg_ctx->cpu_V1);
5836                         }
5837                         neon_store_reg64(tcg_ctx, tcg_ctx->cpu_V0, rd + pass);
5838                     } else { /* size < 3 */
5839                         /* Operands in T0 and T1.  */
5840                         tmp = neon_load_reg(tcg_ctx, rm, pass);
5841                         tmp2 = tcg_temp_new_i32(tcg_ctx);
5842                         tcg_gen_movi_i32(tcg_ctx, tmp2, imm);
5843                         switch (op) {
5844                         case 0:  /* VSHR */
5845                         case 1:  /* VSRA */
5846                             GEN_NEON_INTEGER_OP(shl);
5847                             break;
5848                         case 2: /* VRSHR */
5849                         case 3: /* VRSRA */
5850                             GEN_NEON_INTEGER_OP(rshl);
5851                             break;
5852                         case 4: /* VSRI */
5853                         case 5: /* VSHL, VSLI */
5854                             switch (size) {
5855                             case 0: gen_helper_neon_shl_u8(tcg_ctx, tmp, tmp, tmp2); break;
5856                             case 1: gen_helper_neon_shl_u16(tcg_ctx, tmp, tmp, tmp2); break;
5857                             case 2: gen_helper_neon_shl_u32(tcg_ctx, tmp, tmp, tmp2); break;
5858                             default: abort();
5859                             }
5860                             break;
5861                         case 6: /* VQSHLU */
5862                             switch (size) {
5863                             case 0:
5864                                 gen_helper_neon_qshlu_s8(tcg_ctx, tmp, tcg_ctx->cpu_env,
5865                                                          tmp, tmp2);
5866                                 break;
5867                             case 1:
5868                                 gen_helper_neon_qshlu_s16(tcg_ctx, tmp, tcg_ctx->cpu_env,
5869                                                           tmp, tmp2);
5870                                 break;
5871                             case 2:
5872                                 gen_helper_neon_qshlu_s32(tcg_ctx, tmp, tcg_ctx->cpu_env,
5873                                                           tmp, tmp2);
5874                                 break;
5875                             default:
5876                                 abort();
5877                             }
5878                             break;
5879                         case 7: /* VQSHL */
5880                             GEN_NEON_INTEGER_OP_ENV(qshl);
5881                             break;
5882                         }
5883                         tcg_temp_free_i32(tcg_ctx, tmp2);
5884 
5885                         if (op == 1 || op == 3) {
5886                             /* Accumulate.  */
5887                             tmp2 = neon_load_reg(tcg_ctx, rd, pass);
5888                             gen_neon_add(s, size, tmp, tmp2);
5889                             tcg_temp_free_i32(tcg_ctx, tmp2);
5890                         } else if (op == 4 || (op == 5 && u)) {
5891                             /* Insert */
5892                             switch (size) {
5893                             case 0:
5894                                 if (op == 4)
5895                                     mask = 0xff >> -shift;
5896                                 else
5897                                     mask = (uint8_t)(0xff << shift);
5898                                 mask |= mask << 8;
5899                                 mask |= mask << 16;
5900                                 break;
5901                             case 1:
5902                                 if (op == 4)
5903                                     mask = 0xffff >> -shift;
5904                                 else
5905                                     mask = (uint16_t)(0xffff << shift);
5906                                 mask |= mask << 16;
5907                                 break;
5908                             case 2:
5909                                 if (shift < -31 || shift > 31) {
5910                                     mask = 0;
5911                                 } else {
5912                                     if (op == 4)
5913                                         mask = 0xffffffffu >> -shift;
5914                                     else
5915                                         mask = 0xffffffffu << shift;
5916                                 }
5917                                 break;
5918                             default:
5919                                 abort();
5920                             }
5921                             tmp2 = neon_load_reg(tcg_ctx, rd, pass);
5922                             tcg_gen_andi_i32(tcg_ctx, tmp, tmp, mask);
5923                             tcg_gen_andi_i32(tcg_ctx, tmp2, tmp2, ~mask);
5924                             tcg_gen_or_i32(tcg_ctx, tmp, tmp, tmp2);
5925                             tcg_temp_free_i32(tcg_ctx, tmp2);
5926                         }
5927                         neon_store_reg(tcg_ctx, rd, pass, tmp);
5928                     }
5929                 } /* for pass */
5930             } else if (op < 10) {
5931                 /* Shift by immediate and narrow:
5932                    VSHRN, VRSHRN, VQSHRN, VQRSHRN.  */
5933                 int input_unsigned = (op == 8) ? !u : u;
5934                 if (rm & 1) {
5935                     return 1;
5936                 }
5937                 shift = shift - (1 << (size + 3));
5938                 size++;
5939                 if (size == 3) {
5940                     tmp64 = tcg_const_i64(tcg_ctx, shift);
5941                     neon_load_reg64(tcg_ctx, tcg_ctx->cpu_V0, rm);
5942                     neon_load_reg64(tcg_ctx, tcg_ctx->cpu_V1, rm + 1);
5943                     for (pass = 0; pass < 2; pass++) {
5944                         TCGv_i64 in;
5945                         if (pass == 0) {
5946                             in = tcg_ctx->cpu_V0;
5947                         } else {
5948                             in = tcg_ctx->cpu_V1;
5949                         }
5950                         if (q) {
5951                             if (input_unsigned) {
5952                                 gen_helper_neon_rshl_u64(tcg_ctx, tcg_ctx->cpu_V0, in, tmp64);
5953                             } else {
5954                                 gen_helper_neon_rshl_s64(tcg_ctx, tcg_ctx->cpu_V0, in, tmp64);
5955                             }
5956                         } else {
5957                             if (input_unsigned) {
5958                                 gen_helper_neon_shl_u64(tcg_ctx, tcg_ctx->cpu_V0, in, tmp64);
5959                             } else {
5960                                 gen_helper_neon_shl_s64(tcg_ctx, tcg_ctx->cpu_V0, in, tmp64);
5961                             }
5962                         }
5963                         tmp = tcg_temp_new_i32(tcg_ctx);
5964                         gen_neon_narrow_op(s, op == 8, u, size - 1, tmp, tcg_ctx->cpu_V0);
5965                         neon_store_reg(tcg_ctx, rd, pass, tmp);
5966                     } /* for pass */
5967                     tcg_temp_free_i64(tcg_ctx, tmp64);
5968                 } else {
5969                     if (size == 1) {
5970                         imm = (uint16_t)shift;
5971                         imm |= imm << 16;
5972                     } else {
5973                         /* size == 2 */
5974                         imm = (uint32_t)shift;
5975                     }
5976                     tmp2 = tcg_const_i32(tcg_ctx, imm);
5977                     tmp4 = neon_load_reg(tcg_ctx, rm + 1, 0);
5978                     tmp5 = neon_load_reg(tcg_ctx, rm + 1, 1);
5979                     for (pass = 0; pass < 2; pass++) {
5980                         if (pass == 0) {
5981                             tmp = neon_load_reg(tcg_ctx, rm, 0);
5982                         } else {
5983                             tmp = tmp4;
5984                         }
5985                         gen_neon_shift_narrow(s, size, tmp, tmp2, q,
5986                                               input_unsigned);
5987                         if (pass == 0) {
5988                             tmp3 = neon_load_reg(tcg_ctx, rm, 1);
5989                         } else {
5990                             tmp3 = tmp5;
5991                         }
5992                         gen_neon_shift_narrow(s, size, tmp3, tmp2, q,
5993                                               input_unsigned);
5994                         tcg_gen_concat_i32_i64(tcg_ctx, tcg_ctx->cpu_V0, tmp, tmp3);
5995                         tcg_temp_free_i32(tcg_ctx, tmp);
5996                         tcg_temp_free_i32(tcg_ctx, tmp3);
5997                         tmp = tcg_temp_new_i32(tcg_ctx);
5998                         gen_neon_narrow_op(s, op == 8, u, size - 1, tmp, tcg_ctx->cpu_V0);
5999                         neon_store_reg(tcg_ctx, rd, pass, tmp);
6000                     } /* for pass */
6001                     tcg_temp_free_i32(tcg_ctx, tmp2);
6002                 }
6003             } else if (op == 10) {
6004                 /* VSHLL, VMOVL */
6005                 if (q || (rd & 1)) {
6006                     return 1;
6007                 }
6008                 tmp = neon_load_reg(tcg_ctx, rm, 0);
6009                 tmp2 = neon_load_reg(tcg_ctx, rm, 1);
6010                 for (pass = 0; pass < 2; pass++) {
6011                     if (pass == 1)
6012                         tmp = tmp2;
6013 
6014                     gen_neon_widen(s, tcg_ctx->cpu_V0, tmp, size, u);
6015 
6016                     if (shift != 0) {
6017                         /* The shift is less than the width of the source
6018                            type, so we can just shift the whole register.  */
6019                         tcg_gen_shli_i64(tcg_ctx, tcg_ctx->cpu_V0, tcg_ctx->cpu_V0, shift);
6020                         /* Widen the result of shift: we need to clear
6021                          * the potential overflow bits resulting from
6022                          * left bits of the narrow input appearing as
6023                          * right bits of left the neighbour narrow
6024                          * input.  */
6025                         if (size < 2 || !u) {
6026                             uint64_t imm64;
6027                             if (size == 0) {
6028                                 imm = (0xffu >> (8 - shift));
6029                                 imm |= imm << 16;
6030                             } else if (size == 1) {
6031                                 imm = 0xffff >> (16 - shift);
6032                             } else {
6033                                 /* size == 2 */
6034                                 imm = 0xffffffff >> (32 - shift);
6035                             }
6036                             if (size < 2) {
6037                                 imm64 = imm | (((uint64_t)imm) << 32);
6038                             } else {
6039                                 imm64 = imm;
6040                             }
6041                             tcg_gen_andi_i64(tcg_ctx, tcg_ctx->cpu_V0, tcg_ctx->cpu_V0, ~imm64);
6042                         }
6043                     }
6044                     neon_store_reg64(tcg_ctx, tcg_ctx->cpu_V0, rd + pass);
6045                 }
6046             } else if (op >= 14) {
6047                 /* VCVT fixed-point.  */
6048                 if (!(insn & (1 << 21)) || (q && ((rd | rm) & 1))) {
6049                     return 1;
6050                 }
6051                 /* We have already masked out the must-be-1 top bit of imm6,
6052                  * hence this 32-shift where the ARM ARM has 64-imm6.
6053                  */
6054                 shift = 32 - shift;
6055                 for (pass = 0; pass < (q ? 4 : 2); pass++) {
6056                     tcg_gen_ld_f32(tcg_ctx, tcg_ctx->cpu_F0s, tcg_ctx->cpu_env, neon_reg_offset(rm, pass));
6057                     if (!(op & 1)) {
6058                         if (u)
6059                             gen_vfp_ulto(s, 0, shift, 1);
6060                         else
6061                             gen_vfp_slto(s, 0, shift, 1);
6062                     } else {
6063                         if (u)
6064                             gen_vfp_toul(s, 0, shift, 1);
6065                         else
6066                             gen_vfp_tosl(s, 0, shift, 1);
6067                     }
6068                     tcg_gen_st_f32(tcg_ctx, tcg_ctx->cpu_F0s, tcg_ctx->cpu_env, neon_reg_offset(rd, pass));
6069                 }
6070             } else {
6071                 return 1;
6072             }
6073         } else { /* (insn & 0x00380080) == 0 */
6074             int invert;
6075             if (q && (rd & 1)) {
6076                 return 1;
6077             }
6078 
6079             op = (insn >> 8) & 0xf;
6080             /* One register and immediate.  */
6081             imm = (u << 7) | ((insn >> 12) & 0x70) | (insn & 0xf);
6082             invert = (insn & (1 << 5)) != 0;
6083             /* Note that op = 2,3,4,5,6,7,10,11,12,13 imm=0 is UNPREDICTABLE.
6084              * We choose to not special-case this and will behave as if a
6085              * valid constant encoding of 0 had been given.
6086              */
6087             switch (op) {
6088             case 0: case 1:
6089                 /* no-op */
6090                 break;
6091             case 2: case 3:
6092                 imm <<= 8;
6093                 break;
6094             case 4: case 5:
6095                 imm <<= 16;
6096                 break;
6097             case 6: case 7:
6098                 imm <<= 24;
6099                 break;
6100             case 8: case 9:
6101                 imm |= imm << 16;
6102                 break;
6103             case 10: case 11:
6104                 imm = (imm << 8) | (imm << 24);
6105                 break;
6106             case 12:
6107                 imm = (imm << 8) | 0xff;
6108                 break;
6109             case 13:
6110                 imm = (imm << 16) | 0xffff;
6111                 break;
6112             case 14:
6113                 imm |= (imm << 8) | (imm << 16) | (imm << 24);
6114                 if (invert)
6115                     imm = ~imm;
6116                 break;
6117             case 15:
6118                 if (invert) {
6119                     return 1;
6120                 }
6121                 imm = ((imm & 0x80) << 24) | ((imm & 0x3f) << 19)
6122                       | ((imm & 0x40) ? (0x1f << 25) : (1 << 30));
6123                 break;
6124             }
6125             if (invert)
6126                 imm = ~imm;
6127 
6128             for (pass = 0; pass < (q ? 4 : 2); pass++) {
6129                 if (op & 1 && op < 12) {
6130                     tmp = neon_load_reg(tcg_ctx, rd, pass);
6131                     if (invert) {
6132                         /* The immediate value has already been inverted, so
6133                            BIC becomes AND.  */
6134                         tcg_gen_andi_i32(tcg_ctx, tmp, tmp, imm);
6135                     } else {
6136                         tcg_gen_ori_i32(tcg_ctx, tmp, tmp, imm);
6137                     }
6138                 } else {
6139                     /* VMOV, VMVN.  */
6140                     tmp = tcg_temp_new_i32(tcg_ctx);
6141                     if (op == 14 && invert) {
6142                         int n;
6143                         uint32_t val;
6144                         val = 0;
6145                         for (n = 0; n < 4; n++) {
6146                             if (imm & (1 << (n + (pass & 1) * 4)))
6147                                 val |= 0xffU << (n * 8);
6148                         }
6149                         tcg_gen_movi_i32(tcg_ctx, tmp, val);
6150                     } else {
6151                         tcg_gen_movi_i32(tcg_ctx, tmp, imm);
6152                     }
6153                 }
6154                 neon_store_reg(tcg_ctx, rd, pass, tmp);
6155             }
6156         }
6157     } else { /* (insn & 0x00800010 == 0x00800000) */
6158         if (size != 3) {
6159             op = (insn >> 8) & 0xf;
6160             if ((insn & (1 << 6)) == 0) {
6161                 /* Three registers of different lengths.  */
6162                 int src1_wide;
6163                 int src2_wide;
6164                 int prewiden;
6165                 /* undefreq: bit 0 : UNDEF if size == 0
6166                  *           bit 1 : UNDEF if size == 1
6167                  *           bit 2 : UNDEF if size == 2
6168                  *           bit 3 : UNDEF if U == 1
6169                  * Note that [2:0] set implies 'always UNDEF'
6170                  */
6171                 int undefreq;
6172                 /* prewiden, src1_wide, src2_wide, undefreq */
6173                 static const int neon_3reg_wide[16][4] = {
6174                     {1, 0, 0, 0}, /* VADDL */
6175                     {1, 1, 0, 0}, /* VADDW */
6176                     {1, 0, 0, 0}, /* VSUBL */
6177                     {1, 1, 0, 0}, /* VSUBW */
6178                     {0, 1, 1, 0}, /* VADDHN */
6179                     {0, 0, 0, 0}, /* VABAL */
6180                     {0, 1, 1, 0}, /* VSUBHN */
6181                     {0, 0, 0, 0}, /* VABDL */
6182                     {0, 0, 0, 0}, /* VMLAL */
6183                     {0, 0, 0, 9}, /* VQDMLAL */
6184                     {0, 0, 0, 0}, /* VMLSL */
6185                     {0, 0, 0, 9}, /* VQDMLSL */
6186                     {0, 0, 0, 0}, /* Integer VMULL */
6187                     {0, 0, 0, 1}, /* VQDMULL */
6188                     {0, 0, 0, 0xa}, /* Polynomial VMULL */
6189                     {0, 0, 0, 7}, /* Reserved: always UNDEF */
6190                 };
6191 
6192                 prewiden = neon_3reg_wide[op][0];
6193                 src1_wide = neon_3reg_wide[op][1];
6194                 src2_wide = neon_3reg_wide[op][2];
6195                 undefreq = neon_3reg_wide[op][3];
6196 
6197                 if ((undefreq & (1 << size)) ||
6198                     ((undefreq & 8) && u)) {
6199                     return 1;
6200                 }
6201                 if ((src1_wide && (rn & 1)) ||
6202                     (src2_wide && (rm & 1)) ||
6203                     (!src2_wide && (rd & 1))) {
6204                     return 1;
6205                 }
6206 
6207                 /* Handle VMULL.P64 (Polynomial 64x64 to 128 bit multiply)
6208                  * outside the loop below as it only performs a single pass.
6209                  */
6210                 if (op == 14 && size == 2) {
6211                     TCGv_i64 tcg_rn, tcg_rm, tcg_rd;
6212 
6213                     if (!arm_dc_feature(s, ARM_FEATURE_V8_PMULL)) {
6214                         return 1;
6215                     }
6216                     tcg_rn = tcg_temp_new_i64(tcg_ctx);
6217                     tcg_rm = tcg_temp_new_i64(tcg_ctx);
6218                     tcg_rd = tcg_temp_new_i64(tcg_ctx);
6219                     neon_load_reg64(tcg_ctx, tcg_rn, rn);
6220                     neon_load_reg64(tcg_ctx, tcg_rm, rm);
6221                     gen_helper_neon_pmull_64_lo(tcg_ctx, tcg_rd, tcg_rn, tcg_rm);
6222                     neon_store_reg64(tcg_ctx, tcg_rd, rd);
6223                     gen_helper_neon_pmull_64_hi(tcg_ctx, tcg_rd, tcg_rn, tcg_rm);
6224                     neon_store_reg64(tcg_ctx, tcg_rd, rd + 1);
6225                     tcg_temp_free_i64(tcg_ctx, tcg_rn);
6226                     tcg_temp_free_i64(tcg_ctx, tcg_rm);
6227                     tcg_temp_free_i64(tcg_ctx, tcg_rd);
6228                     return 0;
6229                 }
6230 
6231                 /* Avoid overlapping operands.  Wide source operands are
6232                    always aligned so will never overlap with wide
6233                    destinations in problematic ways.  */
6234                 if (rd == rm && !src2_wide) {
6235                     tmp = neon_load_reg(tcg_ctx, rm, 1);
6236                     neon_store_scratch(tcg_ctx, 2, tmp);
6237                 } else if (rd == rn && !src1_wide) {
6238                     tmp = neon_load_reg(tcg_ctx, rn, 1);
6239                     neon_store_scratch(tcg_ctx, 2, tmp);
6240                 }
6241                 TCGV_UNUSED_I32(tmp3);
6242                 for (pass = 0; pass < 2; pass++) {
6243                     if (src1_wide) {
6244                         neon_load_reg64(tcg_ctx, tcg_ctx->cpu_V0, rn + pass);
6245                         TCGV_UNUSED_I32(tmp);
6246                     } else {
6247                         if (pass == 1 && rd == rn) {
6248                             tmp = neon_load_scratch(tcg_ctx, 2);
6249                         } else {
6250                             tmp = neon_load_reg(tcg_ctx, rn, pass);
6251                         }
6252                         if (prewiden) {
6253                             gen_neon_widen(s, tcg_ctx->cpu_V0, tmp, size, u);
6254                         }
6255                     }
6256                     if (src2_wide) {
6257                         neon_load_reg64(tcg_ctx, tcg_ctx->cpu_V1, rm + pass);
6258                         TCGV_UNUSED_I32(tmp2);
6259                     } else {
6260                         if (pass == 1 && rd == rm) {
6261                             tmp2 = neon_load_scratch(tcg_ctx, 2);
6262                         } else {
6263                             tmp2 = neon_load_reg(tcg_ctx, rm, pass);
6264                         }
6265                         if (prewiden) {
6266                             gen_neon_widen(s, tcg_ctx->cpu_V1, tmp2, size, u);
6267                         }
6268                     }
6269                     switch (op) {
6270                     case 0: case 1: case 4: /* VADDL, VADDW, VADDHN, VRADDHN */
6271                         gen_neon_addl(s, size);
6272                         break;
6273                     case 2: case 3: case 6: /* VSUBL, VSUBW, VSUBHN, VRSUBHN */
6274                         gen_neon_subl(s, size);
6275                         break;
6276                     case 5: case 7: /* VABAL, VABDL */
6277                         switch ((size << 1) | u) {
6278                         case 0:
6279                             gen_helper_neon_abdl_s16(tcg_ctx, tcg_ctx->cpu_V0, tmp, tmp2);
6280                             break;
6281                         case 1:
6282                             gen_helper_neon_abdl_u16(tcg_ctx, tcg_ctx->cpu_V0, tmp, tmp2);
6283                             break;
6284                         case 2:
6285                             gen_helper_neon_abdl_s32(tcg_ctx, tcg_ctx->cpu_V0, tmp, tmp2);
6286                             break;
6287                         case 3:
6288                             gen_helper_neon_abdl_u32(tcg_ctx, tcg_ctx->cpu_V0, tmp, tmp2);
6289                             break;
6290                         case 4:
6291                             gen_helper_neon_abdl_s64(tcg_ctx, tcg_ctx->cpu_V0, tmp, tmp2);
6292                             break;
6293                         case 5:
6294                             gen_helper_neon_abdl_u64(tcg_ctx, tcg_ctx->cpu_V0, tmp, tmp2);
6295                             break;
6296                         default: abort();
6297                         }
6298                         tcg_temp_free_i32(tcg_ctx, tmp2);
6299                         tcg_temp_free_i32(tcg_ctx, tmp);
6300                         break;
6301                     case 8: case 9: case 10: case 11: case 12: case 13:
6302                         /* VMLAL, VQDMLAL, VMLSL, VQDMLSL, VMULL, VQDMULL */
6303                         gen_neon_mull(s, tcg_ctx->cpu_V0, tmp, tmp2, size, u);
6304                         break;
6305                     case 14: /* Polynomial VMULL */
6306                         gen_helper_neon_mull_p8(tcg_ctx, tcg_ctx->cpu_V0, tmp, tmp2);
6307                         tcg_temp_free_i32(tcg_ctx, tmp2);
6308                         tcg_temp_free_i32(tcg_ctx, tmp);
6309                         break;
6310                     default: /* 15 is RESERVED: caught earlier  */
6311                         abort();
6312                     }
6313                     if (op == 13) {
6314                         /* VQDMULL */
6315                         gen_neon_addl_saturate(s, tcg_ctx->cpu_V0, tcg_ctx->cpu_V0, size);
6316                         neon_store_reg64(tcg_ctx, tcg_ctx->cpu_V0, rd + pass);
6317                     } else if (op == 5 || (op >= 8 && op <= 11)) {
6318                         /* Accumulate.  */
6319                         neon_load_reg64(tcg_ctx, tcg_ctx->cpu_V1, rd + pass);
6320                         switch (op) {
6321                         case 10: /* VMLSL */
6322                             gen_neon_negl(s, tcg_ctx->cpu_V0, size);
6323                             /* Fall through */
6324                         case 5: case 8: /* VABAL, VMLAL */
6325                             gen_neon_addl(s, size);
6326                             break;
6327                         case 9: case 11: /* VQDMLAL, VQDMLSL */
6328                             gen_neon_addl_saturate(s, tcg_ctx->cpu_V0, tcg_ctx->cpu_V0, size);
6329                             if (op == 11) {
6330                                 gen_neon_negl(s, tcg_ctx->cpu_V0, size);
6331                             }
6332                             gen_neon_addl_saturate(s, tcg_ctx->cpu_V0, tcg_ctx->cpu_V1, size);
6333                             break;
6334                         default:
6335                             abort();
6336                         }
6337                         neon_store_reg64(tcg_ctx, tcg_ctx->cpu_V0, rd + pass);
6338                     } else if (op == 4 || op == 6) {
6339                         /* Narrowing operation.  */
6340                         tmp = tcg_temp_new_i32(tcg_ctx);
6341                         if (!u) {
6342                             switch (size) {
6343                             case 0:
6344                                 gen_helper_neon_narrow_high_u8(tcg_ctx, tmp, tcg_ctx->cpu_V0);
6345                                 break;
6346                             case 1:
6347                                 gen_helper_neon_narrow_high_u16(tcg_ctx, tmp, tcg_ctx->cpu_V0);
6348                                 break;
6349                             case 2:
6350                                 tcg_gen_shri_i64(tcg_ctx, tcg_ctx->cpu_V0, tcg_ctx->cpu_V0, 32);
6351                                 tcg_gen_trunc_i64_i32(tcg_ctx, tmp, tcg_ctx->cpu_V0);
6352                                 break;
6353                             default: abort();
6354                             }
6355                         } else {
6356                             switch (size) {
6357                             case 0:
6358                                 gen_helper_neon_narrow_round_high_u8(tcg_ctx, tmp, tcg_ctx->cpu_V0);
6359                                 break;
6360                             case 1:
6361                                 gen_helper_neon_narrow_round_high_u16(tcg_ctx, tmp, tcg_ctx->cpu_V0);
6362                                 break;
6363                             case 2:
6364                                 tcg_gen_addi_i64(tcg_ctx, tcg_ctx->cpu_V0, tcg_ctx->cpu_V0, 1u << 31);
6365                                 tcg_gen_shri_i64(tcg_ctx, tcg_ctx->cpu_V0, tcg_ctx->cpu_V0, 32);
6366                                 tcg_gen_trunc_i64_i32(tcg_ctx, tmp, tcg_ctx->cpu_V0);
6367                                 break;
6368                             default: abort();
6369                             }
6370                         }
6371                         if (pass == 0) {
6372                             tmp3 = tmp;
6373                         } else {
6374                             neon_store_reg(tcg_ctx, rd, 0, tmp3);
6375                             neon_store_reg(tcg_ctx, rd, 1, tmp);
6376                         }
6377                     } else {
6378                         /* Write back the result.  */
6379                         neon_store_reg64(tcg_ctx, tcg_ctx->cpu_V0, rd + pass);
6380                     }
6381                 }
6382             } else {
6383                 /* Two registers and a scalar. NB that for ops of this form
6384                  * the ARM ARM labels bit 24 as Q, but it is in our variable
6385                  * 'u', not 'q'.
6386                  */
6387                 if (size == 0) {
6388                     return 1;
6389                 }
6390                 switch (op) {
6391                 case 1: /* Float VMLA scalar */
6392                 case 5: /* Floating point VMLS scalar */
6393                 case 9: /* Floating point VMUL scalar */
6394                     if (size == 1) {
6395                         return 1;
6396                     }
6397                     /* fall through */
6398                 case 0: /* Integer VMLA scalar */
6399                 case 4: /* Integer VMLS scalar */
6400                 case 8: /* Integer VMUL scalar */
6401                 case 12: /* VQDMULH scalar */
6402                 case 13: /* VQRDMULH scalar */
6403                     if (u && ((rd | rn) & 1)) {
6404                         return 1;
6405                     }
6406                     tmp = neon_get_scalar(s, size, rm);
6407                     neon_store_scratch(tcg_ctx, 0, tmp);
6408                     for (pass = 0; pass < (u ? 4 : 2); pass++) {
6409                         tmp = neon_load_scratch(tcg_ctx, 0);
6410                         tmp2 = neon_load_reg(tcg_ctx, rn, pass);
6411                         if (op == 12) {
6412                             if (size == 1) {
6413                                 gen_helper_neon_qdmulh_s16(tcg_ctx, tmp, tcg_ctx->cpu_env, tmp, tmp2);
6414                             } else {
6415                                 gen_helper_neon_qdmulh_s32(tcg_ctx, tmp, tcg_ctx->cpu_env, tmp, tmp2);
6416                             }
6417                         } else if (op == 13) {
6418                             if (size == 1) {
6419                                 gen_helper_neon_qrdmulh_s16(tcg_ctx, tmp, tcg_ctx->cpu_env, tmp, tmp2);
6420                             } else {
6421                                 gen_helper_neon_qrdmulh_s32(tcg_ctx, tmp, tcg_ctx->cpu_env, tmp, tmp2);
6422                             }
6423                         } else if (op & 1) {
6424                             TCGv_ptr fpstatus = get_fpstatus_ptr(s, 1);
6425                             gen_helper_vfp_muls(tcg_ctx, tmp, tmp, tmp2, fpstatus);
6426                             tcg_temp_free_ptr(tcg_ctx, fpstatus);
6427                         } else {
6428                             switch (size) {
6429                             case 0: gen_helper_neon_mul_u8(tcg_ctx, tmp, tmp, tmp2); break;
6430                             case 1: gen_helper_neon_mul_u16(tcg_ctx, tmp, tmp, tmp2); break;
6431                             case 2: tcg_gen_mul_i32(tcg_ctx, tmp, tmp, tmp2); break;
6432                             default: abort();
6433                             }
6434                         }
6435                         tcg_temp_free_i32(tcg_ctx, tmp2);
6436                         if (op < 8) {
6437                             /* Accumulate.  */
6438                             tmp2 = neon_load_reg(tcg_ctx, rd, pass);
6439                             switch (op) {
6440                             case 0:
6441                                 gen_neon_add(s, size, tmp, tmp2);
6442                                 break;
6443                             case 1:
6444                             {
6445                                 TCGv_ptr fpstatus = get_fpstatus_ptr(s, 1);
6446                                 gen_helper_vfp_adds(tcg_ctx, tmp, tmp, tmp2, fpstatus);
6447                                 tcg_temp_free_ptr(tcg_ctx, fpstatus);
6448                                 break;
6449                             }
6450                             case 4:
6451                                 gen_neon_rsb(s, size, tmp, tmp2);
6452                                 break;
6453                             case 5:
6454                             {
6455                                 TCGv_ptr fpstatus = get_fpstatus_ptr(s, 1);
6456                                 gen_helper_vfp_subs(tcg_ctx, tmp, tmp2, tmp, fpstatus);
6457                                 tcg_temp_free_ptr(tcg_ctx, fpstatus);
6458                                 break;
6459                             }
6460                             default:
6461                                 abort();
6462                             }
6463                             tcg_temp_free_i32(tcg_ctx, tmp2);
6464                         }
6465                         neon_store_reg(tcg_ctx, rd, pass, tmp);
6466                     }
6467                     break;
6468                 case 3: /* VQDMLAL scalar */
6469                 case 7: /* VQDMLSL scalar */
6470                 case 11: /* VQDMULL scalar */
6471                     if (u == 1) {
6472                         return 1;
6473                     }
6474                     /* fall through */
6475                 case 2: /* VMLAL sclar */
6476                 case 6: /* VMLSL scalar */
6477                 case 10: /* VMULL scalar */
6478                     if (rd & 1) {
6479                         return 1;
6480                     }
6481                     tmp2 = neon_get_scalar(s, size, rm);
6482                     /* We need a copy of tmp2 because gen_neon_mull
6483                      * deletes it during pass 0.  */
6484                     tmp4 = tcg_temp_new_i32(tcg_ctx);
6485                     tcg_gen_mov_i32(tcg_ctx, tmp4, tmp2);
6486                     tmp3 = neon_load_reg(tcg_ctx, rn, 1);
6487 
6488                     for (pass = 0; pass < 2; pass++) {
6489                         if (pass == 0) {
6490                             tmp = neon_load_reg(tcg_ctx, rn, 0);
6491                         } else {
6492                             tmp = tmp3;
6493                             tmp2 = tmp4;
6494                         }
6495                         gen_neon_mull(s, tcg_ctx->cpu_V0, tmp, tmp2, size, u);
6496                         if (op != 11) {
6497                             neon_load_reg64(tcg_ctx, tcg_ctx->cpu_V1, rd + pass);
6498                         }
6499                         switch (op) {
6500                         case 6:
6501                             gen_neon_negl(s, tcg_ctx->cpu_V0, size);
6502                             /* Fall through */
6503                         case 2:
6504                             gen_neon_addl(s, size);
6505                             break;
6506                         case 3: case 7:
6507                             gen_neon_addl_saturate(s, tcg_ctx->cpu_V0, tcg_ctx->cpu_V0, size);
6508                             if (op == 7) {
6509                                 gen_neon_negl(s, tcg_ctx->cpu_V0, size);
6510                             }
6511                             gen_neon_addl_saturate(s, tcg_ctx->cpu_V0, tcg_ctx->cpu_V1, size);
6512                             break;
6513                         case 10:
6514                             /* no-op */
6515                             break;
6516                         case 11:
6517                             gen_neon_addl_saturate(s, tcg_ctx->cpu_V0, tcg_ctx->cpu_V0, size);
6518                             break;
6519                         default:
6520                             abort();
6521                         }
6522                         neon_store_reg64(tcg_ctx, tcg_ctx->cpu_V0, rd + pass);
6523                     }
6524 
6525 
6526                     break;
6527                 default: /* 14 and 15 are RESERVED */
6528                     return 1;
6529                 }
6530             }
6531         } else { /* size == 3 */
6532             if (!u) {
6533                 /* Extract.  */
6534                 imm = (insn >> 8) & 0xf;
6535 
6536                 if (imm > 7 && !q)
6537                     return 1;
6538 
6539                 if (q && ((rd | rn | rm) & 1)) {
6540                     return 1;
6541                 }
6542 
6543                 if (imm == 0) {
6544                     neon_load_reg64(tcg_ctx, tcg_ctx->cpu_V0, rn);
6545                     if (q) {
6546                         neon_load_reg64(tcg_ctx, tcg_ctx->cpu_V1, rn + 1);
6547                     }
6548                 } else if (imm == 8) {
6549                     neon_load_reg64(tcg_ctx, tcg_ctx->cpu_V0, rn + 1);
6550                     if (q) {
6551                         neon_load_reg64(tcg_ctx, tcg_ctx->cpu_V1, rm);
6552                     }
6553                 } else if (q) {
6554                     tmp64 = tcg_temp_new_i64(tcg_ctx);
6555                     if (imm < 8) {
6556                         neon_load_reg64(tcg_ctx, tcg_ctx->cpu_V0, rn);
6557                         neon_load_reg64(tcg_ctx, tmp64, rn + 1);
6558                     } else {
6559                         neon_load_reg64(tcg_ctx, tcg_ctx->cpu_V0, rn + 1);
6560                         neon_load_reg64(tcg_ctx, tmp64, rm);
6561                     }
6562                     tcg_gen_shri_i64(tcg_ctx, tcg_ctx->cpu_V0, tcg_ctx->cpu_V0, (imm & 7) * 8);
6563                     tcg_gen_shli_i64(tcg_ctx, tcg_ctx->cpu_V1, tmp64, 64 - ((imm & 7) * 8));
6564                     tcg_gen_or_i64(tcg_ctx, tcg_ctx->cpu_V0, tcg_ctx->cpu_V0, tcg_ctx->cpu_V1);
6565                     if (imm < 8) {
6566                         neon_load_reg64(tcg_ctx, tcg_ctx->cpu_V1, rm);
6567                     } else {
6568                         neon_load_reg64(tcg_ctx, tcg_ctx->cpu_V1, rm + 1);
6569                         imm -= 8;
6570                     }
6571                     tcg_gen_shli_i64(tcg_ctx, tcg_ctx->cpu_V1, tcg_ctx->cpu_V1, 64 - (imm * 8));
6572                     tcg_gen_shri_i64(tcg_ctx, tmp64, tmp64, imm * 8);
6573                     tcg_gen_or_i64(tcg_ctx, tcg_ctx->cpu_V1, tcg_ctx->cpu_V1, tmp64);
6574                     tcg_temp_free_i64(tcg_ctx, tmp64);
6575                 } else {
6576                     /* BUGFIX */
6577                     neon_load_reg64(tcg_ctx, tcg_ctx->cpu_V0, rn);
6578                     tcg_gen_shri_i64(tcg_ctx, tcg_ctx->cpu_V0, tcg_ctx->cpu_V0, imm * 8);
6579                     neon_load_reg64(tcg_ctx, tcg_ctx->cpu_V1, rm);
6580                     tcg_gen_shli_i64(tcg_ctx, tcg_ctx->cpu_V1, tcg_ctx->cpu_V1, 64 - (imm * 8));
6581                     tcg_gen_or_i64(tcg_ctx, tcg_ctx->cpu_V0, tcg_ctx->cpu_V0, tcg_ctx->cpu_V1);
6582                 }
6583                 neon_store_reg64(tcg_ctx, tcg_ctx->cpu_V0, rd);
6584                 if (q) {
6585                     neon_store_reg64(tcg_ctx, tcg_ctx->cpu_V1, rd + 1);
6586                 }
6587             } else if ((insn & (1 << 11)) == 0) {
6588                 /* Two register misc.  */
6589                 op = ((insn >> 12) & 0x30) | ((insn >> 7) & 0xf);
6590                 size = (insn >> 18) & 3;
6591                 /* UNDEF for unknown op values and bad op-size combinations */
6592                 if ((neon_2rm_sizes[op] & (1 << size)) == 0) {
6593                     return 1;
6594                 }
6595                 if ((op != NEON_2RM_VMOVN && op != NEON_2RM_VQMOVN) &&
6596                     q && ((rm | rd) & 1)) {
6597                     return 1;
6598                 }
6599                 switch (op) {
6600                 case NEON_2RM_VREV64:
6601                     for (pass = 0; pass < (q ? 2 : 1); pass++) {
6602                         tmp = neon_load_reg(tcg_ctx, rm, pass * 2);
6603                         tmp2 = neon_load_reg(tcg_ctx, rm, pass * 2 + 1);
6604                         switch (size) {
6605                         case 0: tcg_gen_bswap32_i32(tcg_ctx, tmp, tmp); break;
6606                         case 1: gen_swap_half(s, tmp); break;
6607                         case 2: /* no-op */ break;
6608                         default: abort();
6609                         }
6610                         neon_store_reg(tcg_ctx, rd, pass * 2 + 1, tmp);
6611                         if (size == 2) {
6612                             neon_store_reg(tcg_ctx, rd, pass * 2, tmp2);
6613                         } else {
6614                             switch (size) {
6615                             case 0: tcg_gen_bswap32_i32(tcg_ctx, tmp2, tmp2); break;
6616                             case 1: gen_swap_half(s, tmp2); break;
6617                             default: abort();
6618                             }
6619                             neon_store_reg(tcg_ctx, rd, pass * 2, tmp2);
6620                         }
6621                     }
6622                     break;
6623                 case NEON_2RM_VPADDL: case NEON_2RM_VPADDL_U:
6624                 case NEON_2RM_VPADAL: case NEON_2RM_VPADAL_U:
6625                     for (pass = 0; pass < q + 1; pass++) {
6626                         tmp = neon_load_reg(tcg_ctx, rm, pass * 2);
6627                         gen_neon_widen(s, tcg_ctx->cpu_V0, tmp, size, op & 1);
6628                         tmp = neon_load_reg(tcg_ctx, rm, pass * 2 + 1);
6629                         gen_neon_widen(s, tcg_ctx->cpu_V1, tmp, size, op & 1);
6630                         switch (size) {
6631                         case 0: gen_helper_neon_paddl_u16(tcg_ctx, CPU_V001); break;
6632                         case 1: gen_helper_neon_paddl_u32(tcg_ctx, CPU_V001); break;
6633                         case 2: tcg_gen_add_i64(tcg_ctx, CPU_V001); break;
6634                         default: abort();
6635                         }
6636                         if (op >= NEON_2RM_VPADAL) {
6637                             /* Accumulate.  */
6638                             neon_load_reg64(tcg_ctx, tcg_ctx->cpu_V1, rd + pass);
6639                             gen_neon_addl(s, size);
6640                         }
6641                         neon_store_reg64(tcg_ctx, tcg_ctx->cpu_V0, rd + pass);
6642                     }
6643                     break;
6644                 case NEON_2RM_VTRN:
6645                     if (size == 2) {
6646                         int n;
6647                         for (n = 0; n < (q ? 4 : 2); n += 2) {
6648                             tmp = neon_load_reg(tcg_ctx, rm, n);
6649                             tmp2 = neon_load_reg(tcg_ctx, rd, n + 1);
6650                             neon_store_reg(tcg_ctx, rm, n, tmp2);
6651                             neon_store_reg(tcg_ctx, rd, n + 1, tmp);
6652                         }
6653                     } else {
6654                         goto elementwise;
6655                     }
6656                     break;
6657                 case NEON_2RM_VUZP:
6658                     if (gen_neon_unzip(tcg_ctx, rd, rm, size, q)) {
6659                         return 1;
6660                     }
6661                     break;
6662                 case NEON_2RM_VZIP:
6663                     if (gen_neon_zip(tcg_ctx, rd, rm, size, q)) {
6664                         return 1;
6665                     }
6666                     break;
6667                 case NEON_2RM_VMOVN: case NEON_2RM_VQMOVN:
6668                     /* also VQMOVUN; op field and mnemonics don't line up */
6669                     if (rm & 1) {
6670                         return 1;
6671                     }
6672                     TCGV_UNUSED_I32(tmp2);
6673                     for (pass = 0; pass < 2; pass++) {
6674                         neon_load_reg64(tcg_ctx, tcg_ctx->cpu_V0, rm + pass);
6675                         tmp = tcg_temp_new_i32(tcg_ctx);
6676                         gen_neon_narrow_op(s, op == NEON_2RM_VMOVN, q, size,
6677                                            tmp, tcg_ctx->cpu_V0);
6678                         if (pass == 0) {
6679                             tmp2 = tmp;
6680                         } else {
6681                             neon_store_reg(tcg_ctx, rd, 0, tmp2);
6682                             neon_store_reg(tcg_ctx, rd, 1, tmp);
6683                         }
6684                     }
6685                     break;
6686                 case NEON_2RM_VSHLL:
6687                     if (q || (rd & 1)) {
6688                         return 1;
6689                     }
6690                     tmp = neon_load_reg(tcg_ctx, rm, 0);
6691                     tmp2 = neon_load_reg(tcg_ctx, rm, 1);
6692                     for (pass = 0; pass < 2; pass++) {
6693                         if (pass == 1)
6694                             tmp = tmp2;
6695                         gen_neon_widen(s, tcg_ctx->cpu_V0, tmp, size, 1);
6696                         tcg_gen_shli_i64(tcg_ctx, tcg_ctx->cpu_V0, tcg_ctx->cpu_V0, 8 << size);
6697                         neon_store_reg64(tcg_ctx, tcg_ctx->cpu_V0, rd + pass);
6698                     }
6699                     break;
6700                 case NEON_2RM_VCVT_F16_F32:
6701                     if (!arm_dc_feature(s, ARM_FEATURE_VFP_FP16) ||
6702                         q || (rm & 1)) {
6703                         return 1;
6704                     }
6705                     tmp = tcg_temp_new_i32(tcg_ctx);
6706                     tmp2 = tcg_temp_new_i32(tcg_ctx);
6707                     tcg_gen_ld_f32(tcg_ctx, tcg_ctx->cpu_F0s, tcg_ctx->cpu_env, neon_reg_offset(rm, 0));
6708                     gen_helper_neon_fcvt_f32_to_f16(tcg_ctx, tmp, tcg_ctx->cpu_F0s, tcg_ctx->cpu_env);
6709                     tcg_gen_ld_f32(tcg_ctx, tcg_ctx->cpu_F0s, tcg_ctx->cpu_env, neon_reg_offset(rm, 1));
6710                     gen_helper_neon_fcvt_f32_to_f16(tcg_ctx, tmp2, tcg_ctx->cpu_F0s, tcg_ctx->cpu_env);
6711                     tcg_gen_shli_i32(tcg_ctx, tmp2, tmp2, 16);
6712                     tcg_gen_or_i32(tcg_ctx, tmp2, tmp2, tmp);
6713                     tcg_gen_ld_f32(tcg_ctx, tcg_ctx->cpu_F0s, tcg_ctx->cpu_env, neon_reg_offset(rm, 2));
6714                     gen_helper_neon_fcvt_f32_to_f16(tcg_ctx, tmp, tcg_ctx->cpu_F0s, tcg_ctx->cpu_env);
6715                     tcg_gen_ld_f32(tcg_ctx, tcg_ctx->cpu_F0s, tcg_ctx->cpu_env, neon_reg_offset(rm, 3));
6716                     neon_store_reg(tcg_ctx, rd, 0, tmp2);
6717                     tmp2 = tcg_temp_new_i32(tcg_ctx);
6718                     gen_helper_neon_fcvt_f32_to_f16(tcg_ctx, tmp2, tcg_ctx->cpu_F0s, tcg_ctx->cpu_env);
6719                     tcg_gen_shli_i32(tcg_ctx, tmp2, tmp2, 16);
6720                     tcg_gen_or_i32(tcg_ctx, tmp2, tmp2, tmp);
6721                     neon_store_reg(tcg_ctx, rd, 1, tmp2);
6722                     tcg_temp_free_i32(tcg_ctx, tmp);
6723                     break;
6724                 case NEON_2RM_VCVT_F32_F16:
6725                     if (!arm_dc_feature(s, ARM_FEATURE_VFP_FP16) ||
6726                         q || (rd & 1)) {
6727                         return 1;
6728                     }
6729                     tmp3 = tcg_temp_new_i32(tcg_ctx);
6730                     tmp = neon_load_reg(tcg_ctx, rm, 0);
6731                     tmp2 = neon_load_reg(tcg_ctx, rm, 1);
6732                     tcg_gen_ext16u_i32(tcg_ctx, tmp3, tmp);
6733                     gen_helper_neon_fcvt_f16_to_f32(tcg_ctx, tcg_ctx->cpu_F0s, tmp3, tcg_ctx->cpu_env);
6734                     tcg_gen_st_f32(tcg_ctx, tcg_ctx->cpu_F0s, tcg_ctx->cpu_env, neon_reg_offset(rd, 0));
6735                     tcg_gen_shri_i32(tcg_ctx, tmp3, tmp, 16);
6736                     gen_helper_neon_fcvt_f16_to_f32(tcg_ctx, tcg_ctx->cpu_F0s, tmp3, tcg_ctx->cpu_env);
6737                     tcg_gen_st_f32(tcg_ctx, tcg_ctx->cpu_F0s, tcg_ctx->cpu_env, neon_reg_offset(rd, 1));
6738                     tcg_temp_free_i32(tcg_ctx, tmp);
6739                     tcg_gen_ext16u_i32(tcg_ctx, tmp3, tmp2);
6740                     gen_helper_neon_fcvt_f16_to_f32(tcg_ctx, tcg_ctx->cpu_F0s, tmp3, tcg_ctx->cpu_env);
6741                     tcg_gen_st_f32(tcg_ctx, tcg_ctx->cpu_F0s, tcg_ctx->cpu_env, neon_reg_offset(rd, 2));
6742                     tcg_gen_shri_i32(tcg_ctx, tmp3, tmp2, 16);
6743                     gen_helper_neon_fcvt_f16_to_f32(tcg_ctx, tcg_ctx->cpu_F0s, tmp3, tcg_ctx->cpu_env);
6744                     tcg_gen_st_f32(tcg_ctx, tcg_ctx->cpu_F0s, tcg_ctx->cpu_env, neon_reg_offset(rd, 3));
6745                     tcg_temp_free_i32(tcg_ctx, tmp2);
6746                     tcg_temp_free_i32(tcg_ctx, tmp3);
6747                     break;
6748                 case NEON_2RM_AESE: case NEON_2RM_AESMC:
6749                     if (!arm_dc_feature(s, ARM_FEATURE_V8_AES)
6750                         || ((rm | rd) & 1)) {
6751                         return 1;
6752                     }
6753                     tmp = tcg_const_i32(tcg_ctx, rd);
6754                     tmp2 = tcg_const_i32(tcg_ctx, rm);
6755 
6756                      /* Bit 6 is the lowest opcode bit; it distinguishes between
6757                       * encryption (AESE/AESMC) and decryption (AESD/AESIMC)
6758                       */
6759                     tmp3 = tcg_const_i32(tcg_ctx, extract32(insn, 6, 1));
6760 
6761                     if (op == NEON_2RM_AESE) {
6762                         gen_helper_crypto_aese(tcg_ctx, tcg_ctx->cpu_env, tmp, tmp2, tmp3);
6763                     } else {
6764                         gen_helper_crypto_aesmc(tcg_ctx, tcg_ctx->cpu_env, tmp, tmp2, tmp3);
6765                     }
6766                     tcg_temp_free_i32(tcg_ctx, tmp);
6767                     tcg_temp_free_i32(tcg_ctx, tmp2);
6768                     tcg_temp_free_i32(tcg_ctx, tmp3);
6769                     break;
6770                 case NEON_2RM_SHA1H:
6771                     if (!arm_dc_feature(s, ARM_FEATURE_V8_SHA1)
6772                         || ((rm | rd) & 1)) {
6773                         return 1;
6774                     }
6775                     tmp = tcg_const_i32(tcg_ctx, rd);
6776                     tmp2 = tcg_const_i32(tcg_ctx, rm);
6777 
6778                     gen_helper_crypto_sha1h(tcg_ctx, tcg_ctx->cpu_env, tmp, tmp2);
6779 
6780                     tcg_temp_free_i32(tcg_ctx, tmp);
6781                     tcg_temp_free_i32(tcg_ctx, tmp2);
6782                     break;
6783                 case NEON_2RM_SHA1SU1:
6784                     if ((rm | rd) & 1) {
6785                             return 1;
6786                     }
6787                     /* bit 6 (q): set -> SHA256SU0, cleared -> SHA1SU1 */
6788                     if (q) {
6789                         if (!arm_dc_feature(s, ARM_FEATURE_V8_SHA256)) {
6790                             return 1;
6791                         }
6792                     } else if (!arm_dc_feature(s, ARM_FEATURE_V8_SHA1)) {
6793                         return 1;
6794                     }
6795                     tmp = tcg_const_i32(tcg_ctx, rd);
6796                     tmp2 = tcg_const_i32(tcg_ctx, rm);
6797                     if (q) {
6798                         gen_helper_crypto_sha256su0(tcg_ctx, tcg_ctx->cpu_env, tmp, tmp2);
6799                     } else {
6800                         gen_helper_crypto_sha1su1(tcg_ctx, tcg_ctx->cpu_env, tmp, tmp2);
6801                     }
6802                     tcg_temp_free_i32(tcg_ctx, tmp);
6803                     tcg_temp_free_i32(tcg_ctx, tmp2);
6804                     break;
6805                 default:
6806                 elementwise:
6807                     for (pass = 0; pass < (q ? 4 : 2); pass++) {
6808                         if (neon_2rm_is_float_op(op)) {
6809                             tcg_gen_ld_f32(tcg_ctx, tcg_ctx->cpu_F0s, tcg_ctx->cpu_env,
6810                                            neon_reg_offset(rm, pass));
6811                             TCGV_UNUSED_I32(tmp);
6812                         } else {
6813                             tmp = neon_load_reg(tcg_ctx, rm, pass);
6814                         }
6815                         switch (op) {
6816                         case NEON_2RM_VREV32:
6817                             switch (size) {
6818                             case 0: tcg_gen_bswap32_i32(tcg_ctx, tmp, tmp); break;
6819                             case 1: gen_swap_half(s, tmp); break;
6820                             default: abort();
6821                             }
6822                             break;
6823                         case NEON_2RM_VREV16:
6824                             gen_rev16(s, tmp);
6825                             break;
6826                         case NEON_2RM_VCLS:
6827                             switch (size) {
6828                             case 0: gen_helper_neon_cls_s8(tcg_ctx, tmp, tmp); break;
6829                             case 1: gen_helper_neon_cls_s16(tcg_ctx, tmp, tmp); break;
6830                             case 2: gen_helper_neon_cls_s32(tcg_ctx, tmp, tmp); break;
6831                             default: abort();
6832                             }
6833                             break;
6834                         case NEON_2RM_VCLZ:
6835                             switch (size) {
6836                             case 0: gen_helper_neon_clz_u8(tcg_ctx, tmp, tmp); break;
6837                             case 1: gen_helper_neon_clz_u16(tcg_ctx, tmp, tmp); break;
6838                             case 2: gen_helper_clz(tcg_ctx, tmp, tmp); break;
6839                             default: abort();
6840                             }
6841                             break;
6842                         case NEON_2RM_VCNT:
6843                             gen_helper_neon_cnt_u8(tcg_ctx, tmp, tmp);
6844                             break;
6845                         case NEON_2RM_VMVN:
6846                             tcg_gen_not_i32(tcg_ctx, tmp, tmp);
6847                             break;
6848                         case NEON_2RM_VQABS:
6849                             switch (size) {
6850                             case 0:
6851                                 gen_helper_neon_qabs_s8(tcg_ctx, tmp, tcg_ctx->cpu_env, tmp);
6852                                 break;
6853                             case 1:
6854                                 gen_helper_neon_qabs_s16(tcg_ctx, tmp, tcg_ctx->cpu_env, tmp);
6855                                 break;
6856                             case 2:
6857                                 gen_helper_neon_qabs_s32(tcg_ctx, tmp, tcg_ctx->cpu_env, tmp);
6858                                 break;
6859                             default: abort();
6860                             }
6861                             break;
6862                         case NEON_2RM_VQNEG:
6863                             switch (size) {
6864                             case 0:
6865                                 gen_helper_neon_qneg_s8(tcg_ctx, tmp, tcg_ctx->cpu_env, tmp);
6866                                 break;
6867                             case 1:
6868                                 gen_helper_neon_qneg_s16(tcg_ctx, tmp, tcg_ctx->cpu_env, tmp);
6869                                 break;
6870                             case 2:
6871                                 gen_helper_neon_qneg_s32(tcg_ctx, tmp, tcg_ctx->cpu_env, tmp);
6872                                 break;
6873                             default: abort();
6874                             }
6875                             break;
6876                         case NEON_2RM_VCGT0: case NEON_2RM_VCLE0:
6877                             tmp2 = tcg_const_i32(tcg_ctx, 0);
6878                             switch(size) {
6879                             case 0: gen_helper_neon_cgt_s8(tcg_ctx, tmp, tmp, tmp2); break;
6880                             case 1: gen_helper_neon_cgt_s16(tcg_ctx, tmp, tmp, tmp2); break;
6881                             case 2: gen_helper_neon_cgt_s32(tcg_ctx, tmp, tmp, tmp2); break;
6882                             default: abort();
6883                             }
6884                             tcg_temp_free_i32(tcg_ctx, tmp2);
6885                             if (op == NEON_2RM_VCLE0) {
6886                                 tcg_gen_not_i32(tcg_ctx, tmp, tmp);
6887                             }
6888                             break;
6889                         case NEON_2RM_VCGE0: case NEON_2RM_VCLT0:
6890                             tmp2 = tcg_const_i32(tcg_ctx, 0);
6891                             switch(size) {
6892                             case 0: gen_helper_neon_cge_s8(tcg_ctx, tmp, tmp, tmp2); break;
6893                             case 1: gen_helper_neon_cge_s16(tcg_ctx, tmp, tmp, tmp2); break;
6894                             case 2: gen_helper_neon_cge_s32(tcg_ctx, tmp, tmp, tmp2); break;
6895                             default: abort();
6896                             }
6897                             tcg_temp_free_i32(tcg_ctx, tmp2);
6898                             if (op == NEON_2RM_VCLT0) {
6899                                 tcg_gen_not_i32(tcg_ctx, tmp, tmp);
6900                             }
6901                             break;
6902                         case NEON_2RM_VCEQ0:
6903                             tmp2 = tcg_const_i32(tcg_ctx, 0);
6904                             switch(size) {
6905                             case 0: gen_helper_neon_ceq_u8(tcg_ctx, tmp, tmp, tmp2); break;
6906                             case 1: gen_helper_neon_ceq_u16(tcg_ctx, tmp, tmp, tmp2); break;
6907                             case 2: gen_helper_neon_ceq_u32(tcg_ctx, tmp, tmp, tmp2); break;
6908                             default: abort();
6909                             }
6910                             tcg_temp_free_i32(tcg_ctx, tmp2);
6911                             break;
6912                         case NEON_2RM_VABS:
6913                             switch(size) {
6914                             case 0: gen_helper_neon_abs_s8(tcg_ctx, tmp, tmp); break;
6915                             case 1: gen_helper_neon_abs_s16(tcg_ctx, tmp, tmp); break;
6916                             case 2: tcg_gen_abs_i32(s, tmp, tmp); break;
6917                             default: abort();
6918                             }
6919                             break;
6920                         case NEON_2RM_VNEG:
6921                             tmp2 = tcg_const_i32(tcg_ctx, 0);
6922                             gen_neon_rsb(s, size, tmp, tmp2);
6923                             tcg_temp_free_i32(tcg_ctx, tmp2);
6924                             break;
6925                         case NEON_2RM_VCGT0_F:
6926                         {
6927                             TCGv_ptr fpstatus = get_fpstatus_ptr(s, 1);
6928                             tmp2 = tcg_const_i32(tcg_ctx, 0);
6929                             gen_helper_neon_cgt_f32(tcg_ctx, tmp, tmp, tmp2, fpstatus);
6930                             tcg_temp_free_i32(tcg_ctx, tmp2);
6931                             tcg_temp_free_ptr(tcg_ctx, fpstatus);
6932                             break;
6933                         }
6934                         case NEON_2RM_VCGE0_F:
6935                         {
6936                             TCGv_ptr fpstatus = get_fpstatus_ptr(s, 1);
6937                             tmp2 = tcg_const_i32(tcg_ctx, 0);
6938                             gen_helper_neon_cge_f32(tcg_ctx, tmp, tmp, tmp2, fpstatus);
6939                             tcg_temp_free_i32(tcg_ctx, tmp2);
6940                             tcg_temp_free_ptr(tcg_ctx, fpstatus);
6941                             break;
6942                         }
6943                         case NEON_2RM_VCEQ0_F:
6944                         {
6945                             TCGv_ptr fpstatus = get_fpstatus_ptr(s, 1);
6946                             tmp2 = tcg_const_i32(tcg_ctx, 0);
6947                             gen_helper_neon_ceq_f32(tcg_ctx, tmp, tmp, tmp2, fpstatus);
6948                             tcg_temp_free_i32(tcg_ctx, tmp2);
6949                             tcg_temp_free_ptr(tcg_ctx, fpstatus);
6950                             break;
6951                         }
6952                         case NEON_2RM_VCLE0_F:
6953                         {
6954                             TCGv_ptr fpstatus = get_fpstatus_ptr(s, 1);
6955                             tmp2 = tcg_const_i32(tcg_ctx, 0);
6956                             gen_helper_neon_cge_f32(tcg_ctx, tmp, tmp2, tmp, fpstatus);
6957                             tcg_temp_free_i32(tcg_ctx, tmp2);
6958                             tcg_temp_free_ptr(tcg_ctx, fpstatus);
6959                             break;
6960                         }
6961                         case NEON_2RM_VCLT0_F:
6962                         {
6963                             TCGv_ptr fpstatus = get_fpstatus_ptr(s, 1);
6964                             tmp2 = tcg_const_i32(tcg_ctx, 0);
6965                             gen_helper_neon_cgt_f32(tcg_ctx, tmp, tmp2, tmp, fpstatus);
6966                             tcg_temp_free_i32(tcg_ctx, tmp2);
6967                             tcg_temp_free_ptr(tcg_ctx, fpstatus);
6968                             break;
6969                         }
6970                         case NEON_2RM_VABS_F:
6971                             gen_vfp_abs(s, 0);
6972                             break;
6973                         case NEON_2RM_VNEG_F:
6974                             gen_vfp_neg(s, 0);
6975                             break;
6976                         case NEON_2RM_VSWP:
6977                             tmp2 = neon_load_reg(tcg_ctx, rd, pass);
6978                             neon_store_reg(tcg_ctx, rm, pass, tmp2);
6979                             break;
6980                         case NEON_2RM_VTRN:
6981                             tmp2 = neon_load_reg(tcg_ctx, rd, pass);
6982                             switch (size) {
6983                             case 0: gen_neon_trn_u8(tcg_ctx, tmp, tmp2); break;
6984                             case 1: gen_neon_trn_u16(tcg_ctx, tmp, tmp2); break;
6985                             default: abort();
6986                             }
6987                             neon_store_reg(tcg_ctx, rm, pass, tmp2);
6988                             break;
6989                         case NEON_2RM_VRINTN:
6990                         case NEON_2RM_VRINTA:
6991                         case NEON_2RM_VRINTM:
6992                         case NEON_2RM_VRINTP:
6993                         case NEON_2RM_VRINTZ:
6994                         {
6995                             TCGv_i32 tcg_rmode;
6996                             TCGv_ptr fpstatus = get_fpstatus_ptr(s, 1);
6997                             int rmode;
6998 
6999                             if (op == NEON_2RM_VRINTZ) {
7000                                 rmode = FPROUNDING_ZERO;
7001                             } else {
7002                                 rmode = fp_decode_rm[((op & 0x6) >> 1) ^ 1];
7003                             }
7004 
7005                             tcg_rmode = tcg_const_i32(tcg_ctx, arm_rmode_to_sf(rmode));
7006                             gen_helper_set_neon_rmode(tcg_ctx, tcg_rmode, tcg_rmode,
7007                                                       tcg_ctx->cpu_env);
7008                             gen_helper_rints(tcg_ctx, tcg_ctx->cpu_F0s, tcg_ctx->cpu_F0s, fpstatus);
7009                             gen_helper_set_neon_rmode(tcg_ctx, tcg_rmode, tcg_rmode,
7010                                                       tcg_ctx->cpu_env);
7011                             tcg_temp_free_ptr(tcg_ctx, fpstatus);
7012                             tcg_temp_free_i32(tcg_ctx, tcg_rmode);
7013                             break;
7014                         }
7015                         case NEON_2RM_VRINTX:
7016                         {
7017                             TCGv_ptr fpstatus = get_fpstatus_ptr(s, 1);
7018                             gen_helper_rints_exact(tcg_ctx, tcg_ctx->cpu_F0s, tcg_ctx->cpu_F0s, fpstatus);
7019                             tcg_temp_free_ptr(tcg_ctx, fpstatus);
7020                             break;
7021                         }
7022                         case NEON_2RM_VCVTAU:
7023                         case NEON_2RM_VCVTAS:
7024                         case NEON_2RM_VCVTNU:
7025                         case NEON_2RM_VCVTNS:
7026                         case NEON_2RM_VCVTPU:
7027                         case NEON_2RM_VCVTPS:
7028                         case NEON_2RM_VCVTMU:
7029                         case NEON_2RM_VCVTMS:
7030                         {
7031                             bool is_signed = !extract32(insn, 7, 1);
7032                             TCGv_ptr fpst = get_fpstatus_ptr(s, 1);
7033                             TCGv_i32 tcg_rmode, tcg_shift;
7034                             int rmode = fp_decode_rm[extract32(insn, 8, 2)];
7035 
7036                             tcg_shift = tcg_const_i32(tcg_ctx, 0);
7037                             tcg_rmode = tcg_const_i32(tcg_ctx, arm_rmode_to_sf(rmode));
7038                             gen_helper_set_neon_rmode(tcg_ctx, tcg_rmode, tcg_rmode,
7039                                                       tcg_ctx->cpu_env);
7040 
7041                             if (is_signed) {
7042                                 gen_helper_vfp_tosls(tcg_ctx, tcg_ctx->cpu_F0s, tcg_ctx->cpu_F0s,
7043                                                      tcg_shift, fpst);
7044                             } else {
7045                                 gen_helper_vfp_touls(tcg_ctx, tcg_ctx->cpu_F0s, tcg_ctx->cpu_F0s,
7046                                                      tcg_shift, fpst);
7047                             }
7048 
7049                             gen_helper_set_neon_rmode(tcg_ctx, tcg_rmode, tcg_rmode,
7050                                                       tcg_ctx->cpu_env);
7051                             tcg_temp_free_i32(tcg_ctx, tcg_rmode);
7052                             tcg_temp_free_i32(tcg_ctx, tcg_shift);
7053                             tcg_temp_free_ptr(tcg_ctx, fpst);
7054                             break;
7055                         }
7056                         case NEON_2RM_VRECPE:
7057                         {
7058                             TCGv_ptr fpstatus = get_fpstatus_ptr(s, 1);
7059                             gen_helper_recpe_u32(tcg_ctx, tmp, tmp, fpstatus);
7060                             tcg_temp_free_ptr(tcg_ctx, fpstatus);
7061                             break;
7062                         }
7063                         case NEON_2RM_VRSQRTE:
7064                         {
7065                             TCGv_ptr fpstatus = get_fpstatus_ptr(s, 1);
7066                             gen_helper_rsqrte_u32(tcg_ctx, tmp, tmp, fpstatus);
7067                             tcg_temp_free_ptr(tcg_ctx, fpstatus);
7068                             break;
7069                         }
7070                         case NEON_2RM_VRECPE_F:
7071                         {
7072                             TCGv_ptr fpstatus = get_fpstatus_ptr(s, 1);
7073                             gen_helper_recpe_f32(tcg_ctx, tcg_ctx->cpu_F0s, tcg_ctx->cpu_F0s, fpstatus);
7074                             tcg_temp_free_ptr(tcg_ctx, fpstatus);
7075                             break;
7076                         }
7077                         case NEON_2RM_VRSQRTE_F:
7078                         {
7079                             TCGv_ptr fpstatus = get_fpstatus_ptr(s, 1);
7080                             gen_helper_rsqrte_f32(tcg_ctx, tcg_ctx->cpu_F0s, tcg_ctx->cpu_F0s, fpstatus);
7081                             tcg_temp_free_ptr(tcg_ctx, fpstatus);
7082                             break;
7083                         }
7084                         case NEON_2RM_VCVT_FS: /* VCVT.F32.S32 */
7085                             gen_vfp_sito(s, 0, 1);
7086                             break;
7087                         case NEON_2RM_VCVT_FU: /* VCVT.F32.U32 */
7088                             gen_vfp_uito(s, 0, 1);
7089                             break;
7090                         case NEON_2RM_VCVT_SF: /* VCVT.S32.F32 */
7091                             gen_vfp_tosiz(s, 0, 1);
7092                             break;
7093                         case NEON_2RM_VCVT_UF: /* VCVT.U32.F32 */
7094                             gen_vfp_touiz(s, 0, 1);
7095                             break;
7096                         default:
7097                             /* Reserved op values were caught by the
7098                              * neon_2rm_sizes[] check earlier.
7099                              */
7100                             abort();
7101                         }
7102                         if (neon_2rm_is_float_op(op)) {
7103                             tcg_gen_st_f32(tcg_ctx, tcg_ctx->cpu_F0s, tcg_ctx->cpu_env,
7104                                            neon_reg_offset(rd, pass));
7105                         } else {
7106                             neon_store_reg(tcg_ctx, rd, pass, tmp);
7107                         }
7108                     }
7109                     break;
7110                 }
7111             } else if ((insn & (1 << 10)) == 0) {
7112                 /* VTBL, VTBX.  */
7113                 int n = ((insn >> 8) & 3) + 1;
7114                 if ((rn + n) > 32) {
7115                     /* This is UNPREDICTABLE; we choose to UNDEF to avoid the
7116                      * helper function running off the end of the register file.
7117                      */
7118                     return 1;
7119                 }
7120                 n <<= 3;
7121                 if (insn & (1 << 6)) {
7122                     tmp = neon_load_reg(tcg_ctx, rd, 0);
7123                 } else {
7124                     tmp = tcg_temp_new_i32(tcg_ctx);
7125                     tcg_gen_movi_i32(tcg_ctx, tmp, 0);
7126                 }
7127                 tmp2 = neon_load_reg(tcg_ctx, rm, 0);
7128                 tmp4 = tcg_const_i32(tcg_ctx, rn);
7129                 tmp5 = tcg_const_i32(tcg_ctx, n);
7130                 gen_helper_neon_tbl(tcg_ctx, tmp2, tcg_ctx->cpu_env, tmp2, tmp, tmp4, tmp5);
7131                 tcg_temp_free_i32(tcg_ctx, tmp);
7132                 if (insn & (1 << 6)) {
7133                     tmp = neon_load_reg(tcg_ctx, rd, 1);
7134                 } else {
7135                     tmp = tcg_temp_new_i32(tcg_ctx);
7136                     tcg_gen_movi_i32(tcg_ctx, tmp, 0);
7137                 }
7138                 tmp3 = neon_load_reg(tcg_ctx, rm, 1);
7139                 gen_helper_neon_tbl(tcg_ctx, tmp3, tcg_ctx->cpu_env, tmp3, tmp, tmp4, tmp5);
7140                 tcg_temp_free_i32(tcg_ctx, tmp5);
7141                 tcg_temp_free_i32(tcg_ctx, tmp4);
7142                 neon_store_reg(tcg_ctx, rd, 0, tmp2);
7143                 neon_store_reg(tcg_ctx, rd, 1, tmp3);
7144                 tcg_temp_free_i32(tcg_ctx, tmp);
7145             } else if ((insn & 0x380) == 0) {
7146                 /* VDUP */
7147                 if ((insn & (7 << 16)) == 0 || (q && (rd & 1))) {
7148                     return 1;
7149                 }
7150                 if (insn & (1 << 19)) {
7151                     tmp = neon_load_reg(tcg_ctx, rm, 1);
7152                 } else {
7153                     tmp = neon_load_reg(tcg_ctx, rm, 0);
7154                 }
7155                 if (insn & (1 << 16)) {
7156                     gen_neon_dup_u8(s, tmp, ((insn >> 17) & 3) * 8);
7157                 } else if (insn & (1 << 17)) {
7158                     if ((insn >> 18) & 1)
7159                         gen_neon_dup_high16(s, tmp);
7160                     else
7161                         gen_neon_dup_low16(s, tmp);
7162                 }
7163                 for (pass = 0; pass < (q ? 4 : 2); pass++) {
7164                     tmp2 = tcg_temp_new_i32(tcg_ctx);
7165                     tcg_gen_mov_i32(tcg_ctx, tmp2, tmp);
7166                     neon_store_reg(tcg_ctx, rd, pass, tmp2);
7167                 }
7168                 tcg_temp_free_i32(tcg_ctx, tmp);
7169             } else {
7170                 return 1;
7171             }
7172         }
7173     }
7174     return 0;
7175 }
7176 
disas_coproc_insn(DisasContext * s,uint32_t insn)7177 static int disas_coproc_insn(DisasContext *s, uint32_t insn)
7178 {
7179     int cpnum, is64, crn, crm, opc1, opc2, isread, rt, rt2;
7180     const ARMCPRegInfo *ri;
7181     TCGContext *tcg_ctx = s->uc->tcg_ctx;
7182 
7183     cpnum = (insn >> 8) & 0xf;
7184 
7185     /* First check for coprocessor space used for XScale/iwMMXt insns */
7186     if (arm_dc_feature(s, ARM_FEATURE_XSCALE) && (cpnum < 2)) {
7187         if (extract32(s->c15_cpar, cpnum, 1) == 0) {
7188             return 1;
7189         }
7190         if (arm_dc_feature(s, ARM_FEATURE_IWMMXT)) {
7191             return disas_iwmmxt_insn(s, insn);
7192         } else if (arm_dc_feature(s, ARM_FEATURE_XSCALE)) {
7193             return disas_dsp_insn(s, insn);
7194         }
7195         return 1;
7196     }
7197 
7198     /* Otherwise treat as a generic register access */
7199     is64 = (insn & (1 << 25)) == 0;
7200     if (!is64 && ((insn & (1 << 4)) == 0)) {
7201         /* cdp */
7202         return 1;
7203     }
7204 
7205     crm = insn & 0xf;
7206     if (is64) {
7207         crn = 0;
7208         opc1 = (insn >> 4) & 0xf;
7209         opc2 = 0;
7210         rt2 = (insn >> 16) & 0xf;
7211     } else {
7212         crn = (insn >> 16) & 0xf;
7213         opc1 = (insn >> 21) & 7;
7214         opc2 = (insn >> 5) & 7;
7215         rt2 = 0;
7216     }
7217     isread = (insn >> 20) & 1;
7218     rt = (insn >> 12) & 0xf;
7219 
7220     ri = get_arm_cp_reginfo(s->cp_regs,
7221                             ENCODE_CP_REG(cpnum, is64, crn, crm, opc1, opc2));
7222     if (ri) {
7223         /* Check access permissions */
7224         if (!cp_access_ok(s->current_el, ri, isread)) {
7225             return 1;
7226         }
7227 
7228         if (ri->accessfn ||
7229             (arm_dc_feature(s, ARM_FEATURE_XSCALE) && cpnum < 14)) {
7230             /* Emit code to perform further access permissions checks at
7231              * runtime; this may result in an exception.
7232              * Note that on XScale all cp0..c13 registers do an access check
7233              * call in order to handle c15_cpar.
7234              */
7235             TCGv_ptr tmpptr;
7236             TCGv_i32 tcg_syn;
7237             uint32_t syndrome;
7238 
7239             /* Note that since we are an implementation which takes an
7240              * exception on a trapped conditional instruction only if the
7241              * instruction passes its condition code check, we can take
7242              * advantage of the clause in the ARM ARM that allows us to set
7243              * the COND field in the instruction to 0xE in all cases.
7244              * We could fish the actual condition out of the insn (ARM)
7245              * or the condexec bits (Thumb) but it isn't necessary.
7246              */
7247             switch (cpnum) {
7248             case 14:
7249                 if (is64) {
7250                     syndrome = syn_cp14_rrt_trap(1, 0xe, opc1, crm, rt, rt2,
7251                                                  isread, s->thumb);
7252                 } else {
7253                     syndrome = syn_cp14_rt_trap(1, 0xe, opc1, opc2, crn, crm,
7254                                                 rt, isread, s->thumb);
7255                 }
7256                 break;
7257             case 15:
7258                 if (is64) {
7259                     syndrome = syn_cp15_rrt_trap(1, 0xe, opc1, crm, rt, rt2,
7260                                                  isread, s->thumb);
7261                 } else {
7262                     syndrome = syn_cp15_rt_trap(1, 0xe, opc1, opc2, crn, crm,
7263                                                 rt, isread, s->thumb);
7264                 }
7265                 break;
7266             default:
7267                 /* ARMv8 defines that only coprocessors 14 and 15 exist,
7268                  * so this can only happen if this is an ARMv7 or earlier CPU,
7269                  * in which case the syndrome information won't actually be
7270                  * guest visible.
7271                  */
7272                 assert(!arm_dc_feature(s, ARM_FEATURE_V8));
7273                 syndrome = syn_uncategorized();
7274                 break;
7275             }
7276 
7277             gen_set_pc_im(s, s->pc);
7278             tmpptr = tcg_const_ptr(tcg_ctx, ri);
7279             tcg_syn = tcg_const_i32(tcg_ctx, syndrome);
7280             gen_helper_access_check_cp_reg(tcg_ctx, tcg_ctx->cpu_env, tmpptr, tcg_syn);
7281             tcg_temp_free_ptr(tcg_ctx, tmpptr);
7282             tcg_temp_free_i32(tcg_ctx, tcg_syn);
7283         }
7284 
7285         /* Handle special cases first */
7286         switch (ri->type & ~(ARM_CP_FLAG_MASK & ~ARM_CP_SPECIAL)) {
7287         case ARM_CP_NOP:
7288             return 0;
7289         case ARM_CP_WFI:
7290             if (isread) {
7291                 return 1;
7292             }
7293             gen_set_pc_im(s, s->pc);
7294             s->is_jmp = DISAS_WFI;
7295             return 0;
7296         default:
7297             break;
7298         }
7299 
7300         if (isread) {
7301             /* Read */
7302             if (is64) {
7303                 TCGv_i64 tmp64;
7304                 TCGv_i32 tmp;
7305                 if (ri->type & ARM_CP_CONST) {
7306                     tmp64 = tcg_const_i64(tcg_ctx, ri->resetvalue);
7307                 } else if (ri->readfn) {
7308                     TCGv_ptr tmpptr;
7309                     tmp64 = tcg_temp_new_i64(tcg_ctx);
7310                     tmpptr = tcg_const_ptr(tcg_ctx, ri);
7311                     gen_helper_get_cp_reg64(tcg_ctx, tmp64, tcg_ctx->cpu_env, tmpptr);
7312                     tcg_temp_free_ptr(tcg_ctx, tmpptr);
7313                 } else {
7314                     tmp64 = tcg_temp_new_i64(tcg_ctx);
7315                     tcg_gen_ld_i64(tcg_ctx, tmp64, tcg_ctx->cpu_env, ri->fieldoffset);
7316                 }
7317                 tmp = tcg_temp_new_i32(tcg_ctx);
7318                 tcg_gen_trunc_i64_i32(tcg_ctx, tmp, tmp64);
7319                 store_reg(s, rt, tmp);
7320                 tcg_gen_shri_i64(tcg_ctx, tmp64, tmp64, 32);
7321                 tmp = tcg_temp_new_i32(tcg_ctx);
7322                 tcg_gen_trunc_i64_i32(tcg_ctx, tmp, tmp64);
7323                 tcg_temp_free_i64(tcg_ctx, tmp64);
7324                 store_reg(s, rt2, tmp);
7325             } else {
7326                 TCGv_i32 tmp;
7327                 if (ri->type & ARM_CP_CONST) {
7328                     tmp = tcg_const_i32(tcg_ctx, ri->resetvalue);
7329                 } else if (ri->readfn) {
7330                     TCGv_ptr tmpptr;
7331                     tmp = tcg_temp_new_i32(tcg_ctx);
7332                     tmpptr = tcg_const_ptr(tcg_ctx, ri);
7333                     gen_helper_get_cp_reg(tcg_ctx, tmp, tcg_ctx->cpu_env, tmpptr);
7334                     tcg_temp_free_ptr(tcg_ctx, tmpptr);
7335                 } else {
7336                     tmp = load_cpu_offset(s->uc, ri->fieldoffset);
7337                 }
7338                 if (rt == 15) {
7339                     /* Destination register of r15 for 32 bit loads sets
7340                      * the condition codes from the high 4 bits of the value
7341                      */
7342                     gen_set_nzcv(s, tmp);
7343                     tcg_temp_free_i32(tcg_ctx, tmp);
7344                 } else {
7345                     store_reg(s, rt, tmp);
7346                 }
7347             }
7348         } else {
7349             /* Write */
7350             if (ri->type & ARM_CP_CONST) {
7351                 /* If not forbidden by access permissions, treat as WI */
7352                 return 0;
7353             }
7354 
7355             if (is64) {
7356                 TCGv_i32 tmplo, tmphi;
7357                 TCGv_i64 tmp64 = tcg_temp_new_i64(tcg_ctx);
7358                 tmplo = load_reg(s, rt);
7359                 tmphi = load_reg(s, rt2);
7360                 tcg_gen_concat_i32_i64(tcg_ctx, tmp64, tmplo, tmphi);
7361                 tcg_temp_free_i32(tcg_ctx, tmplo);
7362                 tcg_temp_free_i32(tcg_ctx, tmphi);
7363                 if (ri->writefn) {
7364                     TCGv_ptr tmpptr = tcg_const_ptr(tcg_ctx, ri);
7365                     gen_helper_set_cp_reg64(tcg_ctx, tcg_ctx->cpu_env, tmpptr, tmp64);
7366                     tcg_temp_free_ptr(tcg_ctx, tmpptr);
7367                 } else {
7368                     tcg_gen_st_i64(tcg_ctx, tmp64, tcg_ctx->cpu_env, ri->fieldoffset);
7369                 }
7370                 tcg_temp_free_i64(tcg_ctx, tmp64);
7371             } else {
7372                 if (ri->writefn) {
7373                     TCGv_i32 tmp;
7374                     TCGv_ptr tmpptr;
7375                     tmp = load_reg(s, rt);
7376                     tmpptr = tcg_const_ptr(tcg_ctx, ri);
7377                     gen_helper_set_cp_reg(tcg_ctx, tcg_ctx->cpu_env, tmpptr, tmp);
7378                     tcg_temp_free_ptr(tcg_ctx, tmpptr);
7379                     tcg_temp_free_i32(tcg_ctx, tmp);
7380                 } else {
7381                     TCGv_i32 tmp = load_reg(s, rt);
7382                     store_cpu_offset(tcg_ctx, tmp, ri->fieldoffset);
7383                 }
7384             }
7385         }
7386 
7387         if (!isread && !(ri->type & ARM_CP_SUPPRESS_TB_END)) {
7388             /* We default to ending the TB on a coprocessor register write,
7389              * but allow this to be suppressed by the register definition
7390              * (usually only necessary to work around guest bugs).
7391              */
7392             gen_lookup_tb(s);
7393         }
7394 
7395         return 0;
7396     }
7397 
7398     /* Unknown register; this might be a guest error or a QEMU
7399      * unimplemented feature.
7400      */
7401     if (is64) {
7402         qemu_log_mask(LOG_UNIMP, "%s access to unsupported AArch32 "
7403                       "64 bit system register cp:%d opc1: %d crm:%d\n",
7404                       isread ? "read" : "write", cpnum, opc1, crm);
7405     } else {
7406         qemu_log_mask(LOG_UNIMP, "%s access to unsupported AArch32 "
7407                       "system register cp:%d opc1:%d crn:%d crm:%d opc2:%d\n",
7408                       isread ? "read" : "write", cpnum, opc1, crn, crm, opc2);
7409     }
7410 
7411     return 1;
7412 }
7413 
7414 
7415 /* Store a 64-bit value to a register pair.  Clobbers val.  */
gen_storeq_reg(DisasContext * s,int rlow,int rhigh,TCGv_i64 val)7416 static void gen_storeq_reg(DisasContext *s, int rlow, int rhigh, TCGv_i64 val)
7417 {
7418     TCGContext *tcg_ctx = s->uc->tcg_ctx;
7419     TCGv_i32 tmp;
7420     tmp = tcg_temp_new_i32(tcg_ctx);
7421     tcg_gen_trunc_i64_i32(tcg_ctx, tmp, val);
7422     store_reg(s, rlow, tmp);
7423     tmp = tcg_temp_new_i32(tcg_ctx);
7424     tcg_gen_shri_i64(tcg_ctx, val, val, 32);
7425     tcg_gen_trunc_i64_i32(tcg_ctx, tmp, val);
7426     store_reg(s, rhigh, tmp);
7427 }
7428 
7429 /* load a 32-bit value from a register and perform a 64-bit accumulate.  */
gen_addq_lo(DisasContext * s,TCGv_i64 val,int rlow)7430 static void gen_addq_lo(DisasContext *s, TCGv_i64 val, int rlow)
7431 {
7432     TCGContext *tcg_ctx = s->uc->tcg_ctx;
7433     TCGv_i64 tmp;
7434     TCGv_i32 tmp2;
7435 
7436     /* Load value and extend to 64 bits.  */
7437     tmp = tcg_temp_new_i64(tcg_ctx);
7438     tmp2 = load_reg(s, rlow);
7439     tcg_gen_extu_i32_i64(tcg_ctx, tmp, tmp2);
7440     tcg_temp_free_i32(tcg_ctx, tmp2);
7441     tcg_gen_add_i64(tcg_ctx, val, val, tmp);
7442     tcg_temp_free_i64(tcg_ctx, tmp);
7443 }
7444 
7445 /* load and add a 64-bit value from a register pair.  */
gen_addq(DisasContext * s,TCGv_i64 val,int rlow,int rhigh)7446 static void gen_addq(DisasContext *s, TCGv_i64 val, int rlow, int rhigh)
7447 {
7448     TCGContext *tcg_ctx = s->uc->tcg_ctx;
7449     TCGv_i64 tmp;
7450     TCGv_i32 tmpl;
7451     TCGv_i32 tmph;
7452 
7453     /* Load 64-bit value rd:rn.  */
7454     tmpl = load_reg(s, rlow);
7455     tmph = load_reg(s, rhigh);
7456     tmp = tcg_temp_new_i64(tcg_ctx);
7457     tcg_gen_concat_i32_i64(tcg_ctx, tmp, tmpl, tmph);
7458     tcg_temp_free_i32(tcg_ctx, tmpl);
7459     tcg_temp_free_i32(tcg_ctx, tmph);
7460     tcg_gen_add_i64(tcg_ctx, val, val, tmp);
7461     tcg_temp_free_i64(tcg_ctx, tmp);
7462 }
7463 
7464 /* Set N and Z flags from hi|lo.  */
gen_logicq_cc(DisasContext * s,TCGv_i32 lo,TCGv_i32 hi)7465 static void gen_logicq_cc(DisasContext *s, TCGv_i32 lo, TCGv_i32 hi)
7466 {
7467     TCGContext *tcg_ctx = s->uc->tcg_ctx;
7468     tcg_gen_mov_i32(tcg_ctx, tcg_ctx->cpu_NF, hi);
7469     tcg_gen_or_i32(tcg_ctx, tcg_ctx->cpu_ZF, lo, hi);
7470 }
7471 
7472 /* Load/Store exclusive instructions are implemented by remembering
7473    the value/address loaded, and seeing if these are the same
7474    when the store is performed. This should be sufficient to implement
7475    the architecturally mandated semantics, and avoids having to monitor
7476    regular stores.
7477 
7478    In system emulation mode only one CPU will be running at once, so
7479    this sequence is effectively atomic.  In user emulation mode we
7480    throw an exception and handle the atomic operation elsewhere.  */
gen_load_exclusive(DisasContext * s,int rt,int rt2,TCGv_i32 addr,int size)7481 static void gen_load_exclusive(DisasContext *s, int rt, int rt2,
7482                                TCGv_i32 addr, int size)
7483 {
7484     TCGContext *tcg_ctx = s->uc->tcg_ctx;
7485     TCGv_i32 tmp = tcg_temp_new_i32(tcg_ctx);
7486 
7487     s->is_ldex = true;
7488 
7489     switch (size) {
7490     case 0:
7491         gen_aa32_ld8u(s, tmp, addr, get_mem_index(s));
7492         break;
7493     case 1:
7494         gen_aa32_ld16u(s, tmp, addr, get_mem_index(s));
7495         break;
7496     case 2:
7497     case 3:
7498         gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
7499         break;
7500     default:
7501         abort();
7502     }
7503 
7504     if (size == 3) {
7505         TCGv_i32 tmp2 = tcg_temp_new_i32(tcg_ctx);
7506         TCGv_i32 tmp3 = tcg_temp_new_i32(tcg_ctx);
7507 
7508         tcg_gen_addi_i32(tcg_ctx, tmp2, addr, 4);
7509         gen_aa32_ld32u(s, tmp3, tmp2, get_mem_index(s));
7510         tcg_temp_free_i32(tcg_ctx, tmp2);
7511         tcg_gen_concat_i32_i64(tcg_ctx, tcg_ctx->cpu_exclusive_val, tmp, tmp3);
7512         store_reg(s, rt2, tmp3);
7513     } else {
7514         tcg_gen_extu_i32_i64(tcg_ctx, tcg_ctx->cpu_exclusive_val, tmp);
7515     }
7516 
7517     store_reg(s, rt, tmp);
7518     tcg_gen_extu_i32_i64(tcg_ctx, tcg_ctx->cpu_exclusive_addr, addr);
7519 }
7520 
gen_clrex(DisasContext * s)7521 static void gen_clrex(DisasContext *s)
7522 {
7523     TCGContext *tcg_ctx = s->uc->tcg_ctx;
7524     tcg_gen_movi_i64(tcg_ctx, tcg_ctx->cpu_exclusive_addr, -1);
7525 }
7526 
7527 #ifdef CONFIG_USER_ONLY
gen_store_exclusive(DisasContext * s,int rd,int rt,int rt2,TCGv_i32 addr,int size)7528 static void gen_store_exclusive(DisasContext *s, int rd, int rt, int rt2,
7529                                 TCGv_i32 addr, int size)
7530 {
7531     TCGContext *tcg_ctx = s->uc->tcg_ctx;
7532     tcg_gen_extu_i32_i64(tcg_ctx, cpu_exclusive_test, addr);
7533     tcg_gen_movi_i32(tcg_ctx, cpu_exclusive_info,
7534                      size | (rd << 4) | (rt << 8) | (rt2 << 12));
7535     gen_exception_internal_insn(s, 4, EXCP_STREX);
7536 }
7537 #else
gen_store_exclusive(DisasContext * s,int rd,int rt,int rt2,TCGv_i32 addr,int size)7538 static void gen_store_exclusive(DisasContext *s, int rd, int rt, int rt2,
7539                                 TCGv_i32 addr, int size)
7540 {
7541     TCGContext *tcg_ctx = s->uc->tcg_ctx;
7542     TCGv_i32 tmp;
7543     TCGv_i64 val64, extaddr;
7544     int done_label;
7545     int fail_label;
7546 
7547     /* if (env->exclusive_addr == addr && env->exclusive_val == [addr]) {
7548          [addr] = {Rt};
7549          {Rd} = 0;
7550        } else {
7551          {Rd} = 1;
7552        } */
7553     fail_label = gen_new_label(tcg_ctx);
7554     done_label = gen_new_label(tcg_ctx);
7555     extaddr = tcg_temp_new_i64(tcg_ctx);
7556     tcg_gen_extu_i32_i64(tcg_ctx, extaddr, addr);
7557     tcg_gen_brcond_i64(tcg_ctx, TCG_COND_NE, extaddr, tcg_ctx->cpu_exclusive_addr, fail_label);
7558     tcg_temp_free_i64(tcg_ctx, extaddr);
7559 
7560     tmp = tcg_temp_new_i32(tcg_ctx);
7561     switch (size) {
7562     case 0:
7563         gen_aa32_ld8u(s, tmp, addr, get_mem_index(s));
7564         break;
7565     case 1:
7566         gen_aa32_ld16u(s, tmp, addr, get_mem_index(s));
7567         break;
7568     case 2:
7569     case 3:
7570         gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
7571         break;
7572     default:
7573         abort();
7574     }
7575 
7576     val64 = tcg_temp_new_i64(tcg_ctx);
7577     if (size == 3) {
7578         TCGv_i32 tmp2 = tcg_temp_new_i32(tcg_ctx);
7579         TCGv_i32 tmp3 = tcg_temp_new_i32(tcg_ctx);
7580         tcg_gen_addi_i32(tcg_ctx, tmp2, addr, 4);
7581         gen_aa32_ld32u(s, tmp3, tmp2, get_mem_index(s));
7582         tcg_temp_free_i32(tcg_ctx, tmp2);
7583         tcg_gen_concat_i32_i64(tcg_ctx, val64, tmp, tmp3);
7584         tcg_temp_free_i32(tcg_ctx, tmp3);
7585     } else {
7586         tcg_gen_extu_i32_i64(tcg_ctx, val64, tmp);
7587     }
7588     tcg_temp_free_i32(tcg_ctx, tmp);
7589 
7590     tcg_gen_brcond_i64(tcg_ctx, TCG_COND_NE, val64, tcg_ctx->cpu_exclusive_val, fail_label);
7591     tcg_temp_free_i64(tcg_ctx, val64);
7592 
7593     tmp = load_reg(s, rt);
7594     switch (size) {
7595     case 0:
7596         gen_aa32_st8(s, tmp, addr, get_mem_index(s));
7597         break;
7598     case 1:
7599         gen_aa32_st16(s, tmp, addr, get_mem_index(s));
7600         break;
7601     case 2:
7602     case 3:
7603         gen_aa32_st32(s, tmp, addr, get_mem_index(s));
7604         break;
7605     default:
7606         abort();
7607     }
7608     tcg_temp_free_i32(tcg_ctx, tmp);
7609     if (size == 3) {
7610         tcg_gen_addi_i32(tcg_ctx, addr, addr, 4);
7611         tmp = load_reg(s, rt2);
7612         gen_aa32_st32(s, tmp, addr, get_mem_index(s));
7613         tcg_temp_free_i32(tcg_ctx, tmp);
7614     }
7615     tcg_gen_movi_i32(tcg_ctx, tcg_ctx->cpu_R[rd], 0);
7616     tcg_gen_br(tcg_ctx, done_label);
7617     gen_set_label(tcg_ctx, fail_label);
7618     tcg_gen_movi_i32(tcg_ctx, tcg_ctx->cpu_R[rd], 1);
7619     gen_set_label(tcg_ctx, done_label);
7620     tcg_gen_movi_i64(tcg_ctx, tcg_ctx->cpu_exclusive_addr, -1);
7621 }
7622 #endif
7623 
7624 /* gen_srs:
7625  * @env: CPUARMState
7626  * @s: DisasContext
7627  * @mode: mode field from insn (which stack to store to)
7628  * @amode: addressing mode (DA/IA/DB/IB), encoded as per P,U bits in ARM insn
7629  * @writeback: true if writeback bit set
7630  *
7631  * Generate code for the SRS (Store Return State) insn.
7632  */
gen_srs(DisasContext * s,uint32_t mode,uint32_t amode,bool writeback)7633 static void gen_srs(DisasContext *s,
7634                     uint32_t mode, uint32_t amode, bool writeback)
7635 {
7636     TCGContext *tcg_ctx = s->uc->tcg_ctx;
7637     int32_t offset;
7638     TCGv_i32 addr = tcg_temp_new_i32(tcg_ctx);
7639     TCGv_i32 tmp = tcg_const_i32(tcg_ctx, mode);
7640     gen_helper_get_r13_banked(tcg_ctx, addr, tcg_ctx->cpu_env, tmp);
7641     tcg_temp_free_i32(tcg_ctx, tmp);
7642     switch (amode) {
7643     case 0: /* DA */
7644         offset = -4;
7645         break;
7646     case 1: /* IA */
7647         offset = 0;
7648         break;
7649     case 2: /* DB */
7650         offset = -8;
7651         break;
7652     case 3: /* IB */
7653         offset = 4;
7654         break;
7655     default:
7656         abort();
7657     }
7658     tcg_gen_addi_i32(tcg_ctx, addr, addr, offset);
7659     tmp = load_reg(s, 14);
7660     gen_aa32_st32(s, tmp, addr, get_mem_index(s));
7661     tcg_temp_free_i32(tcg_ctx, tmp);
7662     tmp = load_cpu_field(s->uc, spsr);
7663     tcg_gen_addi_i32(tcg_ctx, addr, addr, 4);
7664     gen_aa32_st32(s, tmp, addr, get_mem_index(s));
7665     tcg_temp_free_i32(tcg_ctx, tmp);
7666     if (writeback) {
7667         switch (amode) {
7668         case 0:
7669             offset = -8;
7670             break;
7671         case 1:
7672             offset = 4;
7673             break;
7674         case 2:
7675             offset = -4;
7676             break;
7677         case 3:
7678             offset = 0;
7679             break;
7680         default:
7681             abort();
7682         }
7683         tcg_gen_addi_i32(tcg_ctx, addr, addr, offset);
7684         tmp = tcg_const_i32(tcg_ctx, mode);
7685         gen_helper_set_r13_banked(tcg_ctx, tcg_ctx->cpu_env, tmp, addr);
7686         tcg_temp_free_i32(tcg_ctx, tmp);
7687     }
7688     tcg_temp_free_i32(tcg_ctx, addr);
7689 }
7690 
disas_arm_insn(DisasContext * s,unsigned int insn)7691 static void disas_arm_insn(DisasContext *s, unsigned int insn)  // qq
7692 {
7693     TCGContext *tcg_ctx = s->uc->tcg_ctx;
7694     unsigned int cond, val, op1, i, shift, rm, rs, rn, rd, sh;
7695     TCGv_i32 tmp;
7696     TCGv_i32 tmp2;
7697     TCGv_i32 tmp3;
7698     TCGv_i32 addr;
7699     TCGv_i64 tmp64;
7700 
7701     /* M variants do not implement ARM mode.  */
7702     if (arm_dc_feature(s, ARM_FEATURE_M)) {
7703         goto illegal_op;
7704     }
7705 
7706     // Unicorn: trace this instruction on request
7707     if (HOOK_EXISTS_BOUNDED(s->uc, UC_HOOK_CODE, s->pc - 4)) {
7708         gen_uc_tracecode(tcg_ctx, 4, UC_HOOK_CODE_IDX, s->uc, s->pc - 4);
7709         // the callback might want to stop emulation immediately
7710         check_exit_request(tcg_ctx);
7711     }
7712 
7713     cond = insn >> 28;
7714     if (cond == 0xf){
7715         /* In ARMv3 and v4 the NV condition is UNPREDICTABLE; we
7716          * choose to UNDEF. In ARMv5 and above the space is used
7717          * for miscellaneous unconditional instructions.
7718          */
7719         ARCH(5);
7720 
7721         /* Unconditional instructions.  */
7722         if (((insn >> 25) & 7) == 1) {
7723             /* NEON Data processing.  */
7724             if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {
7725                 goto illegal_op;
7726             }
7727 
7728             if (disas_neon_data_insn(s, insn)) {
7729                 goto illegal_op;
7730             }
7731             return;
7732         }
7733         if ((insn & 0x0f100000) == 0x04000000) {
7734             /* NEON load/store.  */
7735             if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {
7736                 goto illegal_op;
7737             }
7738 
7739             if (disas_neon_ls_insn(s, insn)) {
7740                 goto illegal_op;
7741             }
7742             return;
7743         }
7744         if ((insn & 0x0f000e10) == 0x0e000a00) {
7745             /* VFP.  */
7746             if (disas_vfp_insn(s, insn)) {
7747                 goto illegal_op;
7748             }
7749             return;
7750         }
7751         if (((insn & 0x0f30f000) == 0x0510f000) ||
7752             ((insn & 0x0f30f010) == 0x0710f000)) {
7753             if ((insn & (1 << 22)) == 0) {
7754                 /* PLDW; v7MP */
7755                 if (!arm_dc_feature(s, ARM_FEATURE_V7MP)) {
7756                     goto illegal_op;
7757                 }
7758             }
7759             /* Otherwise PLD; v5TE+ */
7760             ARCH(5TE);
7761             return;
7762         }
7763         if (((insn & 0x0f70f000) == 0x0450f000) ||
7764             ((insn & 0x0f70f010) == 0x0650f000)) {
7765             ARCH(7);
7766             return; /* PLI; V7 */
7767         }
7768         if (((insn & 0x0f700000) == 0x04100000) ||
7769             ((insn & 0x0f700010) == 0x06100000)) {
7770             if (!arm_dc_feature(s, ARM_FEATURE_V7MP)) {
7771                 goto illegal_op;
7772             }
7773             return; /* v7MP: Unallocated memory hint: must NOP */
7774         }
7775 
7776         if ((insn & 0x0ffffdff) == 0x01010000) {
7777             ARCH(6);
7778             /* setend */
7779             if (((insn >> 9) & 1) != s->bswap_code) {
7780                 /* Dynamic endianness switching not implemented. */
7781                 qemu_log_mask(LOG_UNIMP, "arm: unimplemented setend\n");
7782                 goto illegal_op;
7783             }
7784             return;
7785         } else if ((insn & 0x0fffff00) == 0x057ff000) {
7786             switch ((insn >> 4) & 0xf) {
7787             case 1: /* clrex */
7788                 ARCH(6K);
7789                 gen_clrex(s);
7790                 return;
7791             case 4: /* dsb */
7792             case 5: /* dmb */
7793             case 6: /* isb */
7794                 ARCH(7);
7795                 /* We don't emulate caches so these are a no-op.  */
7796                 return;
7797             default:
7798                 goto illegal_op;
7799             }
7800         } else if ((insn & 0x0e5fffe0) == 0x084d0500) {
7801             /* srs */
7802             if (IS_USER(s)) {
7803                 goto illegal_op;
7804             }
7805             ARCH(6);
7806             gen_srs(s, (insn & 0x1f), (insn >> 23) & 3, insn & (1 << 21));
7807             return;
7808         } else if ((insn & 0x0e50ffe0) == 0x08100a00) {
7809             /* rfe */
7810             int32_t offset;
7811             if (IS_USER(s))
7812                 goto illegal_op;
7813             ARCH(6);
7814             rn = (insn >> 16) & 0xf;
7815             addr = load_reg(s, rn);
7816             i = (insn >> 23) & 3;
7817             switch (i) {
7818             case 0: offset = -4; break; /* DA */
7819             case 1: offset = 0; break; /* IA */
7820             case 2: offset = -8; break; /* DB */
7821             case 3: offset = 4; break; /* IB */
7822             default: abort();
7823             }
7824             if (offset)
7825                 tcg_gen_addi_i32(tcg_ctx, addr, addr, offset);
7826             /* Load PC into tmp and CPSR into tmp2.  */
7827             tmp = tcg_temp_new_i32(tcg_ctx);
7828             gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
7829             tcg_gen_addi_i32(tcg_ctx, addr, addr, 4);
7830             tmp2 = tcg_temp_new_i32(tcg_ctx);
7831             gen_aa32_ld32u(s, tmp2, addr, get_mem_index(s));
7832             if (insn & (1 << 21)) {
7833                 /* Base writeback.  */
7834                 switch (i) {
7835                 case 0: offset = -8; break;
7836                 case 1: offset = 4; break;
7837                 case 2: offset = -4; break;
7838                 case 3: offset = 0; break;
7839                 default: abort();
7840                 }
7841                 if (offset)
7842                     tcg_gen_addi_i32(tcg_ctx, addr, addr, offset);
7843                 store_reg(s, rn, addr);
7844             } else {
7845                 tcg_temp_free_i32(tcg_ctx, addr);
7846             }
7847             gen_rfe(s, tmp, tmp2);
7848             return;
7849         } else if ((insn & 0x0e000000) == 0x0a000000) {
7850             /* branch link and change to thumb (blx <offset>) */
7851             int32_t offset;
7852 
7853             val = (uint32_t)s->pc;
7854             tmp = tcg_temp_new_i32(tcg_ctx);
7855             tcg_gen_movi_i32(tcg_ctx, tmp, val);
7856             store_reg(s, 14, tmp);
7857             /* Sign-extend the 24-bit offset */
7858             offset = ((int32_t)(insn << 8)) >> 8;
7859             /* offset * 4 + bit24 * 2 + (thumb bit) */
7860             val += (((uint32_t)offset) << 2) | ((insn >> 23) & 2) | 1;
7861             /* pipeline offset */
7862             val += 4;
7863             /* protected by ARCH(5); above, near the start of uncond block */
7864             gen_bx_im(s, val);
7865             return;
7866         } else if ((insn & 0x0e000f00) == 0x0c000100) {
7867             if (arm_dc_feature(s, ARM_FEATURE_IWMMXT)) {
7868                 /* iWMMXt register transfer.  */
7869                 if (extract32(s->c15_cpar, 1, 1)) {
7870                     if (!disas_iwmmxt_insn(s, insn)) {
7871                         return;
7872                     }
7873                 }
7874             }
7875         } else if ((insn & 0x0fe00000) == 0x0c400000) {
7876             /* Coprocessor double register transfer.  */
7877             ARCH(5TE);
7878         } else if ((insn & 0x0f000010) == 0x0e000010) {
7879             /* Additional coprocessor register transfer.  */
7880         } else if ((insn & 0x0ff10020) == 0x01000000) {
7881             uint32_t mask;
7882             uint32_t val;
7883             /* cps (privileged) */
7884             if (IS_USER(s))
7885                 return;
7886             mask = val = 0;
7887             if (insn & (1 << 19)) {
7888                 if (insn & (1 << 8))
7889                     mask |= CPSR_A;
7890                 if (insn & (1 << 7))
7891                     mask |= CPSR_I;
7892                 if (insn & (1 << 6))
7893                     mask |= CPSR_F;
7894                 if (insn & (1 << 18))
7895                     val |= mask;
7896             }
7897             if (insn & (1 << 17)) {
7898                 mask |= CPSR_M;
7899                 val |= (insn & 0x1f);
7900             }
7901             if (mask) {
7902                 gen_set_psr_im(s, mask, 0, val);
7903             }
7904             return;
7905         }
7906         goto illegal_op;
7907     }
7908     if (cond != 0xe) {
7909         /* if not always execute, we generate a conditional jump to
7910            next instruction */
7911         s->condlabel = gen_new_label(tcg_ctx);
7912         arm_gen_test_cc(tcg_ctx, cond ^ 1, s->condlabel);
7913         s->condjmp = 1;
7914     }
7915     if ((insn & 0x0f900000) == 0x03000000) {
7916         if ((insn & (1 << 21)) == 0) {
7917             ARCH(6T2);
7918             rd = (insn >> 12) & 0xf;
7919             val = ((insn >> 4) & 0xf000) | (insn & 0xfff);
7920             if ((insn & (1 << 22)) == 0) {
7921                 /* MOVW */
7922                 tmp = tcg_temp_new_i32(tcg_ctx);
7923                 tcg_gen_movi_i32(tcg_ctx, tmp, val);
7924             } else {
7925                 /* MOVT */
7926                 tmp = load_reg(s, rd);
7927                 tcg_gen_ext16u_i32(tcg_ctx, tmp, tmp);
7928                 tcg_gen_ori_i32(tcg_ctx, tmp, tmp, val << 16);
7929             }
7930             store_reg(s, rd, tmp);
7931         } else {
7932             if (((insn >> 12) & 0xf) != 0xf)
7933                 goto illegal_op;
7934             if (((insn >> 16) & 0xf) == 0) {
7935                 gen_nop_hint(s, insn & 0xff);
7936             } else {
7937                 /* CPSR = immediate */
7938                 val = insn & 0xff;
7939                 shift = ((insn >> 8) & 0xf) * 2;
7940                 if (shift)
7941                     val = (val >> shift) | (val << (32 - shift));
7942                 i = ((insn & (1 << 22)) != 0);
7943                 if (gen_set_psr_im(s, msr_mask(s, (insn >> 16) & 0xf, i),
7944                                    i, val)) {
7945                     goto illegal_op;
7946                 }
7947             }
7948         }
7949     } else if ((insn & 0x0f900000) == 0x01000000
7950                && (insn & 0x00000090) != 0x00000090) {
7951         /* miscellaneous instructions */
7952         op1 = (insn >> 21) & 3;
7953         sh = (insn >> 4) & 0xf;
7954         rm = insn & 0xf;
7955         switch (sh) {
7956         case 0x0: /* move program status register */
7957             if (op1 & 1) {
7958                 /* PSR = reg */
7959                 tmp = load_reg(s, rm);
7960                 i = ((op1 & 2) != 0);
7961                 if (gen_set_psr(s, msr_mask(s, (insn >> 16) & 0xf, i), i, tmp))
7962                     goto illegal_op;
7963             } else {
7964                 /* reg = PSR */
7965                 rd = (insn >> 12) & 0xf;
7966                 if (op1 & 2) {
7967                     if (IS_USER(s))
7968                         goto illegal_op;
7969                     tmp = load_cpu_field(s->uc, spsr);
7970                 } else {
7971                     tmp = tcg_temp_new_i32(tcg_ctx);
7972                     gen_helper_cpsr_read(tcg_ctx, tmp, tcg_ctx->cpu_env);
7973                 }
7974                 store_reg(s, rd, tmp);
7975             }
7976             break;
7977         case 0x1:
7978             if (op1 == 1) {
7979                 /* branch/exchange thumb (bx).  */
7980                 ARCH(4T);
7981                 tmp = load_reg(s, rm);
7982                 gen_bx(s, tmp);
7983             } else if (op1 == 3) {
7984                 /* clz */
7985                 ARCH(5);
7986                 rd = (insn >> 12) & 0xf;
7987                 tmp = load_reg(s, rm);
7988                 gen_helper_clz(tcg_ctx, tmp, tmp);
7989                 store_reg(s, rd, tmp);
7990             } else {
7991                 goto illegal_op;
7992             }
7993             break;
7994         case 0x2:
7995             if (op1 == 1) {
7996                 ARCH(5J); /* bxj */
7997                 /* Trivial implementation equivalent to bx.  */
7998                 tmp = load_reg(s, rm);
7999                 gen_bx(s, tmp);
8000             } else {
8001                 goto illegal_op;
8002             }
8003             break;
8004         case 0x3:
8005             if (op1 != 1)
8006               goto illegal_op;
8007 
8008             ARCH(5);
8009             /* branch link/exchange thumb (blx) */
8010             tmp = load_reg(s, rm);
8011             tmp2 = tcg_temp_new_i32(tcg_ctx);
8012             tcg_gen_movi_i32(tcg_ctx, tmp2, s->pc);
8013             store_reg(s, 14, tmp2);
8014             gen_bx(s, tmp);
8015             break;
8016         case 0x4:
8017         {
8018             /* crc32/crc32c */
8019             uint32_t c = extract32(insn, 8, 4);
8020 
8021             /* Check this CPU supports ARMv8 CRC instructions.
8022              * op1 == 3 is UNPREDICTABLE but handle as UNDEFINED.
8023              * Bits 8, 10 and 11 should be zero.
8024              */
8025             if (!arm_dc_feature(s, ARM_FEATURE_CRC) || op1 == 0x3 ||
8026                 (c & 0xd) != 0) {
8027                 goto illegal_op;
8028             }
8029 
8030             rn = extract32(insn, 16, 4);
8031             rd = extract32(insn, 12, 4);
8032 
8033             tmp = load_reg(s, rn);
8034             tmp2 = load_reg(s, rm);
8035             if (op1 == 0) {
8036                 tcg_gen_andi_i32(tcg_ctx, tmp2, tmp2, 0xff);
8037             } else if (op1 == 1) {
8038                 tcg_gen_andi_i32(tcg_ctx, tmp2, tmp2, 0xffff);
8039             }
8040             tmp3 = tcg_const_i32(tcg_ctx, 1 << op1);
8041             if (c & 0x2) {
8042                 gen_helper_crc32c(tcg_ctx, tmp, tmp, tmp2, tmp3);
8043             } else {
8044                 gen_helper_crc32(tcg_ctx, tmp, tmp, tmp2, tmp3);
8045             }
8046             tcg_temp_free_i32(tcg_ctx, tmp2);
8047             tcg_temp_free_i32(tcg_ctx, tmp3);
8048             store_reg(s, rd, tmp);
8049             break;
8050         }
8051         case 0x5: /* saturating add/subtract */
8052             ARCH(5TE);
8053             rd = (insn >> 12) & 0xf;
8054             rn = (insn >> 16) & 0xf;
8055             tmp = load_reg(s, rm);
8056             tmp2 = load_reg(s, rn);
8057             if (op1 & 2)
8058                 gen_helper_double_saturate(tcg_ctx, tmp2, tcg_ctx->cpu_env, tmp2);
8059             if (op1 & 1)
8060                 gen_helper_sub_saturate(tcg_ctx, tmp, tcg_ctx->cpu_env, tmp, tmp2);
8061             else
8062                 gen_helper_add_saturate(tcg_ctx, tmp, tcg_ctx->cpu_env, tmp, tmp2);
8063             tcg_temp_free_i32(tcg_ctx, tmp2);
8064             store_reg(s, rd, tmp);
8065             break;
8066         case 7:
8067         {
8068             int imm16 = extract32(insn, 0, 4) | (extract32(insn, 8, 12) << 4);
8069             switch (op1) {
8070             case 1:
8071                 /* bkpt */
8072                 ARCH(5);
8073                 gen_exception_insn(s, 4, EXCP_BKPT,
8074                                    syn_aa32_bkpt(imm16, false));
8075                 break;
8076             case 2:
8077                 /* Hypervisor call (v7) */
8078                 ARCH(7);
8079                 if (IS_USER(s)) {
8080                     goto illegal_op;
8081                 }
8082                 gen_hvc(s, imm16);
8083                 break;
8084             case 3:
8085                 /* Secure monitor call (v6+) */
8086                 ARCH(6K);
8087                 if (IS_USER(s)) {
8088                     goto illegal_op;
8089                 }
8090                 gen_smc(s);
8091                 break;
8092             default:
8093                 goto illegal_op;
8094             }
8095             break;
8096         }
8097         case 0x8: /* signed multiply */
8098         case 0xa:
8099         case 0xc:
8100         case 0xe:
8101             ARCH(5TE);
8102             rs = (insn >> 8) & 0xf;
8103             rn = (insn >> 12) & 0xf;
8104             rd = (insn >> 16) & 0xf;
8105             if (op1 == 1) {
8106                 /* (32 * 16) >> 16 */
8107                 tmp = load_reg(s, rm);
8108                 tmp2 = load_reg(s, rs);
8109                 if (sh & 4)
8110                     tcg_gen_sari_i32(tcg_ctx, tmp2, tmp2, 16);
8111                 else
8112                     gen_sxth(tmp2);
8113                 tmp64 = gen_muls_i64_i32(s, tmp, tmp2);
8114                 tcg_gen_shri_i64(tcg_ctx, tmp64, tmp64, 16);
8115                 tmp = tcg_temp_new_i32(tcg_ctx);
8116                 tcg_gen_trunc_i64_i32(tcg_ctx, tmp, tmp64);
8117                 tcg_temp_free_i64(tcg_ctx, tmp64);
8118                 if ((sh & 2) == 0) {
8119                     tmp2 = load_reg(s, rn);
8120                     gen_helper_add_setq(tcg_ctx, tmp, tcg_ctx->cpu_env, tmp, tmp2);
8121                     tcg_temp_free_i32(tcg_ctx, tmp2);
8122                 }
8123                 store_reg(s, rd, tmp);
8124             } else {
8125                 /* 16 * 16 */
8126                 tmp = load_reg(s, rm);
8127                 tmp2 = load_reg(s, rs);
8128                 gen_mulxy(s, tmp, tmp2, sh & 2, sh & 4);
8129                 tcg_temp_free_i32(tcg_ctx, tmp2);
8130                 if (op1 == 2) {
8131                     tmp64 = tcg_temp_new_i64(tcg_ctx);
8132                     tcg_gen_ext_i32_i64(tcg_ctx, tmp64, tmp);
8133                     tcg_temp_free_i32(tcg_ctx, tmp);
8134                     gen_addq(s, tmp64, rn, rd);
8135                     gen_storeq_reg(s, rn, rd, tmp64);
8136                     tcg_temp_free_i64(tcg_ctx, tmp64);
8137                 } else {
8138                     if (op1 == 0) {
8139                         tmp2 = load_reg(s, rn);
8140                         gen_helper_add_setq(tcg_ctx, tmp, tcg_ctx->cpu_env, tmp, tmp2);
8141                         tcg_temp_free_i32(tcg_ctx, tmp2);
8142                     }
8143                     store_reg(s, rd, tmp);
8144                 }
8145             }
8146             break;
8147         default:
8148             goto illegal_op;
8149         }
8150     } else if (((insn & 0x0e000000) == 0 &&
8151                 (insn & 0x00000090) != 0x90) ||
8152                ((insn & 0x0e000000) == (1 << 25))) {
8153         int set_cc, logic_cc, shiftop;
8154 
8155         op1 = (insn >> 21) & 0xf;
8156         set_cc = (insn >> 20) & 1;
8157         logic_cc = table_logic_cc[op1] & set_cc;
8158 
8159         /* data processing instruction */
8160         if (insn & (1 << 25)) {
8161             /* immediate operand */
8162             val = insn & 0xff;
8163             shift = ((insn >> 8) & 0xf) * 2;
8164             if (shift) {
8165                 val = (val >> shift) | (val << (32 - shift));
8166             }
8167             tmp2 = tcg_temp_new_i32(tcg_ctx);
8168             tcg_gen_movi_i32(tcg_ctx, tmp2, val);
8169             if (logic_cc && shift) {
8170                 gen_set_CF_bit31(s, tmp2);
8171             }
8172         } else {
8173             /* register */
8174             rm = (insn) & 0xf;
8175             tmp2 = load_reg(s, rm);
8176             shiftop = (insn >> 5) & 3;
8177             if (!(insn & (1 << 4))) {
8178                 shift = (insn >> 7) & 0x1f;
8179                 gen_arm_shift_im(s, tmp2, shiftop, shift, logic_cc);
8180             } else {
8181                 rs = (insn >> 8) & 0xf;
8182                 tmp = load_reg(s, rs);
8183                 gen_arm_shift_reg(s, tmp2, shiftop, tmp, logic_cc);
8184             }
8185         }
8186         if (op1 != 0x0f && op1 != 0x0d) {
8187             rn = (insn >> 16) & 0xf;
8188             tmp = load_reg(s, rn);
8189         } else {
8190             TCGV_UNUSED_I32(tmp);
8191         }
8192         rd = (insn >> 12) & 0xf;
8193         switch(op1) {
8194         case 0x00:
8195             tcg_gen_and_i32(tcg_ctx, tmp, tmp, tmp2);
8196             if (logic_cc) {
8197                 gen_logic_CC(s, tmp);
8198             }
8199             store_reg_bx(s, rd, tmp);
8200             break;
8201         case 0x01:
8202             tcg_gen_xor_i32(tcg_ctx, tmp, tmp, tmp2);
8203             if (logic_cc) {
8204                 gen_logic_CC(s, tmp);
8205             }
8206             store_reg_bx(s, rd, tmp);
8207             break;
8208         case 0x02:
8209             if (set_cc && rd == 15) {
8210                 /* SUBS r15, ... is used for exception return.  */
8211                 if (IS_USER(s)) {
8212                     goto illegal_op;
8213                 }
8214                 gen_sub_CC(s, tmp, tmp, tmp2);
8215                 gen_exception_return(s, tmp);
8216             } else {
8217                 if (set_cc) {
8218                     gen_sub_CC(s, tmp, tmp, tmp2);
8219                 } else {
8220                     tcg_gen_sub_i32(tcg_ctx, tmp, tmp, tmp2);
8221                 }
8222                 store_reg_bx(s, rd, tmp);
8223             }
8224             break;
8225         case 0x03:
8226             if (set_cc) {
8227                 gen_sub_CC(s, tmp, tmp2, tmp);
8228             } else {
8229                 tcg_gen_sub_i32(tcg_ctx, tmp, tmp2, tmp);
8230             }
8231             store_reg_bx(s, rd, tmp);
8232             break;
8233         case 0x04:
8234             if (set_cc) {
8235                 gen_add_CC(s, tmp, tmp, tmp2);
8236             } else {
8237                 tcg_gen_add_i32(tcg_ctx, tmp, tmp, tmp2);
8238             }
8239             store_reg_bx(s, rd, tmp);
8240             break;
8241         case 0x05:
8242             if (set_cc) {
8243                 gen_adc_CC(s, tmp, tmp, tmp2);
8244             } else {
8245                 gen_add_carry(s, tmp, tmp, tmp2);
8246             }
8247             store_reg_bx(s, rd, tmp);
8248             break;
8249         case 0x06:
8250             if (set_cc) {
8251                 gen_sbc_CC(s, tmp, tmp, tmp2);
8252             } else {
8253                 gen_sub_carry(s, tmp, tmp, tmp2);
8254             }
8255             store_reg_bx(s, rd, tmp);
8256             break;
8257         case 0x07:
8258             if (set_cc) {
8259                 gen_sbc_CC(s, tmp, tmp2, tmp);
8260             } else {
8261                 gen_sub_carry(s, tmp, tmp2, tmp);
8262             }
8263             store_reg_bx(s, rd, tmp);
8264             break;
8265         case 0x08:
8266             if (set_cc) {
8267                 tcg_gen_and_i32(tcg_ctx, tmp, tmp, tmp2);
8268                 gen_logic_CC(s, tmp);
8269             }
8270             tcg_temp_free_i32(tcg_ctx, tmp);
8271             break;
8272         case 0x09:
8273             if (set_cc) {
8274                 tcg_gen_xor_i32(tcg_ctx, tmp, tmp, tmp2);
8275                 gen_logic_CC(s, tmp);
8276             }
8277             tcg_temp_free_i32(tcg_ctx, tmp);
8278             break;
8279         case 0x0a:
8280             if (set_cc) {
8281                 gen_sub_CC(s, tmp, tmp, tmp2);
8282             }
8283             tcg_temp_free_i32(tcg_ctx, tmp);
8284             break;
8285         case 0x0b:
8286             if (set_cc) {
8287                 gen_add_CC(s, tmp, tmp, tmp2);
8288             }
8289             tcg_temp_free_i32(tcg_ctx, tmp);
8290             break;
8291         case 0x0c:
8292             tcg_gen_or_i32(tcg_ctx, tmp, tmp, tmp2);
8293             if (logic_cc) {
8294                 gen_logic_CC(s, tmp);
8295             }
8296             store_reg_bx(s, rd, tmp);
8297             break;
8298         case 0x0d:
8299             if (logic_cc && rd == 15) {
8300                 /* MOVS r15, ... is used for exception return.  */
8301                 if (IS_USER(s)) {
8302                     goto illegal_op;
8303                 }
8304                 gen_exception_return(s, tmp2);
8305             } else {
8306                 if (logic_cc) {
8307                     gen_logic_CC(s, tmp2);
8308                 }
8309                 store_reg_bx(s, rd, tmp2);
8310             }
8311             break;
8312         case 0x0e:
8313             tcg_gen_andc_i32(tcg_ctx, tmp, tmp, tmp2);
8314             if (logic_cc) {
8315                 gen_logic_CC(s, tmp);
8316             }
8317             store_reg_bx(s, rd, tmp);
8318             break;
8319         default:
8320         case 0x0f:
8321             tcg_gen_not_i32(tcg_ctx, tmp2, tmp2);
8322             if (logic_cc) {
8323                 gen_logic_CC(s, tmp2);
8324             }
8325             store_reg_bx(s, rd, tmp2);
8326             break;
8327         }
8328         if (op1 != 0x0f && op1 != 0x0d) {
8329             tcg_temp_free_i32(tcg_ctx, tmp2);
8330         }
8331     } else {
8332         /* other instructions */
8333         op1 = (insn >> 24) & 0xf;
8334         switch(op1) {
8335         case 0x0:
8336         case 0x1:
8337             /* multiplies, extra load/stores */
8338             sh = (insn >> 5) & 3;
8339             if (sh == 0) {
8340                 if (op1 == 0x0) {
8341                     rd = (insn >> 16) & 0xf;
8342                     rn = (insn >> 12) & 0xf;
8343                     rs = (insn >> 8) & 0xf;
8344                     rm = (insn) & 0xf;
8345                     op1 = (insn >> 20) & 0xf;
8346                     switch (op1) {
8347                     case 0: case 1: case 2: case 3: case 6:
8348                         /* 32 bit mul */
8349                         tmp = load_reg(s, rs);
8350                         tmp2 = load_reg(s, rm);
8351                         tcg_gen_mul_i32(tcg_ctx, tmp, tmp, tmp2);
8352                         tcg_temp_free_i32(tcg_ctx, tmp2);
8353                         if (insn & (1 << 22)) {
8354                             /* Subtract (mls) */
8355                             ARCH(6T2);
8356                             tmp2 = load_reg(s, rn);
8357                             tcg_gen_sub_i32(tcg_ctx, tmp, tmp2, tmp);
8358                             tcg_temp_free_i32(tcg_ctx, tmp2);
8359                         } else if (insn & (1 << 21)) {
8360                             /* Add */
8361                             tmp2 = load_reg(s, rn);
8362                             tcg_gen_add_i32(tcg_ctx, tmp, tmp, tmp2);
8363                             tcg_temp_free_i32(tcg_ctx, tmp2);
8364                         }
8365                         if (insn & (1 << 20))
8366                             gen_logic_CC(s, tmp);
8367                         store_reg(s, rd, tmp);
8368                         break;
8369                     case 4:
8370                         /* 64 bit mul double accumulate (UMAAL) */
8371                         ARCH(6);
8372                         tmp = load_reg(s, rs);
8373                         tmp2 = load_reg(s, rm);
8374                         tmp64 = gen_mulu_i64_i32(s, tmp, tmp2);
8375                         gen_addq_lo(s, tmp64, rn);
8376                         gen_addq_lo(s, tmp64, rd);
8377                         gen_storeq_reg(s, rn, rd, tmp64);
8378                         tcg_temp_free_i64(tcg_ctx, tmp64);
8379                         break;
8380                     case 8: case 9: case 10: case 11:
8381                     case 12: case 13: case 14: case 15:
8382                         /* 64 bit mul: UMULL, UMLAL, SMULL, SMLAL. */
8383                         tmp = load_reg(s, rs);
8384                         tmp2 = load_reg(s, rm);
8385                         if (insn & (1 << 22)) {
8386                             tcg_gen_muls2_i32(tcg_ctx, tmp, tmp2, tmp, tmp2);
8387                         } else {
8388                             tcg_gen_mulu2_i32(tcg_ctx, tmp, tmp2, tmp, tmp2);
8389                         }
8390                         if (insn & (1 << 21)) { /* mult accumulate */
8391                             TCGv_i32 al = load_reg(s, rn);
8392                             TCGv_i32 ah = load_reg(s, rd);
8393                             tcg_gen_add2_i32(tcg_ctx, tmp, tmp2, tmp, tmp2, al, ah);
8394                             tcg_temp_free_i32(tcg_ctx, al);
8395                             tcg_temp_free_i32(tcg_ctx, ah);
8396                         }
8397                         if (insn & (1 << 20)) {
8398                             gen_logicq_cc(s, tmp, tmp2);
8399                         }
8400                         store_reg(s, rn, tmp);
8401                         store_reg(s, rd, tmp2);
8402                         break;
8403                     default:
8404                         goto illegal_op;
8405                     }
8406                 } else {
8407                     rn = (insn >> 16) & 0xf;
8408                     rd = (insn >> 12) & 0xf;
8409                     if (insn & (1 << 23)) {
8410                         /* load/store exclusive */
8411                         int op2 = (insn >> 8) & 3;
8412                         op1 = (insn >> 21) & 0x3;
8413 
8414                         switch (op2) {
8415                         case 0: /* lda/stl */
8416                             if (op1 == 1) {
8417                                 goto illegal_op;
8418                             }
8419                             ARCH(8);
8420                             break;
8421                         case 1: /* reserved */
8422                             goto illegal_op;
8423                         case 2: /* ldaex/stlex */
8424                             ARCH(8);
8425                             break;
8426                         case 3: /* ldrex/strex */
8427                             if (op1) {
8428                                 ARCH(6K);
8429                             } else {
8430                                 ARCH(6);
8431                             }
8432                             break;
8433                         }
8434 
8435                         addr = tcg_temp_local_new_i32(tcg_ctx);
8436                         load_reg_var(s, addr, rn);
8437 
8438                         /* Since the emulation does not have barriers,
8439                            the acquire/release semantics need no special
8440                            handling */
8441                         if (op2 == 0) {
8442                             if (insn & (1 << 20)) {
8443                                 tmp = tcg_temp_new_i32(tcg_ctx);
8444                                 switch (op1) {
8445                                 case 0: /* lda */
8446                                     gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
8447                                     break;
8448                                 case 2: /* ldab */
8449                                     gen_aa32_ld8u(s, tmp, addr, get_mem_index(s));
8450                                     break;
8451                                 case 3: /* ldah */
8452                                     gen_aa32_ld16u(s, tmp, addr, get_mem_index(s));
8453                                     break;
8454                                 default:
8455                                     abort();
8456                                 }
8457                                 store_reg(s, rd, tmp);
8458                             } else {
8459                                 rm = insn & 0xf;
8460                                 tmp = load_reg(s, rm);
8461                                 switch (op1) {
8462                                 case 0: /* stl */
8463                                     gen_aa32_st32(s, tmp, addr, get_mem_index(s));
8464                                     break;
8465                                 case 2: /* stlb */
8466                                     gen_aa32_st8(s, tmp, addr, get_mem_index(s));
8467                                     break;
8468                                 case 3: /* stlh */
8469                                     gen_aa32_st16(s, tmp, addr, get_mem_index(s));
8470                                     break;
8471                                 default:
8472                                     abort();
8473                                 }
8474                                 tcg_temp_free_i32(tcg_ctx, tmp);
8475                             }
8476                         } else if (insn & (1 << 20)) {
8477                             switch (op1) {
8478                             case 0: /* ldrex */
8479                                 gen_load_exclusive(s, rd, 15, addr, 2);
8480                                 break;
8481                             case 1: /* ldrexd */
8482                                 gen_load_exclusive(s, rd, rd + 1, addr, 3);
8483                                 break;
8484                             case 2: /* ldrexb */
8485                                 gen_load_exclusive(s, rd, 15, addr, 0);
8486                                 break;
8487                             case 3: /* ldrexh */
8488                                 gen_load_exclusive(s, rd, 15, addr, 1);
8489                                 break;
8490                             default:
8491                                 abort();
8492                             }
8493                         } else {
8494                             rm = insn & 0xf;
8495                             switch (op1) {
8496                             case 0:  /*  strex */
8497                                 gen_store_exclusive(s, rd, rm, 15, addr, 2);
8498                                 break;
8499                             case 1: /*  strexd */
8500                                 gen_store_exclusive(s, rd, rm, rm + 1, addr, 3);
8501                                 break;
8502                             case 2: /*  strexb */
8503                                 gen_store_exclusive(s, rd, rm, 15, addr, 0);
8504                                 break;
8505                             case 3: /* strexh */
8506                                 gen_store_exclusive(s, rd, rm, 15, addr, 1);
8507                                 break;
8508                             default:
8509                                 abort();
8510                             }
8511                         }
8512                         tcg_temp_free_i32(tcg_ctx, addr);
8513                     } else {
8514                         /* SWP instruction */
8515                         rm = (insn) & 0xf;
8516 
8517                         /* ??? This is not really atomic.  However we know
8518                            we never have multiple CPUs running in parallel,
8519                            so it is good enough.  */
8520                         addr = load_reg(s, rn);
8521                         tmp = load_reg(s, rm);
8522                         tmp2 = tcg_temp_new_i32(tcg_ctx);
8523                         if (insn & (1 << 22)) {
8524                             gen_aa32_ld8u(s, tmp2, addr, get_mem_index(s));
8525                             gen_aa32_st8(s, tmp, addr, get_mem_index(s));
8526                         } else {
8527                             gen_aa32_ld32u(s, tmp2, addr, get_mem_index(s));
8528                             gen_aa32_st32(s, tmp, addr, get_mem_index(s));
8529                         }
8530                         tcg_temp_free_i32(tcg_ctx, tmp);
8531                         tcg_temp_free_i32(tcg_ctx, addr);
8532                         store_reg(s, rd, tmp2);
8533                     }
8534                 }
8535             } else {
8536                 int address_offset;
8537                 int load = insn & (1 << 20);
8538                 int wbit = insn & (1 << 21);
8539                 int pbit = insn & (1 << 24);
8540                 int doubleword = 0;
8541                 /* Misc load/store */
8542                 rn = (insn >> 16) & 0xf;
8543                 rd = (insn >> 12) & 0xf;
8544                 if (!load && (sh & 2)) {
8545                     /* doubleword */
8546                     ARCH(5TE);
8547                     if (rd & 1) {
8548                         /* UNPREDICTABLE; we choose to UNDEF */
8549                         goto illegal_op;
8550                     }
8551                     load = (sh & 1) == 0;
8552                     doubleword = 1;
8553                 }
8554                 addr = load_reg(s, rn);
8555                 if (pbit)
8556                     gen_add_datah_offset(s, insn, 0, addr);
8557                 address_offset = 0;
8558                 if (doubleword) {
8559                     if (!load) {
8560                         /* store */
8561                         tmp = load_reg(s, rd);
8562                         gen_aa32_st32(s, tmp, addr, get_mem_index(s));
8563                         tcg_temp_free_i32(tcg_ctx, tmp);
8564                         tcg_gen_addi_i32(tcg_ctx, addr, addr, 4);
8565                         tmp = load_reg(s, rd + 1);
8566                         gen_aa32_st32(s, tmp, addr, get_mem_index(s));
8567                         tcg_temp_free_i32(tcg_ctx, tmp);
8568                     } else {
8569                         /* load */
8570                         tmp = tcg_temp_new_i32(tcg_ctx);
8571                         gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
8572                         store_reg(s, rd, tmp);
8573                         tcg_gen_addi_i32(tcg_ctx, addr, addr, 4);
8574                         tmp = tcg_temp_new_i32(tcg_ctx);
8575                         gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
8576                         rd++;
8577                     }
8578                     address_offset = -4;
8579                 } else if (load) {
8580                     /* load */
8581                     tmp = tcg_temp_new_i32(tcg_ctx);
8582                     switch(sh) {
8583                     case 1:
8584                         gen_aa32_ld16u(s, tmp, addr, get_mem_index(s));
8585                         break;
8586                     case 2:
8587                         gen_aa32_ld8s(s, tmp, addr, get_mem_index(s));
8588                         break;
8589                         default:
8590                     case 3:
8591                         gen_aa32_ld16s(s, tmp, addr, get_mem_index(s));
8592                         break;
8593                     }
8594                 } else {
8595                     /* store */
8596                     tmp = load_reg(s, rd);
8597                     gen_aa32_st16(s, tmp, addr, get_mem_index(s));
8598                     tcg_temp_free_i32(tcg_ctx, tmp);
8599                 }
8600                 /* Perform base writeback before the loaded value to
8601                    ensure correct behavior with overlapping index registers.
8602                    ldrd with base writeback is is undefined if the
8603                    destination and index registers overlap.  */
8604                 if (!pbit) {
8605                     gen_add_datah_offset(s, insn, address_offset, addr);
8606                     store_reg(s, rn, addr);
8607                 } else if (wbit) {
8608                     if (address_offset)
8609                         tcg_gen_addi_i32(tcg_ctx, addr, addr, address_offset);
8610                     store_reg(s, rn, addr);
8611                 } else {
8612                     tcg_temp_free_i32(tcg_ctx, addr);
8613                 }
8614                 if (load) {
8615                     /* Complete the load.  */
8616                     store_reg(s, rd, tmp);
8617                 }
8618             }
8619             break;
8620         case 0x4:
8621         case 0x5:
8622             goto do_ldst;
8623         case 0x6:
8624         case 0x7:
8625             if (insn & (1 << 4)) {
8626                 ARCH(6);
8627                 /* Armv6 Media instructions.  */
8628                 rm = insn & 0xf;
8629                 rn = (insn >> 16) & 0xf;
8630                 rd = (insn >> 12) & 0xf;
8631                 rs = (insn >> 8) & 0xf;
8632                 switch ((insn >> 23) & 3) {
8633                 case 0: /* Parallel add/subtract.  */
8634                     op1 = (insn >> 20) & 7;
8635                     tmp = load_reg(s, rn);
8636                     tmp2 = load_reg(s, rm);
8637                     sh = (insn >> 5) & 7;
8638                     if ((op1 & 3) == 0 || sh == 5 || sh == 6)
8639                         goto illegal_op;
8640                     gen_arm_parallel_addsub(s, op1, sh, tmp, tmp2);
8641                     tcg_temp_free_i32(tcg_ctx, tmp2);
8642                     store_reg(s, rd, tmp);
8643                     break;
8644                 case 1:
8645                     if ((insn & 0x00700020) == 0) {
8646                         /* Halfword pack.  */
8647                         tmp = load_reg(s, rn);
8648                         tmp2 = load_reg(s, rm);
8649                         shift = (insn >> 7) & 0x1f;
8650                         if (insn & (1 << 6)) {
8651                             /* pkhtb */
8652                             if (shift == 0)
8653                                 shift = 31;
8654                             tcg_gen_sari_i32(tcg_ctx, tmp2, tmp2, shift);
8655                             tcg_gen_andi_i32(tcg_ctx, tmp, tmp, 0xffff0000);
8656                             tcg_gen_ext16u_i32(tcg_ctx, tmp2, tmp2);
8657                         } else {
8658                             /* pkhbt */
8659                             if (shift)
8660                                 tcg_gen_shli_i32(tcg_ctx, tmp2, tmp2, shift);
8661                             tcg_gen_ext16u_i32(tcg_ctx, tmp, tmp);
8662                             tcg_gen_andi_i32(tcg_ctx, tmp2, tmp2, 0xffff0000);
8663                         }
8664                         tcg_gen_or_i32(tcg_ctx, tmp, tmp, tmp2);
8665                         tcg_temp_free_i32(tcg_ctx, tmp2);
8666                         store_reg(s, rd, tmp);
8667                     } else if ((insn & 0x00200020) == 0x00200000) {
8668                         /* [us]sat */
8669                         tmp = load_reg(s, rm);
8670                         shift = (insn >> 7) & 0x1f;
8671                         if (insn & (1 << 6)) {
8672                             if (shift == 0)
8673                                 shift = 31;
8674                             tcg_gen_sari_i32(tcg_ctx, tmp, tmp, shift);
8675                         } else {
8676                             tcg_gen_shli_i32(tcg_ctx, tmp, tmp, shift);
8677                         }
8678                         sh = (insn >> 16) & 0x1f;
8679                         tmp2 = tcg_const_i32(tcg_ctx, sh);
8680                         if (insn & (1 << 22))
8681                           gen_helper_usat(tcg_ctx, tmp, tcg_ctx->cpu_env, tmp, tmp2);
8682                         else
8683                           gen_helper_ssat(tcg_ctx, tmp, tcg_ctx->cpu_env, tmp, tmp2);
8684                         tcg_temp_free_i32(tcg_ctx, tmp2);
8685                         store_reg(s, rd, tmp);
8686                     } else if ((insn & 0x00300fe0) == 0x00200f20) {
8687                         /* [us]sat16 */
8688                         tmp = load_reg(s, rm);
8689                         sh = (insn >> 16) & 0x1f;
8690                         tmp2 = tcg_const_i32(tcg_ctx, sh);
8691                         if (insn & (1 << 22))
8692                           gen_helper_usat16(tcg_ctx, tmp, tcg_ctx->cpu_env, tmp, tmp2);
8693                         else
8694                           gen_helper_ssat16(tcg_ctx, tmp, tcg_ctx->cpu_env, tmp, tmp2);
8695                         tcg_temp_free_i32(tcg_ctx, tmp2);
8696                         store_reg(s, rd, tmp);
8697                     } else if ((insn & 0x00700fe0) == 0x00000fa0) {
8698                         /* Select bytes.  */
8699                         tmp = load_reg(s, rn);
8700                         tmp2 = load_reg(s, rm);
8701                         tmp3 = tcg_temp_new_i32(tcg_ctx);
8702                         tcg_gen_ld_i32(tcg_ctx, tmp3, tcg_ctx->cpu_env, offsetof(CPUARMState, GE));
8703                         gen_helper_sel_flags(tcg_ctx, tmp, tmp3, tmp, tmp2);
8704                         tcg_temp_free_i32(tcg_ctx, tmp3);
8705                         tcg_temp_free_i32(tcg_ctx, tmp2);
8706                         store_reg(s, rd, tmp);
8707                     } else if ((insn & 0x000003e0) == 0x00000060) {
8708                         tmp = load_reg(s, rm);
8709                         shift = (insn >> 10) & 3;
8710                         /* ??? In many cases it's not necessary to do a
8711                            rotate, a shift is sufficient.  */
8712                         if (shift != 0)
8713                             tcg_gen_rotri_i32(tcg_ctx, tmp, tmp, shift * 8);
8714                         op1 = (insn >> 20) & 7;
8715                         switch (op1) {
8716                         case 0: gen_sxtb16(tmp);  break;
8717                         case 2: gen_sxtb(tmp);    break;
8718                         case 3: gen_sxth(tmp);    break;
8719                         case 4: gen_uxtb16(tmp);  break;
8720                         case 6: gen_uxtb(tmp);    break;
8721                         case 7: gen_uxth(tmp);    break;
8722                         default: goto illegal_op;
8723                         }
8724                         if (rn != 15) {
8725                             tmp2 = load_reg(s, rn);
8726                             if ((op1 & 3) == 0) {
8727                                 gen_add16(s, tmp, tmp2);
8728                             } else {
8729                                 tcg_gen_add_i32(tcg_ctx, tmp, tmp, tmp2);
8730                                 tcg_temp_free_i32(tcg_ctx, tmp2);
8731                             }
8732                         }
8733                         store_reg(s, rd, tmp);
8734                     } else if ((insn & 0x003f0f60) == 0x003f0f20) {
8735                         /* rev */
8736                         tmp = load_reg(s, rm);
8737                         if (insn & (1 << 22)) {
8738                             if (insn & (1 << 7)) {
8739                                 gen_revsh(s, tmp);
8740                             } else {
8741                                 ARCH(6T2);
8742                                 gen_helper_rbit(tcg_ctx, tmp, tmp);
8743                             }
8744                         } else {
8745                             if (insn & (1 << 7))
8746                                 gen_rev16(s, tmp);
8747                             else
8748                                 tcg_gen_bswap32_i32(tcg_ctx, tmp, tmp);
8749                         }
8750                         store_reg(s, rd, tmp);
8751                     } else {
8752                         goto illegal_op;
8753                     }
8754                     break;
8755                 case 2: /* Multiplies (Type 3).  */
8756                     switch ((insn >> 20) & 0x7) {
8757                     case 5:
8758                         if (((insn >> 6) ^ (insn >> 7)) & 1) {
8759                             /* op2 not 00x or 11x : UNDEF */
8760                             goto illegal_op;
8761                         }
8762                         /* Signed multiply most significant [accumulate].
8763                            (SMMUL, SMMLA, SMMLS) */
8764                         tmp = load_reg(s, rm);
8765                         tmp2 = load_reg(s, rs);
8766                         tmp64 = gen_muls_i64_i32(s, tmp, tmp2);
8767 
8768                         if (rd != 15) {
8769                             tmp = load_reg(s, rd);
8770                             if (insn & (1 << 6)) {
8771                                 tmp64 = gen_subq_msw(s, tmp64, tmp);
8772                             } else {
8773                                 tmp64 = gen_addq_msw(s, tmp64, tmp);
8774                             }
8775                         }
8776                         if (insn & (1 << 5)) {
8777                             tcg_gen_addi_i64(tcg_ctx, tmp64, tmp64, 0x80000000u);
8778                         }
8779                         tcg_gen_shri_i64(tcg_ctx, tmp64, tmp64, 32);
8780                         tmp = tcg_temp_new_i32(tcg_ctx);
8781                         tcg_gen_trunc_i64_i32(tcg_ctx, tmp, tmp64);
8782                         tcg_temp_free_i64(tcg_ctx, tmp64);
8783                         store_reg(s, rn, tmp);
8784                         break;
8785                     case 0:
8786                     case 4:
8787                         /* SMLAD, SMUAD, SMLSD, SMUSD, SMLALD, SMLSLD */
8788                         if (insn & (1 << 7)) {
8789                             goto illegal_op;
8790                         }
8791                         tmp = load_reg(s, rm);
8792                         tmp2 = load_reg(s, rs);
8793                         if (insn & (1 << 5))
8794                             gen_swap_half(s, tmp2);
8795                         gen_smul_dual(s, tmp, tmp2);
8796                         if (insn & (1 << 22)) {
8797                             /* smlald, smlsld */
8798                             TCGv_i64 tmp64_2;
8799 
8800                             tmp64 = tcg_temp_new_i64(tcg_ctx);
8801                             tmp64_2 = tcg_temp_new_i64(tcg_ctx);
8802                             tcg_gen_ext_i32_i64(tcg_ctx, tmp64, tmp);
8803                             tcg_gen_ext_i32_i64(tcg_ctx, tmp64_2, tmp2);
8804                             tcg_temp_free_i32(tcg_ctx, tmp);
8805                             tcg_temp_free_i32(tcg_ctx, tmp2);
8806                             if (insn & (1 << 6)) {
8807                                 tcg_gen_sub_i64(tcg_ctx, tmp64, tmp64, tmp64_2);
8808                             } else {
8809                                 tcg_gen_add_i64(tcg_ctx, tmp64, tmp64, tmp64_2);
8810                             }
8811                             tcg_temp_free_i64(tcg_ctx, tmp64_2);
8812                             gen_addq(s, tmp64, rd, rn);
8813                             gen_storeq_reg(s, rd, rn, tmp64);
8814                             tcg_temp_free_i64(tcg_ctx, tmp64);
8815                         } else {
8816                             /* smuad, smusd, smlad, smlsd */
8817                             if (insn & (1 << 6)) {
8818                                 /* This subtraction cannot overflow. */
8819                                 tcg_gen_sub_i32(tcg_ctx, tmp, tmp, tmp2);
8820                             } else {
8821                                 /* This addition cannot overflow 32 bits;
8822                                  * however it may overflow considered as a
8823                                  * signed operation, in which case we must set
8824                                  * the Q flag.
8825                                  */
8826                                 gen_helper_add_setq(tcg_ctx, tmp, tcg_ctx->cpu_env, tmp, tmp2);
8827                             }
8828                             tcg_temp_free_i32(tcg_ctx, tmp2);
8829                             if (rd != 15)
8830                               {
8831                                 tmp2 = load_reg(s, rd);
8832                                 gen_helper_add_setq(tcg_ctx, tmp, tcg_ctx->cpu_env, tmp, tmp2);
8833                                 tcg_temp_free_i32(tcg_ctx, tmp2);
8834                               }
8835                             store_reg(s, rn, tmp);
8836                         }
8837                         break;
8838                     case 1:
8839                     case 3:
8840                         /* SDIV, UDIV */
8841                         if (!arm_dc_feature(s, ARM_FEATURE_ARM_DIV)) {
8842                             goto illegal_op;
8843                         }
8844                         if (((insn >> 5) & 7) || (rd != 15)) {
8845                             goto illegal_op;
8846                         }
8847                         tmp = load_reg(s, rm);
8848                         tmp2 = load_reg(s, rs);
8849                         if (insn & (1 << 21)) {
8850                             gen_helper_udiv(tcg_ctx, tmp, tmp, tmp2);
8851                         } else {
8852                             gen_helper_sdiv(tcg_ctx, tmp, tmp, tmp2);
8853                         }
8854                         tcg_temp_free_i32(tcg_ctx, tmp2);
8855                         store_reg(s, rn, tmp);
8856                         break;
8857                     default:
8858                         goto illegal_op;
8859                     }
8860                     break;
8861                 case 3:
8862                     op1 = ((insn >> 17) & 0x38) | ((insn >> 5) & 7);
8863                     switch (op1) {
8864                     case 0: /* Unsigned sum of absolute differences.  */
8865                         ARCH(6);
8866                         tmp = load_reg(s, rm);
8867                         tmp2 = load_reg(s, rs);
8868                         gen_helper_usad8(tcg_ctx, tmp, tmp, tmp2);
8869                         tcg_temp_free_i32(tcg_ctx, tmp2);
8870                         if (rd != 15) {
8871                             tmp2 = load_reg(s, rd);
8872                             tcg_gen_add_i32(tcg_ctx, tmp, tmp, tmp2);
8873                             tcg_temp_free_i32(tcg_ctx, tmp2);
8874                         }
8875                         store_reg(s, rn, tmp);
8876                         break;
8877                     case 0x20: case 0x24: case 0x28: case 0x2c:
8878                         /* Bitfield insert/clear.  */
8879                         ARCH(6T2);
8880                         shift = (insn >> 7) & 0x1f;
8881                         i = (insn >> 16) & 0x1f;
8882                         i = i + 1 - shift;
8883                         if (rm == 15) {
8884                             tmp = tcg_temp_new_i32(tcg_ctx);
8885                             tcg_gen_movi_i32(tcg_ctx, tmp, 0);
8886                         } else {
8887                             tmp = load_reg(s, rm);
8888                         }
8889                         if (i != 32) {
8890                             tmp2 = load_reg(s, rd);
8891                             tcg_gen_deposit_i32(tcg_ctx, tmp, tmp2, tmp, shift, i);
8892                             tcg_temp_free_i32(tcg_ctx, tmp2);
8893                         }
8894                         store_reg(s, rd, tmp);
8895                         break;
8896                     case 0x12: case 0x16: case 0x1a: case 0x1e: /* sbfx */
8897                     case 0x32: case 0x36: case 0x3a: case 0x3e: /* ubfx */
8898                         ARCH(6T2);
8899                         tmp = load_reg(s, rm);
8900                         shift = (insn >> 7) & 0x1f;
8901                         i = ((insn >> 16) & 0x1f) + 1;
8902                         if (shift + i > 32)
8903                             goto illegal_op;
8904                         if (i < 32) {
8905                             if (op1 & 0x20) {
8906                                 gen_ubfx(s, tmp, shift, (1u << i) - 1);
8907                             } else {
8908                                 gen_sbfx(s, tmp, shift, i);
8909                             }
8910                         }
8911                         store_reg(s, rd, tmp);
8912                         break;
8913                     default:
8914                         goto illegal_op;
8915                     }
8916                     break;
8917                 }
8918                 break;
8919             }
8920         do_ldst:
8921             /* Check for undefined extension instructions
8922              * per the ARM Bible IE:
8923              * xxxx 0111 1111 xxxx  xxxx xxxx 1111 xxxx
8924              */
8925             sh = (0xf << 20) | (0xf << 4);
8926             if (op1 == 0x7 && ((insn & sh) == sh))
8927             {
8928                 goto illegal_op;
8929             }
8930             /* load/store byte/word */
8931             rn = (insn >> 16) & 0xf;
8932             rd = (insn >> 12) & 0xf;
8933             tmp2 = load_reg(s, rn);
8934             if ((insn & 0x01200000) == 0x00200000) {
8935                 /* ldrt/strt */
8936                 i = MMU_USER_IDX;
8937             } else {
8938                 i = get_mem_index(s);
8939             }
8940             if (insn & (1 << 24))
8941                 gen_add_data_offset(s, insn, tmp2);
8942             if (insn & (1 << 20)) {
8943                 /* load */
8944                 tmp = tcg_temp_new_i32(tcg_ctx);
8945                 if (insn & (1 << 22)) {
8946                     gen_aa32_ld8u(s, tmp, tmp2, i);
8947                 } else {
8948                     gen_aa32_ld32u(s, tmp, tmp2, i);
8949                 }
8950             } else {
8951                 /* store */
8952                 tmp = load_reg(s, rd);
8953                 if (insn & (1 << 22)) {
8954                     gen_aa32_st8(s, tmp, tmp2, i);
8955                 } else {
8956                     gen_aa32_st32(s, tmp, tmp2, i);
8957                 }
8958                 tcg_temp_free_i32(tcg_ctx, tmp);
8959             }
8960             if (!(insn & (1 << 24))) {
8961                 gen_add_data_offset(s, insn, tmp2);
8962                 store_reg(s, rn, tmp2);
8963             } else if (insn & (1 << 21)) {
8964                 store_reg(s, rn, tmp2);
8965             } else {
8966                 tcg_temp_free_i32(tcg_ctx, tmp2);
8967             }
8968             if (insn & (1 << 20)) {
8969                 /* Complete the load.  */
8970                 store_reg_from_load(s, rd, tmp);
8971             }
8972             break;
8973         case 0x08:
8974         case 0x09:
8975             {
8976                 int j, n, user, loaded_base;
8977                 TCGv_i32 loaded_var;
8978                 /* load/store multiple words */
8979                 /* XXX: store correct base if write back */
8980                 user = 0;
8981                 if (insn & (1 << 22)) {
8982                     if (IS_USER(s))
8983                         goto illegal_op; /* only usable in supervisor mode */
8984 
8985                     if ((insn & (1 << 15)) == 0)
8986                         user = 1;
8987                 }
8988                 rn = (insn >> 16) & 0xf;
8989                 addr = load_reg(s, rn);
8990 
8991                 /* compute total size */
8992                 loaded_base = 0;
8993                 TCGV_UNUSED_I32(loaded_var);
8994                 n = 0;
8995                 for(i=0;i<16;i++) {
8996                     if (insn & (1 << i))
8997                         n++;
8998                 }
8999                 /* XXX: test invalid n == 0 case ? */
9000                 if (insn & (1 << 23)) {
9001                     if (insn & (1 << 24)) {
9002                         /* pre increment */
9003                         tcg_gen_addi_i32(tcg_ctx, addr, addr, 4);
9004                     } else {
9005                         /* post increment */
9006                     }
9007                 } else {
9008                     if (insn & (1 << 24)) {
9009                         /* pre decrement */
9010                         tcg_gen_addi_i32(tcg_ctx, addr, addr, -(n * 4));
9011                     } else {
9012                         /* post decrement */
9013                         if (n != 1)
9014                         tcg_gen_addi_i32(tcg_ctx, addr, addr, -((n - 1) * 4));
9015                     }
9016                 }
9017                 j = 0;
9018                 for(i=0;i<16;i++) {
9019                     if (insn & (1 << i)) {
9020                         if (insn & (1 << 20)) {
9021                             /* load */
9022                             tmp = tcg_temp_new_i32(tcg_ctx);
9023                             gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
9024                             if (user) {
9025                                 tmp2 = tcg_const_i32(tcg_ctx, i);
9026                                 gen_helper_set_user_reg(tcg_ctx, tcg_ctx->cpu_env, tmp2, tmp);
9027                                 tcg_temp_free_i32(tcg_ctx, tmp2);
9028                                 tcg_temp_free_i32(tcg_ctx, tmp);
9029                             } else if (i == rn) {
9030                                 loaded_var = tmp;
9031                                 loaded_base = 1;
9032                             } else {
9033                                 store_reg_from_load(s, i, tmp);
9034                             }
9035                         } else {
9036                             /* store */
9037                             if (i == 15) {
9038                                 /* special case: r15 = PC + 8 */
9039                                 val = (long)s->pc + 4;
9040                                 tmp = tcg_temp_new_i32(tcg_ctx);
9041                                 tcg_gen_movi_i32(tcg_ctx, tmp, val);
9042                             } else if (user) {
9043                                 tmp = tcg_temp_new_i32(tcg_ctx);
9044                                 tmp2 = tcg_const_i32(tcg_ctx, i);
9045                                 gen_helper_get_user_reg(tcg_ctx, tmp, tcg_ctx->cpu_env, tmp2);
9046                                 tcg_temp_free_i32(tcg_ctx, tmp2);
9047                             } else {
9048                                 tmp = load_reg(s, i);
9049                             }
9050                             gen_aa32_st32(s, tmp, addr, get_mem_index(s));
9051                             tcg_temp_free_i32(tcg_ctx, tmp);
9052                         }
9053                         j++;
9054                         /* no need to add after the last transfer */
9055                         if (j != n)
9056                             tcg_gen_addi_i32(tcg_ctx, addr, addr, 4);
9057                     }
9058                 }
9059                 if (insn & (1 << 21)) {
9060                     /* write back */
9061                     if (insn & (1 << 23)) {
9062                         if (insn & (1 << 24)) {
9063                             /* pre increment */
9064                         } else {
9065                             /* post increment */
9066                             tcg_gen_addi_i32(tcg_ctx, addr, addr, 4);
9067                         }
9068                     } else {
9069                         if (insn & (1 << 24)) {
9070                             /* pre decrement */
9071                             if (n != 1)
9072                                 tcg_gen_addi_i32(tcg_ctx, addr, addr, -((n - 1) * 4));
9073                         } else {
9074                             /* post decrement */
9075                             tcg_gen_addi_i32(tcg_ctx, addr, addr, -(n * 4));
9076                         }
9077                     }
9078                     store_reg(s, rn, addr);
9079                 } else {
9080                     tcg_temp_free_i32(tcg_ctx, addr);
9081                 }
9082                 if (loaded_base) {
9083                     store_reg(s, rn, loaded_var);
9084                 }
9085                 if ((insn & (1 << 22)) && !user) {
9086                     /* Restore CPSR from SPSR.  */
9087                     tmp = load_cpu_field(s->uc, spsr);
9088                     gen_set_cpsr(s, tmp, CPSR_ERET_MASK);
9089                     tcg_temp_free_i32(tcg_ctx, tmp);
9090                     s->is_jmp = DISAS_UPDATE;
9091                 }
9092             }
9093             break;
9094         case 0xa:
9095         case 0xb:
9096             {
9097                 int32_t offset;
9098 
9099                 /* branch (and link) */
9100                 val = (int32_t)s->pc;
9101                 if (insn & (1 << 24)) {
9102                     tmp = tcg_temp_new_i32(tcg_ctx);
9103                     tcg_gen_movi_i32(tcg_ctx, tmp, val);
9104                     store_reg(s, 14, tmp);
9105                 }
9106                 offset = sextract32(insn << 2, 0, 26);
9107                 val += offset + 4;
9108                 gen_jmp(s, val);
9109             }
9110             break;
9111         case 0xc:
9112         case 0xd:
9113         case 0xe:
9114             if (((insn >> 8) & 0xe) == 10) {
9115                 /* VFP.  */
9116                 if (disas_vfp_insn(s, insn)) {
9117                     goto illegal_op;
9118                 }
9119             } else if (disas_coproc_insn(s, insn)) {
9120                 /* Coprocessor.  */
9121                 goto illegal_op;
9122             }
9123             break;
9124         case 0xf:   // qq
9125             /* swi */
9126             gen_set_pc_im(s, s->pc);
9127             s->svc_imm = extract32(insn, 0, 24);
9128             s->is_jmp = DISAS_SWI;
9129             break;
9130         default:
9131         illegal_op:
9132             gen_exception_insn(s, 4, EXCP_UDEF, syn_uncategorized());
9133             break;
9134         }
9135     }
9136 }
9137 
9138 /* Return true if this is a Thumb-2 logical op.  */
9139 static int
thumb2_logic_op(int op)9140 thumb2_logic_op(int op)
9141 {
9142     return (op < 8);
9143 }
9144 
9145 /* Generate code for a Thumb-2 data processing operation.  If CONDS is nonzero
9146    then set condition code flags based on the result of the operation.
9147    If SHIFTER_OUT is nonzero then set the carry flag for logical operations
9148    to the high bit of T1.
9149    Returns zero if the opcode is valid.  */
9150 
9151 static int
gen_thumb2_data_op(DisasContext * s,int op,int conds,uint32_t shifter_out,TCGv_i32 t0,TCGv_i32 t1)9152 gen_thumb2_data_op(DisasContext *s, int op, int conds, uint32_t shifter_out,
9153                    TCGv_i32 t0, TCGv_i32 t1)
9154 {
9155     TCGContext *tcg_ctx = s->uc->tcg_ctx;
9156     int logic_cc;
9157 
9158     logic_cc = 0;
9159     switch (op) {
9160     case 0: /* and */
9161         tcg_gen_and_i32(tcg_ctx, t0, t0, t1);
9162         logic_cc = conds;
9163         break;
9164     case 1: /* bic */
9165         tcg_gen_andc_i32(tcg_ctx, t0, t0, t1);
9166         logic_cc = conds;
9167         break;
9168     case 2: /* orr */
9169         tcg_gen_or_i32(tcg_ctx, t0, t0, t1);
9170         logic_cc = conds;
9171         break;
9172     case 3: /* orn */
9173         tcg_gen_orc_i32(tcg_ctx, t0, t0, t1);
9174         logic_cc = conds;
9175         break;
9176     case 4: /* eor */
9177         tcg_gen_xor_i32(tcg_ctx, t0, t0, t1);
9178         logic_cc = conds;
9179         break;
9180     case 8: /* add */
9181         if (conds)
9182             gen_add_CC(s, t0, t0, t1);
9183         else
9184             tcg_gen_add_i32(tcg_ctx, t0, t0, t1);
9185         break;
9186     case 10: /* adc */
9187         if (conds)
9188             gen_adc_CC(s, t0, t0, t1);
9189         else
9190             gen_adc(s, t0, t1);
9191         break;
9192     case 11: /* sbc */
9193         if (conds) {
9194             gen_sbc_CC(s, t0, t0, t1);
9195         } else {
9196             gen_sub_carry(s, t0, t0, t1);
9197         }
9198         break;
9199     case 13: /* sub */
9200         if (conds)
9201             gen_sub_CC(s, t0, t0, t1);
9202         else
9203             tcg_gen_sub_i32(tcg_ctx, t0, t0, t1);
9204         break;
9205     case 14: /* rsb */
9206         if (conds)
9207             gen_sub_CC(s, t0, t1, t0);
9208         else
9209             tcg_gen_sub_i32(tcg_ctx, t0, t1, t0);
9210         break;
9211     default: /* 5, 6, 7, 9, 12, 15. */
9212         return 1;
9213     }
9214     if (logic_cc) {
9215         gen_logic_CC(s, t0);
9216         if (shifter_out)
9217             gen_set_CF_bit31(s, t1);
9218     }
9219     return 0;
9220 }
9221 
9222 /* Translate a 32-bit thumb instruction.  Returns nonzero if the instruction
9223    is not legal.  */
disas_thumb2_insn(CPUARMState * env,DisasContext * s,uint16_t insn_hw1)9224 static int disas_thumb2_insn(CPUARMState *env, DisasContext *s, uint16_t insn_hw1)
9225 {
9226     TCGContext *tcg_ctx = s->uc->tcg_ctx;
9227     uint32_t insn, imm, shift, offset;
9228     uint32_t rd, rn, rm, rs;
9229     TCGv_i32 tmp;
9230     TCGv_i32 tmp2;
9231     TCGv_i32 tmp3;
9232     TCGv_i32 addr;
9233     TCGv_i64 tmp64;
9234     int op;
9235     int shiftop;
9236     int conds;
9237     int logic_cc;
9238 
9239     if (!(arm_dc_feature(s, ARM_FEATURE_THUMB2)
9240           || arm_dc_feature(s, ARM_FEATURE_M))) {
9241         /* Thumb-1 cores may need to treat bl and blx as a pair of
9242            16-bit instructions to get correct prefetch abort behavior.  */
9243         insn = insn_hw1;
9244         if ((insn & (1 << 12)) == 0) {
9245             ARCH(5);
9246             /* Second half of blx.  */
9247             offset = ((insn & 0x7ff) << 1);
9248             tmp = load_reg(s, 14);
9249             tcg_gen_addi_i32(tcg_ctx, tmp, tmp, offset);
9250             tcg_gen_andi_i32(tcg_ctx, tmp, tmp, 0xfffffffc);
9251 
9252             tmp2 = tcg_temp_new_i32(tcg_ctx);
9253             tcg_gen_movi_i32(tcg_ctx, tmp2, s->pc | 1);
9254             store_reg(s, 14, tmp2);
9255             gen_bx(s, tmp);
9256             return 0;
9257         }
9258         if (insn & (1 << 11)) {
9259             /* Second half of bl.  */
9260             offset = ((insn & 0x7ff) << 1) | 1;
9261             tmp = load_reg(s, 14);
9262             tcg_gen_addi_i32(tcg_ctx, tmp, tmp, offset);
9263 
9264             tmp2 = tcg_temp_new_i32(tcg_ctx);
9265             tcg_gen_movi_i32(tcg_ctx, tmp2, s->pc | 1);
9266             store_reg(s, 14, tmp2);
9267             gen_bx(s, tmp);
9268             return 0;
9269         }
9270         if ((s->pc & ~TARGET_PAGE_MASK) == 0) {
9271             /* Instruction spans a page boundary.  Implement it as two
9272                16-bit instructions in case the second half causes an
9273                prefetch abort.  */
9274             offset = ((int32_t)insn << 21) >> 9;
9275             tcg_gen_movi_i32(tcg_ctx, tcg_ctx->cpu_R[14], s->pc + 2 + offset);
9276             return 0;
9277         }
9278         /* Fall through to 32-bit decode.  */
9279     }
9280 
9281     insn = arm_lduw_code(env, s->pc, s->bswap_code);
9282     s->pc += 2;
9283     insn |= (uint32_t)insn_hw1 << 16;
9284 
9285     if ((insn & 0xf800e800) != 0xf000e800) {
9286         ARCH(6T2);
9287     }
9288 
9289     rn = (insn >> 16) & 0xf;
9290     rs = (insn >> 12) & 0xf;
9291     rd = (insn >> 8) & 0xf;
9292     rm = insn & 0xf;
9293     switch ((insn >> 25) & 0xf) {
9294     case 0: case 1: case 2: case 3:
9295         /* 16-bit instructions.  Should never happen.  */
9296         abort();
9297     case 4:
9298         if (insn & (1 << 22)) {
9299             /* Other load/store, table branch.  */
9300             if (insn & 0x01200000) {
9301                 /* Load/store doubleword.  */
9302                 if (rn == 15) {
9303                     addr = tcg_temp_new_i32(tcg_ctx);
9304                     tcg_gen_movi_i32(tcg_ctx, addr, s->pc & ~3);
9305                 } else {
9306                     addr = load_reg(s, rn);
9307                 }
9308                 offset = (insn & 0xff) * 4;
9309                 if ((insn & (1 << 23)) == 0)
9310                     offset = 0-offset;
9311                 if (insn & (1 << 24)) {
9312                     tcg_gen_addi_i32(tcg_ctx, addr, addr, offset);
9313                     offset = 0;
9314                 }
9315                 if (insn & (1 << 20)) {
9316                     /* ldrd */
9317                     tmp = tcg_temp_new_i32(tcg_ctx);
9318                     gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
9319                     store_reg(s, rs, tmp);
9320                     tcg_gen_addi_i32(tcg_ctx, addr, addr, 4);
9321                     tmp = tcg_temp_new_i32(tcg_ctx);
9322                     gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
9323                     store_reg(s, rd, tmp);
9324                 } else {
9325                     /* strd */
9326                     tmp = load_reg(s, rs);
9327                     gen_aa32_st32(s, tmp, addr, get_mem_index(s));
9328                     tcg_temp_free_i32(tcg_ctx, tmp);
9329                     tcg_gen_addi_i32(tcg_ctx, addr, addr, 4);
9330                     tmp = load_reg(s, rd);
9331                     gen_aa32_st32(s, tmp, addr, get_mem_index(s));
9332                     tcg_temp_free_i32(tcg_ctx, tmp);
9333                 }
9334                 if (insn & (1 << 21)) {
9335                     /* Base writeback.  */
9336                     if (rn == 15)
9337                         goto illegal_op;
9338                     tcg_gen_addi_i32(tcg_ctx, addr, addr, offset - 4);
9339                     store_reg(s, rn, addr);
9340                 } else {
9341                     tcg_temp_free_i32(tcg_ctx, addr);
9342                 }
9343             } else if ((insn & (1 << 23)) == 0) {
9344                 /* Load/store exclusive word.  */
9345                 addr = tcg_temp_local_new_i32(tcg_ctx);
9346                 load_reg_var(s, addr, rn);
9347                 tcg_gen_addi_i32(tcg_ctx, addr, addr, (insn & 0xff) << 2);
9348                 if (insn & (1 << 20)) {
9349                     gen_load_exclusive(s, rs, 15, addr, 2);
9350                 } else {
9351                     gen_store_exclusive(s, rd, rs, 15, addr, 2);
9352                 }
9353                 tcg_temp_free_i32(tcg_ctx, addr);
9354             } else if ((insn & (7 << 5)) == 0) {
9355                 /* Table Branch.  */
9356                 if (rn == 15) {
9357                     addr = tcg_temp_new_i32(tcg_ctx);
9358                     tcg_gen_movi_i32(tcg_ctx, addr, s->pc);
9359                 } else {
9360                     addr = load_reg(s, rn);
9361                 }
9362                 tmp = load_reg(s, rm);
9363                 tcg_gen_add_i32(tcg_ctx, addr, addr, tmp);
9364                 if (insn & (1 << 4)) {
9365                     /* tbh */
9366                     tcg_gen_add_i32(tcg_ctx, addr, addr, tmp);
9367                     tcg_temp_free_i32(tcg_ctx, tmp);
9368                     tmp = tcg_temp_new_i32(tcg_ctx);
9369                     gen_aa32_ld16u(s, tmp, addr, get_mem_index(s));
9370                 } else { /* tbb */
9371                     tcg_temp_free_i32(tcg_ctx, tmp);
9372                     tmp = tcg_temp_new_i32(tcg_ctx);
9373                     gen_aa32_ld8u(s, tmp, addr, get_mem_index(s));
9374                 }
9375                 tcg_temp_free_i32(tcg_ctx, addr);
9376                 tcg_gen_shli_i32(tcg_ctx, tmp, tmp, 1);
9377                 tcg_gen_addi_i32(tcg_ctx, tmp, tmp, s->pc);
9378                 store_reg(s, 15, tmp);
9379             } else {
9380                 int op2 = (insn >> 6) & 0x3;
9381                 op = (insn >> 4) & 0x3;
9382                 switch (op2) {
9383                 case 0:
9384                     goto illegal_op;
9385                 case 1:
9386                     /* Load/store exclusive byte/halfword/doubleword */
9387                     if (op == 2) {
9388                         goto illegal_op;
9389                     }
9390                     ARCH(7);
9391                     break;
9392                 case 2:
9393                     /* Load-acquire/store-release */
9394                     if (op == 3) {
9395                         goto illegal_op;
9396                     }
9397                     /* Fall through */
9398                 case 3:
9399                     /* Load-acquire/store-release exclusive */
9400                     ARCH(8);
9401                     break;
9402                 }
9403                 addr = tcg_temp_local_new_i32(tcg_ctx);
9404                 load_reg_var(s, addr, rn);
9405                 if (!(op2 & 1)) {
9406                     if (insn & (1 << 20)) {
9407                         tmp = tcg_temp_new_i32(tcg_ctx);
9408                         switch (op) {
9409                         case 0: /* ldab */
9410                             gen_aa32_ld8u(s, tmp, addr, get_mem_index(s));
9411                             break;
9412                         case 1: /* ldah */
9413                             gen_aa32_ld16u(s, tmp, addr, get_mem_index(s));
9414                             break;
9415                         case 2: /* lda */
9416                             gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
9417                             break;
9418                         default:
9419                             abort();
9420                         }
9421                         store_reg(s, rs, tmp);
9422                     } else {
9423                         tmp = load_reg(s, rs);
9424                         switch (op) {
9425                         case 0: /* stlb */
9426                             gen_aa32_st8(s, tmp, addr, get_mem_index(s));
9427                             break;
9428                         case 1: /* stlh */
9429                             gen_aa32_st16(s, tmp, addr, get_mem_index(s));
9430                             break;
9431                         case 2: /* stl */
9432                             gen_aa32_st32(s, tmp, addr, get_mem_index(s));
9433                             break;
9434                         default:
9435                             abort();
9436                         }
9437                         tcg_temp_free_i32(tcg_ctx, tmp);
9438                     }
9439                 } else if (insn & (1 << 20)) {
9440                     gen_load_exclusive(s, rs, rd, addr, op);
9441                 } else {
9442                     gen_store_exclusive(s, rm, rs, rd, addr, op);
9443                 }
9444                 tcg_temp_free_i32(tcg_ctx, addr);
9445             }
9446         } else {
9447             /* Load/store multiple, RFE, SRS.  */
9448             if (((insn >> 23) & 1) == ((insn >> 24) & 1)) {
9449                 /* RFE, SRS: not available in user mode or on M profile */
9450                 if (IS_USER(s) || arm_dc_feature(s, ARM_FEATURE_M)) {
9451                     goto illegal_op;
9452                 }
9453                 if (insn & (1 << 20)) {
9454                     /* rfe */
9455                     addr = load_reg(s, rn);
9456                     if ((insn & (1 << 24)) == 0)
9457                         tcg_gen_addi_i32(tcg_ctx, addr, addr, -8);
9458                     /* Load PC into tmp and CPSR into tmp2.  */
9459                     tmp = tcg_temp_new_i32(tcg_ctx);
9460                     gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
9461                     tcg_gen_addi_i32(tcg_ctx, addr, addr, 4);
9462                     tmp2 = tcg_temp_new_i32(tcg_ctx);
9463                     gen_aa32_ld32u(s, tmp2, addr, get_mem_index(s));
9464                     if (insn & (1 << 21)) {
9465                         /* Base writeback.  */
9466                         if (insn & (1 << 24)) {
9467                             tcg_gen_addi_i32(tcg_ctx, addr, addr, 4);
9468                         } else {
9469                             tcg_gen_addi_i32(tcg_ctx, addr, addr, -4);
9470                         }
9471                         store_reg(s, rn, addr);
9472                     } else {
9473                         tcg_temp_free_i32(tcg_ctx, addr);
9474                     }
9475                     gen_rfe(s, tmp, tmp2);
9476                 } else {
9477                     /* srs */
9478                     gen_srs(s, (insn & 0x1f), (insn & (1 << 24)) ? 1 : 2,
9479                             insn & (1 << 21));
9480                 }
9481             } else {
9482                 int i, loaded_base = 0;
9483                 TCGv_i32 loaded_var;
9484                 /* Load/store multiple.  */
9485                 addr = load_reg(s, rn);
9486                 offset = 0;
9487                 for (i = 0; i < 16; i++) {
9488                     if (insn & (1 << i))
9489                         offset += 4;
9490                 }
9491                 if (insn & (1 << 24)) {
9492                     tcg_gen_addi_i32(tcg_ctx, addr, addr, 0-offset);
9493                 }
9494 
9495                 TCGV_UNUSED_I32(loaded_var);
9496                 for (i = 0; i < 16; i++) {
9497                     if ((insn & (1 << i)) == 0)
9498                         continue;
9499                     if (insn & (1 << 20)) {
9500                         /* Load.  */
9501                         tmp = tcg_temp_new_i32(tcg_ctx);
9502                         gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
9503                         if (i == 15) {
9504                             gen_bx(s, tmp);
9505                         } else if (i == rn) {
9506                             loaded_var = tmp;
9507                             loaded_base = 1;
9508                         } else {
9509                             store_reg(s, i, tmp);
9510                         }
9511                     } else {
9512                         /* Store.  */
9513                         tmp = load_reg(s, i);
9514                         gen_aa32_st32(s, tmp, addr, get_mem_index(s));
9515                         tcg_temp_free_i32(tcg_ctx, tmp);
9516                     }
9517                     tcg_gen_addi_i32(tcg_ctx, addr, addr, 4);
9518                 }
9519                 if (loaded_base) {
9520                     store_reg(s, rn, loaded_var);
9521                 }
9522                 if (insn & (1 << 21)) {
9523                     /* Base register writeback.  */
9524                     if (insn & (1 << 24)) {
9525                         tcg_gen_addi_i32(tcg_ctx, addr, addr, 0-offset);
9526                     }
9527                     /* Fault if writeback register is in register list.  */
9528                     if (insn & (1 << rn))
9529                         goto illegal_op;
9530                     store_reg(s, rn, addr);
9531                 } else {
9532                     tcg_temp_free_i32(tcg_ctx, addr);
9533                 }
9534             }
9535         }
9536         break;
9537     case 5:
9538 
9539         op = (insn >> 21) & 0xf;
9540         if (op == 6) {
9541             /* Halfword pack.  */
9542             tmp = load_reg(s, rn);
9543             tmp2 = load_reg(s, rm);
9544             shift = ((insn >> 10) & 0x1c) | ((insn >> 6) & 0x3);
9545             if (insn & (1 << 5)) {
9546                 /* pkhtb */
9547                 if (shift == 0)
9548                     shift = 31;
9549                 tcg_gen_sari_i32(tcg_ctx, tmp2, tmp2, shift);
9550                 tcg_gen_andi_i32(tcg_ctx, tmp, tmp, 0xffff0000);
9551                 tcg_gen_ext16u_i32(tcg_ctx, tmp2, tmp2);
9552             } else {
9553                 /* pkhbt */
9554                 if (shift)
9555                     tcg_gen_shli_i32(tcg_ctx, tmp2, tmp2, shift);
9556                 tcg_gen_ext16u_i32(tcg_ctx, tmp, tmp);
9557                 tcg_gen_andi_i32(tcg_ctx, tmp2, tmp2, 0xffff0000);
9558             }
9559             tcg_gen_or_i32(tcg_ctx, tmp, tmp, tmp2);
9560             tcg_temp_free_i32(tcg_ctx, tmp2);
9561             store_reg(s, rd, tmp);
9562         } else {
9563             /* Data processing register constant shift.  */
9564             if (rn == 15) {
9565                 tmp = tcg_temp_new_i32(tcg_ctx);
9566                 tcg_gen_movi_i32(tcg_ctx, tmp, 0);
9567             } else {
9568                 tmp = load_reg(s, rn);
9569             }
9570             tmp2 = load_reg(s, rm);
9571 
9572             shiftop = (insn >> 4) & 3;
9573             shift = ((insn >> 6) & 3) | ((insn >> 10) & 0x1c);
9574             conds = (insn & (1 << 20)) != 0;
9575             logic_cc = (conds && thumb2_logic_op(op));
9576             gen_arm_shift_im(s, tmp2, shiftop, shift, logic_cc);
9577             if (gen_thumb2_data_op(s, op, conds, 0, tmp, tmp2))
9578                 goto illegal_op;
9579             tcg_temp_free_i32(tcg_ctx, tmp2);
9580             if (rd != 15) {
9581                 store_reg(s, rd, tmp);
9582             } else {
9583                 tcg_temp_free_i32(tcg_ctx, tmp);
9584             }
9585         }
9586         break;
9587     case 13: /* Misc data processing.  */
9588         op = ((insn >> 22) & 6) | ((insn >> 7) & 1);
9589         if (op < 4 && (insn & 0xf000) != 0xf000)
9590             goto illegal_op;
9591         switch (op) {
9592         case 0: /* Register controlled shift.  */
9593             tmp = load_reg(s, rn);
9594             tmp2 = load_reg(s, rm);
9595             if ((insn & 0x70) != 0)
9596                 goto illegal_op;
9597             op = (insn >> 21) & 3;
9598             logic_cc = (insn & (1 << 20)) != 0;
9599             gen_arm_shift_reg(s, tmp, op, tmp2, logic_cc);
9600             if (logic_cc)
9601                 gen_logic_CC(s, tmp);
9602             store_reg_bx(s, rd, tmp);
9603             break;
9604         case 1: /* Sign/zero extend.  */
9605             tmp = load_reg(s, rm);
9606             shift = (insn >> 4) & 3;
9607             /* ??? In many cases it's not necessary to do a
9608                rotate, a shift is sufficient.  */
9609             if (shift != 0)
9610                 tcg_gen_rotri_i32(tcg_ctx, tmp, tmp, shift * 8);
9611             op = (insn >> 20) & 7;
9612             switch (op) {
9613             case 0: gen_sxth(tmp);   break;
9614             case 1: gen_uxth(tmp);   break;
9615             case 2: gen_sxtb16(tmp); break;
9616             case 3: gen_uxtb16(tmp); break;
9617             case 4: gen_sxtb(tmp);   break;
9618             case 5: gen_uxtb(tmp);   break;
9619             default: goto illegal_op;
9620             }
9621             if (rn != 15) {
9622                 tmp2 = load_reg(s, rn);
9623                 if ((op >> 1) == 1) {
9624                     gen_add16(s, tmp, tmp2);
9625                 } else {
9626                     tcg_gen_add_i32(tcg_ctx, tmp, tmp, tmp2);
9627                     tcg_temp_free_i32(tcg_ctx, tmp2);
9628                 }
9629             }
9630             store_reg(s, rd, tmp);
9631             break;
9632         case 2: /* SIMD add/subtract.  */
9633             op = (insn >> 20) & 7;
9634             shift = (insn >> 4) & 7;
9635             if ((op & 3) == 3 || (shift & 3) == 3)
9636                 goto illegal_op;
9637             tmp = load_reg(s, rn);
9638             tmp2 = load_reg(s, rm);
9639             gen_thumb2_parallel_addsub(s, op, shift, tmp, tmp2);
9640             tcg_temp_free_i32(tcg_ctx, tmp2);
9641             store_reg(s, rd, tmp);
9642             break;
9643         case 3: /* Other data processing.  */
9644             op = ((insn >> 17) & 0x38) | ((insn >> 4) & 7);
9645             if (op < 4) {
9646                 /* Saturating add/subtract.  */
9647                 tmp = load_reg(s, rn);
9648                 tmp2 = load_reg(s, rm);
9649                 if (op & 1)
9650                     gen_helper_double_saturate(tcg_ctx, tmp, tcg_ctx->cpu_env, tmp);
9651                 if (op & 2)
9652                     gen_helper_sub_saturate(tcg_ctx, tmp, tcg_ctx->cpu_env, tmp2, tmp);
9653                 else
9654                     gen_helper_add_saturate(tcg_ctx, tmp, tcg_ctx->cpu_env, tmp, tmp2);
9655                 tcg_temp_free_i32(tcg_ctx, tmp2);
9656             } else {
9657                 tmp = load_reg(s, rn);
9658                 switch (op) {
9659                 case 0x0a: /* rbit */
9660                     gen_helper_rbit(tcg_ctx, tmp, tmp);
9661                     break;
9662                 case 0x08: /* rev */
9663                     tcg_gen_bswap32_i32(tcg_ctx, tmp, tmp);
9664                     break;
9665                 case 0x09: /* rev16 */
9666                     gen_rev16(s, tmp);
9667                     break;
9668                 case 0x0b: /* revsh */
9669                     gen_revsh(s, tmp);
9670                     break;
9671                 case 0x10: /* sel */
9672                     tmp2 = load_reg(s, rm);
9673                     tmp3 = tcg_temp_new_i32(tcg_ctx);
9674                     tcg_gen_ld_i32(tcg_ctx, tmp3, tcg_ctx->cpu_env, offsetof(CPUARMState, GE));
9675                     gen_helper_sel_flags(tcg_ctx, tmp, tmp3, tmp, tmp2);
9676                     tcg_temp_free_i32(tcg_ctx, tmp3);
9677                     tcg_temp_free_i32(tcg_ctx, tmp2);
9678                     break;
9679                 case 0x18: /* clz */
9680                     gen_helper_clz(tcg_ctx, tmp, tmp);
9681                     break;
9682                 case 0x20:
9683                 case 0x21:
9684                 case 0x22:
9685                 case 0x28:
9686                 case 0x29:
9687                 case 0x2a:
9688                 {
9689                     /* crc32/crc32c */
9690                     uint32_t sz = op & 0x3;
9691                     uint32_t c = op & 0x8;
9692 
9693                     if (!arm_dc_feature(s, ARM_FEATURE_CRC)) {
9694                         goto illegal_op;
9695                     }
9696 
9697                     tmp2 = load_reg(s, rm);
9698                     if (sz == 0) {
9699                         tcg_gen_andi_i32(tcg_ctx, tmp2, tmp2, 0xff);
9700                     } else if (sz == 1) {
9701                         tcg_gen_andi_i32(tcg_ctx, tmp2, tmp2, 0xffff);
9702                     }
9703                     tmp3 = tcg_const_i32(tcg_ctx, 1 << sz);
9704                     if (c) {
9705                         gen_helper_crc32c(tcg_ctx, tmp, tmp, tmp2, tmp3);
9706                     } else {
9707                         gen_helper_crc32(tcg_ctx, tmp, tmp, tmp2, tmp3);
9708                     }
9709                     tcg_temp_free_i32(tcg_ctx, tmp2);
9710                     tcg_temp_free_i32(tcg_ctx, tmp3);
9711                     break;
9712                 }
9713                 default:
9714                     goto illegal_op;
9715                 }
9716             }
9717             store_reg(s, rd, tmp);
9718             break;
9719         case 4: case 5: /* 32-bit multiply.  Sum of absolute differences.  */
9720             op = (insn >> 4) & 0xf;
9721             tmp = load_reg(s, rn);
9722             tmp2 = load_reg(s, rm);
9723             switch ((insn >> 20) & 7) {
9724             case 0: /* 32 x 32 -> 32 */
9725                 tcg_gen_mul_i32(tcg_ctx, tmp, tmp, tmp2);
9726                 tcg_temp_free_i32(tcg_ctx, tmp2);
9727                 if (rs != 15) {
9728                     tmp2 = load_reg(s, rs);
9729                     if (op)
9730                         tcg_gen_sub_i32(tcg_ctx, tmp, tmp2, tmp);
9731                     else
9732                         tcg_gen_add_i32(tcg_ctx, tmp, tmp, tmp2);
9733                     tcg_temp_free_i32(tcg_ctx, tmp2);
9734                 }
9735                 break;
9736             case 1: /* 16 x 16 -> 32 */
9737                 gen_mulxy(s, tmp, tmp2, op & 2, op & 1);
9738                 tcg_temp_free_i32(tcg_ctx, tmp2);
9739                 if (rs != 15) {
9740                     tmp2 = load_reg(s, rs);
9741                     gen_helper_add_setq(tcg_ctx, tmp, tcg_ctx->cpu_env, tmp, tmp2);
9742                     tcg_temp_free_i32(tcg_ctx, tmp2);
9743                 }
9744                 break;
9745             case 2: /* Dual multiply add.  */
9746             case 4: /* Dual multiply subtract.  */
9747                 if (op)
9748                     gen_swap_half(s, tmp2);
9749                 gen_smul_dual(s, tmp, tmp2);
9750                 if (insn & (1 << 22)) {
9751                     /* This subtraction cannot overflow. */
9752                     tcg_gen_sub_i32(tcg_ctx, tmp, tmp, tmp2);
9753                 } else {
9754                     /* This addition cannot overflow 32 bits;
9755                      * however it may overflow considered as a signed
9756                      * operation, in which case we must set the Q flag.
9757                      */
9758                     gen_helper_add_setq(tcg_ctx, tmp, tcg_ctx->cpu_env, tmp, tmp2);
9759                 }
9760                 tcg_temp_free_i32(tcg_ctx, tmp2);
9761                 if (rs != 15)
9762                   {
9763                     tmp2 = load_reg(s, rs);
9764                     gen_helper_add_setq(tcg_ctx, tmp, tcg_ctx->cpu_env, tmp, tmp2);
9765                     tcg_temp_free_i32(tcg_ctx, tmp2);
9766                   }
9767                 break;
9768             case 3: /* 32 * 16 -> 32msb */
9769                 if (op)
9770                     tcg_gen_sari_i32(tcg_ctx, tmp2, tmp2, 16);
9771                 else
9772                     gen_sxth(tmp2);
9773                 tmp64 = gen_muls_i64_i32(s, tmp, tmp2);
9774                 tcg_gen_shri_i64(tcg_ctx, tmp64, tmp64, 16);
9775                 tmp = tcg_temp_new_i32(tcg_ctx);
9776                 tcg_gen_trunc_i64_i32(tcg_ctx, tmp, tmp64);
9777                 tcg_temp_free_i64(tcg_ctx, tmp64);
9778                 if (rs != 15)
9779                   {
9780                     tmp2 = load_reg(s, rs);
9781                     gen_helper_add_setq(tcg_ctx, tmp, tcg_ctx->cpu_env, tmp, tmp2);
9782                     tcg_temp_free_i32(tcg_ctx, tmp2);
9783                   }
9784                 break;
9785             case 5: case 6: /* 32 * 32 -> 32msb (SMMUL, SMMLA, SMMLS) */
9786                 tmp64 = gen_muls_i64_i32(s, tmp, tmp2);
9787                 if (rs != 15) {
9788                     tmp = load_reg(s, rs);
9789                     if (insn & (1 << 20)) {
9790                         tmp64 = gen_addq_msw(s, tmp64, tmp);
9791                     } else {
9792                         tmp64 = gen_subq_msw(s, tmp64, tmp);
9793                     }
9794                 }
9795                 if (insn & (1 << 4)) {
9796                     tcg_gen_addi_i64(tcg_ctx, tmp64, tmp64, 0x80000000u);
9797                 }
9798                 tcg_gen_shri_i64(tcg_ctx, tmp64, tmp64, 32);
9799                 tmp = tcg_temp_new_i32(tcg_ctx);
9800                 tcg_gen_trunc_i64_i32(tcg_ctx, tmp, tmp64);
9801                 tcg_temp_free_i64(tcg_ctx, tmp64);
9802                 break;
9803             case 7: /* Unsigned sum of absolute differences.  */
9804                 gen_helper_usad8(tcg_ctx, tmp, tmp, tmp2);
9805                 tcg_temp_free_i32(tcg_ctx, tmp2);
9806                 if (rs != 15) {
9807                     tmp2 = load_reg(s, rs);
9808                     tcg_gen_add_i32(tcg_ctx, tmp, tmp, tmp2);
9809                     tcg_temp_free_i32(tcg_ctx, tmp2);
9810                 }
9811                 break;
9812             }
9813             store_reg(s, rd, tmp);
9814             break;
9815         case 6: case 7: /* 64-bit multiply, Divide.  */
9816             op = ((insn >> 4) & 0xf) | ((insn >> 16) & 0x70);
9817             tmp = load_reg(s, rn);
9818             tmp2 = load_reg(s, rm);
9819             if ((op & 0x50) == 0x10) {
9820                 /* sdiv, udiv */
9821                 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DIV)) {
9822                     goto illegal_op;
9823                 }
9824                 if (op & 0x20)
9825                     gen_helper_udiv(tcg_ctx, tmp, tmp, tmp2);
9826                 else
9827                     gen_helper_sdiv(tcg_ctx, tmp, tmp, tmp2);
9828                 tcg_temp_free_i32(tcg_ctx, tmp2);
9829                 store_reg(s, rd, tmp);
9830             } else if ((op & 0xe) == 0xc) {
9831                 /* Dual multiply accumulate long.  */
9832                 if (op & 1)
9833                     gen_swap_half(s, tmp2);
9834                 gen_smul_dual(s, tmp, tmp2);
9835                 if (op & 0x10) {
9836                     tcg_gen_sub_i32(tcg_ctx, tmp, tmp, tmp2);
9837                 } else {
9838                     tcg_gen_add_i32(tcg_ctx, tmp, tmp, tmp2);
9839                 }
9840                 tcg_temp_free_i32(tcg_ctx, tmp2);
9841                 /* BUGFIX */
9842                 tmp64 = tcg_temp_new_i64(tcg_ctx);
9843                 tcg_gen_ext_i32_i64(tcg_ctx, tmp64, tmp);
9844                 tcg_temp_free_i32(tcg_ctx, tmp);
9845                 gen_addq(s, tmp64, rs, rd);
9846                 gen_storeq_reg(s, rs, rd, tmp64);
9847                 tcg_temp_free_i64(tcg_ctx, tmp64);
9848             } else {
9849                 if (op & 0x20) {
9850                     /* Unsigned 64-bit multiply  */
9851                     tmp64 = gen_mulu_i64_i32(s, tmp, tmp2);
9852                 } else {
9853                     if (op & 8) {
9854                         /* smlalxy */
9855                         gen_mulxy(s, tmp, tmp2, op & 2, op & 1);
9856                         tcg_temp_free_i32(tcg_ctx, tmp2);
9857                         tmp64 = tcg_temp_new_i64(tcg_ctx);
9858                         tcg_gen_ext_i32_i64(tcg_ctx, tmp64, tmp);
9859                         tcg_temp_free_i32(tcg_ctx, tmp);
9860                     } else {
9861                         /* Signed 64-bit multiply  */
9862                         tmp64 = gen_muls_i64_i32(s, tmp, tmp2);
9863                     }
9864                 }
9865                 if (op & 4) {
9866                     /* umaal */
9867                     gen_addq_lo(s, tmp64, rs);
9868                     gen_addq_lo(s, tmp64, rd);
9869                 } else if (op & 0x40) {
9870                     /* 64-bit accumulate.  */
9871                     gen_addq(s, tmp64, rs, rd);
9872                 }
9873                 gen_storeq_reg(s, rs, rd, tmp64);
9874                 tcg_temp_free_i64(tcg_ctx, tmp64);
9875             }
9876             break;
9877         }
9878         break;
9879     case 6: case 7: case 14: case 15:
9880         /* Coprocessor.  */
9881         if (((insn >> 24) & 3) == 3) {
9882             /* Translate into the equivalent ARM encoding.  */
9883             insn = (insn & 0xe2ffffff) | ((insn & (1 << 28)) >> 4) | (1 << 28);
9884             if (disas_neon_data_insn(s, insn)) {
9885                 goto illegal_op;
9886             }
9887         } else if (((insn >> 8) & 0xe) == 10) {
9888             if (disas_vfp_insn(s, insn)) {
9889                 goto illegal_op;
9890             }
9891         } else {
9892             if (insn & (1 << 28))
9893                 goto illegal_op;
9894             if (disas_coproc_insn(s, insn)) {
9895                 goto illegal_op;
9896             }
9897         }
9898         break;
9899     case 8: case 9: case 10: case 11:
9900         if (insn & (1 << 15)) {
9901             /* Branches, misc control.  */
9902             if (insn & 0x5000) {
9903                 /* Unconditional branch.  */
9904                 /* signextend(hw1[10:0]) -> offset[:12].  */
9905                 offset = ((int32_t)(insn << 5)) >> 9 & ~(int32_t)0xfff;
9906                 /* hw1[10:0] -> offset[11:1].  */
9907                 offset |= (insn & 0x7ff) << 1;
9908                 /* (~hw2[13, 11] ^ offset[24]) -> offset[23,22]
9909                    offset[24:22] already have the same value because of the
9910                    sign extension above.  */
9911                 offset ^= ((~insn) & (1 << 13)) << 10;
9912                 offset ^= ((~insn) & (1 << 11)) << 11;
9913 
9914                 if (insn & (1 << 14)) {
9915                     /* Branch and link.  */
9916                     tcg_gen_movi_i32(tcg_ctx, tcg_ctx->cpu_R[14], s->pc | 1);
9917                 }
9918 
9919                 offset += s->pc;
9920                 if (insn & (1 << 12)) {
9921                     /* b/bl */
9922                     gen_jmp(s, offset);
9923                 } else {
9924                     /* blx */
9925                     offset &= ~(uint32_t)2;
9926                     /* thumb2 bx, no need to check */
9927                     gen_bx_im(s, offset);
9928                 }
9929             } else if (((insn >> 23) & 7) == 7) {
9930                 /* Misc control */
9931                 if (insn & (1 << 13))
9932                     goto illegal_op;
9933 
9934                 if (insn & (1 << 26)) {
9935                     if (!(insn & (1 << 20))) {
9936                         /* Hypervisor call (v7) */
9937                         int imm16 = extract32(insn, 16, 4) << 12
9938                             | extract32(insn, 0, 12);
9939                         ARCH(7);
9940                         if (IS_USER(s)) {
9941                             goto illegal_op;
9942                         }
9943                         gen_hvc(s, imm16);
9944                     } else {
9945                         /* Secure monitor call (v6+) */
9946                         ARCH(6K);
9947                         if (IS_USER(s)) {
9948                             goto illegal_op;
9949                         }
9950                         gen_smc(s);
9951                     }
9952                 } else {
9953                     op = (insn >> 20) & 7;
9954                     switch (op) {
9955                     case 0: /* msr cpsr.  */
9956                         if (arm_dc_feature(s, ARM_FEATURE_M)) {
9957                             tmp = load_reg(s, rn);
9958                             addr = tcg_const_i32(tcg_ctx, insn & 0xff);
9959                             gen_helper_v7m_msr(tcg_ctx, tcg_ctx->cpu_env, addr, tmp);
9960                             tcg_temp_free_i32(tcg_ctx, addr);
9961                             tcg_temp_free_i32(tcg_ctx, tmp);
9962                             gen_lookup_tb(s);
9963                             break;
9964                         }
9965                         /* fall through */
9966                     case 1: /* msr spsr.  */
9967                         if (arm_dc_feature(s, ARM_FEATURE_M)) {
9968                             goto illegal_op;
9969                         }
9970                         tmp = load_reg(s, rn);
9971                         if (gen_set_psr(s,
9972                               msr_mask(s, (insn >> 8) & 0xf, op == 1),
9973                               op == 1, tmp))
9974                             goto illegal_op;
9975                         break;
9976                     case 2: /* cps, nop-hint.  */
9977                         if (((insn >> 8) & 7) == 0) {
9978                             gen_nop_hint(s, insn & 0xff);
9979                         }
9980                         /* Implemented as NOP in user mode.  */
9981                         if (IS_USER(s))
9982                             break;
9983                         offset = 0;
9984                         imm = 0;
9985                         if (insn & (1 << 10)) {
9986                             if (insn & (1 << 7))
9987                                 offset |= CPSR_A;
9988                             if (insn & (1 << 6))
9989                                 offset |= CPSR_I;
9990                             if (insn & (1 << 5))
9991                                 offset |= CPSR_F;
9992                             if (insn & (1 << 9))
9993                                 imm = CPSR_A | CPSR_I | CPSR_F;
9994                         }
9995                         if (insn & (1 << 8)) {
9996                             offset |= 0x1f;
9997                             imm |= (insn & 0x1f);
9998                         }
9999                         if (offset) {
10000                             gen_set_psr_im(s, offset, 0, imm);
10001                         }
10002                         break;
10003                     case 3: /* Special control operations.  */
10004                         ARCH(7);
10005                         op = (insn >> 4) & 0xf;
10006                         switch (op) {
10007                         case 2: /* clrex */
10008                             gen_clrex(s);
10009                             break;
10010                         case 4: /* dsb */
10011                         case 5: /* dmb */
10012                         case 6: /* isb */
10013                             /* These execute as NOPs.  */
10014                             break;
10015                         default:
10016                             goto illegal_op;
10017                         }
10018                         break;
10019                     case 4: /* bxj */
10020                         /* Trivial implementation equivalent to bx.  */
10021                         tmp = load_reg(s, rn);
10022                         gen_bx(s, tmp);
10023                         break;
10024                     case 5: /* Exception return.  */
10025                         if (IS_USER(s)) {
10026                             goto illegal_op;
10027                         }
10028                         if (rn != 14 || rd != 15) {
10029                             goto illegal_op;
10030                         }
10031                         tmp = load_reg(s, rn);
10032                         tcg_gen_subi_i32(tcg_ctx, tmp, tmp, insn & 0xff);
10033                         gen_exception_return(s, tmp);
10034                         break;
10035                     case 6: /* mrs cpsr.  */
10036                         tmp = tcg_temp_new_i32(tcg_ctx);
10037                         if (arm_dc_feature(s, ARM_FEATURE_M)) {
10038                             addr = tcg_const_i32(tcg_ctx, insn & 0xff);
10039                             gen_helper_v7m_mrs(tcg_ctx, tmp, tcg_ctx->cpu_env, addr);
10040                             tcg_temp_free_i32(tcg_ctx, addr);
10041                         } else {
10042                             gen_helper_cpsr_read(tcg_ctx, tmp, tcg_ctx->cpu_env);
10043                         }
10044                         store_reg(s, rd, tmp);
10045                         break;
10046                     case 7: /* mrs spsr.  */
10047                         /* Not accessible in user mode.  */
10048                         if (IS_USER(s) || arm_dc_feature(s, ARM_FEATURE_M)) {
10049                             goto illegal_op;
10050                         }
10051                         tmp = load_cpu_field(s->uc, spsr);
10052                         store_reg(s, rd, tmp);
10053                         break;
10054                     }
10055                 }
10056             } else {
10057                 /* Conditional branch.  */
10058                 op = (insn >> 22) & 0xf;
10059                 /* Generate a conditional jump to next instruction.  */
10060                 s->condlabel = gen_new_label(tcg_ctx);
10061                 arm_gen_test_cc(tcg_ctx, op ^ 1, s->condlabel);
10062                 s->condjmp = 1;
10063 
10064                 /* offset[11:1] = insn[10:0] */
10065                 offset = (insn & 0x7ff) << 1;
10066                 /* offset[17:12] = insn[21:16].  */
10067                 offset |= (insn & 0x003f0000) >> 4;
10068                 /* offset[31:20] = insn[26].  */
10069                 offset |= ((int32_t)((insn << 5) & 0x80000000)) >> 11;
10070                 /* offset[18] = insn[13].  */
10071                 offset |= (insn & (1 << 13)) << 5;
10072                 /* offset[19] = insn[11].  */
10073                 offset |= (insn & (1 << 11)) << 8;
10074 
10075                 /* jump to the offset */
10076                 gen_jmp(s, s->pc + offset);
10077             }
10078         } else {
10079             /* Data processing immediate.  */
10080             if (insn & (1 << 25)) {
10081                 if (insn & (1 << 24)) {
10082                     if (insn & (1 << 20))
10083                         goto illegal_op;
10084                     /* Bitfield/Saturate.  */
10085                     op = (insn >> 21) & 7;
10086                     imm = insn & 0x1f;
10087                     shift = ((insn >> 6) & 3) | ((insn >> 10) & 0x1c);
10088                     if (rn == 15) {
10089                         tmp = tcg_temp_new_i32(tcg_ctx);
10090                         tcg_gen_movi_i32(tcg_ctx, tmp, 0);
10091                     } else {
10092                         tmp = load_reg(s, rn);
10093                     }
10094                     switch (op) {
10095                     case 2: /* Signed bitfield extract.  */
10096                         imm++;
10097                         if (shift + imm > 32)
10098                             goto illegal_op;
10099                         if (imm < 32)
10100                             gen_sbfx(s, tmp, shift, imm);
10101                         break;
10102                     case 6: /* Unsigned bitfield extract.  */
10103                         imm++;
10104                         if (shift + imm > 32)
10105                             goto illegal_op;
10106                         if (imm < 32)
10107                             gen_ubfx(s, tmp, shift, (1u << imm) - 1);
10108                         break;
10109                     case 3: /* Bitfield insert/clear.  */
10110                         if (imm < shift)
10111                             goto illegal_op;
10112                         imm = imm + 1 - shift;
10113                         if (imm != 32) {
10114                             tmp2 = load_reg(s, rd);
10115                             tcg_gen_deposit_i32(tcg_ctx, tmp, tmp2, tmp, shift, imm);
10116                             tcg_temp_free_i32(tcg_ctx, tmp2);
10117                         }
10118                         break;
10119                     case 7:
10120                         goto illegal_op;
10121                     default: /* Saturate.  */
10122                         if (shift) {
10123                             if (op & 1)
10124                                 tcg_gen_sari_i32(tcg_ctx, tmp, tmp, shift);
10125                             else
10126                                 tcg_gen_shli_i32(tcg_ctx, tmp, tmp, shift);
10127                         }
10128                         tmp2 = tcg_const_i32(tcg_ctx, imm);
10129                         if (op & 4) {
10130                             /* Unsigned.  */
10131                             if ((op & 1) && shift == 0)
10132                                 gen_helper_usat16(tcg_ctx, tmp, tcg_ctx->cpu_env, tmp, tmp2);
10133                             else
10134                                 gen_helper_usat(tcg_ctx, tmp, tcg_ctx->cpu_env, tmp, tmp2);
10135                         } else {
10136                             /* Signed.  */
10137                             if ((op & 1) && shift == 0)
10138                                 gen_helper_ssat16(tcg_ctx, tmp, tcg_ctx->cpu_env, tmp, tmp2);
10139                             else
10140                                 gen_helper_ssat(tcg_ctx, tmp, tcg_ctx->cpu_env, tmp, tmp2);
10141                         }
10142                         tcg_temp_free_i32(tcg_ctx, tmp2);
10143                         break;
10144                     }
10145                     store_reg(s, rd, tmp);
10146                 } else {
10147                     imm = ((insn & 0x04000000) >> 15)
10148                           | ((insn & 0x7000) >> 4) | (insn & 0xff);
10149                     if (insn & (1 << 22)) {
10150                         /* 16-bit immediate.  */
10151                         imm |= (insn >> 4) & 0xf000;
10152                         if (insn & (1 << 23)) {
10153                             /* movt */
10154                             tmp = load_reg(s, rd);
10155                             tcg_gen_ext16u_i32(tcg_ctx, tmp, tmp);
10156                             tcg_gen_ori_i32(tcg_ctx, tmp, tmp, imm << 16);
10157                         } else {
10158                             /* movw */
10159                             tmp = tcg_temp_new_i32(tcg_ctx);
10160                             tcg_gen_movi_i32(tcg_ctx, tmp, imm);
10161                         }
10162                     } else {
10163                         /* Add/sub 12-bit immediate.  */
10164                         if (rn == 15) {
10165                             offset = s->pc & ~(uint32_t)3;
10166                             if (insn & (1 << 23))
10167                                 offset -= imm;
10168                             else
10169                                 offset += imm;
10170                             tmp = tcg_temp_new_i32(tcg_ctx);
10171                             tcg_gen_movi_i32(tcg_ctx, tmp, offset);
10172                         } else {
10173                             tmp = load_reg(s, rn);
10174                             if (insn & (1 << 23))
10175                                 tcg_gen_subi_i32(tcg_ctx, tmp, tmp, imm);
10176                             else
10177                                 tcg_gen_addi_i32(tcg_ctx, tmp, tmp, imm);
10178                         }
10179                     }
10180                     store_reg(s, rd, tmp);
10181                 }
10182             } else {
10183                 int shifter_out = 0;
10184                 /* modified 12-bit immediate.  */
10185                 shift = ((insn & 0x04000000) >> 23) | ((insn & 0x7000) >> 12);
10186                 imm = (insn & 0xff);
10187                 switch (shift) {
10188                 case 0: /* XY */
10189                     /* Nothing to do.  */
10190                     break;
10191                 case 1: /* 00XY00XY */
10192                     imm |= imm << 16;
10193                     break;
10194                 case 2: /* XY00XY00 */
10195                     imm |= imm << 16;
10196                     imm <<= 8;
10197                     break;
10198                 case 3: /* XYXYXYXY */
10199                     imm |= imm << 16;
10200                     imm |= imm << 8;
10201                     break;
10202                 default: /* Rotated constant.  */
10203                     shift = (shift << 1) | (imm >> 7);
10204                     imm |= 0x80;
10205                     imm = imm << (32 - shift);
10206                     shifter_out = 1;
10207                     break;
10208                 }
10209                 tmp2 = tcg_temp_new_i32(tcg_ctx);
10210                 tcg_gen_movi_i32(tcg_ctx, tmp2, imm);
10211                 rn = (insn >> 16) & 0xf;
10212                 if (rn == 15) {
10213                     tmp = tcg_temp_new_i32(tcg_ctx);
10214                     tcg_gen_movi_i32(tcg_ctx, tmp, 0);
10215                 } else {
10216                     tmp = load_reg(s, rn);
10217                 }
10218                 op = (insn >> 21) & 0xf;
10219                 if (gen_thumb2_data_op(s, op, (insn & (1 << 20)) != 0,
10220                                        shifter_out, tmp, tmp2))
10221                     goto illegal_op;
10222                 tcg_temp_free_i32(tcg_ctx, tmp2);
10223                 rd = (insn >> 8) & 0xf;
10224                 if (rd != 15) {
10225                     store_reg(s, rd, tmp);
10226                 } else {
10227                     tcg_temp_free_i32(tcg_ctx, tmp);
10228                 }
10229             }
10230         }
10231         break;
10232     case 12: /* Load/store single data item.  */
10233         {
10234         int postinc = 0;
10235         int writeback = 0;
10236         int memidx;
10237         if ((insn & 0x01100000) == 0x01000000) {
10238             if (disas_neon_ls_insn(s, insn)) {
10239                 goto illegal_op;
10240             }
10241             break;
10242         }
10243         op = ((insn >> 21) & 3) | ((insn >> 22) & 4);
10244         if (rs == 15) {
10245             if (!(insn & (1 << 20))) {
10246                 goto illegal_op;
10247             }
10248             if (op != 2) {
10249                 /* Byte or halfword load space with dest == r15 : memory hints.
10250                  * Catch them early so we don't emit pointless addressing code.
10251                  * This space is a mix of:
10252                  *  PLD/PLDW/PLI,  which we implement as NOPs (note that unlike
10253                  *     the ARM encodings, PLDW space doesn't UNDEF for non-v7MP
10254                  *     cores)
10255                  *  unallocated hints, which must be treated as NOPs
10256                  *  UNPREDICTABLE space, which we NOP or UNDEF depending on
10257                  *     which is easiest for the decoding logic
10258                  *  Some space which must UNDEF
10259                  */
10260                 int op1 = (insn >> 23) & 3;
10261                 int op2 = (insn >> 6) & 0x3f;
10262                 if (op & 2) {
10263                     goto illegal_op;
10264                 }
10265                 if (rn == 15) {
10266                     /* UNPREDICTABLE, unallocated hint or
10267                      * PLD/PLDW/PLI (literal)
10268                      */
10269                     return 0;
10270                 }
10271                 if (op1 & 1) {
10272                     return 0; /* PLD/PLDW/PLI or unallocated hint */
10273                 }
10274                 if ((op2 == 0) || ((op2 & 0x3c) == 0x30)) {
10275                     return 0; /* PLD/PLDW/PLI or unallocated hint */
10276                 }
10277                 /* UNDEF space, or an UNPREDICTABLE */
10278                 return 1;
10279             }
10280         }
10281         memidx = get_mem_index(s);
10282         if (rn == 15) {
10283             addr = tcg_temp_new_i32(tcg_ctx);
10284             /* PC relative.  */
10285             /* s->pc has already been incremented by 4.  */
10286             imm = s->pc & 0xfffffffc;
10287             if (insn & (1 << 23))
10288                 imm += insn & 0xfff;
10289             else
10290                 imm -= insn & 0xfff;
10291             tcg_gen_movi_i32(tcg_ctx, addr, imm);
10292         } else {
10293             addr = load_reg(s, rn);
10294             if (insn & (1 << 23)) {
10295                 /* Positive offset.  */
10296                 imm = insn & 0xfff;
10297                 tcg_gen_addi_i32(tcg_ctx, addr, addr, imm);
10298             } else {
10299                 imm = insn & 0xff;
10300                 switch ((insn >> 8) & 0xf) {
10301                 case 0x0: /* Shifted Register.  */
10302                     shift = (insn >> 4) & 0xf;
10303                     if (shift > 3) {
10304                         tcg_temp_free_i32(tcg_ctx, addr);
10305                         goto illegal_op;
10306                     }
10307                     tmp = load_reg(s, rm);
10308                     if (shift)
10309                         tcg_gen_shli_i32(tcg_ctx, tmp, tmp, shift);
10310                     tcg_gen_add_i32(tcg_ctx, addr, addr, tmp);
10311                     tcg_temp_free_i32(tcg_ctx, tmp);
10312                     break;
10313                 case 0xc: /* Negative offset.  */
10314                     tcg_gen_addi_i32(tcg_ctx, addr, addr, 0-imm);
10315                     break;
10316                 case 0xe: /* User privilege.  */
10317                     tcg_gen_addi_i32(tcg_ctx, addr, addr, imm);
10318                     memidx = MMU_USER_IDX;
10319                     break;
10320                 case 0x9: /* Post-decrement.  */
10321                     imm = 0-imm;
10322                     /* Fall through.  */
10323                 case 0xb: /* Post-increment.  */
10324                     postinc = 1;
10325                     writeback = 1;
10326                     break;
10327                 case 0xd: /* Pre-decrement.  */
10328                     imm = 0-imm;
10329                     /* Fall through.  */
10330                 case 0xf: /* Pre-increment.  */
10331                     tcg_gen_addi_i32(tcg_ctx, addr, addr, imm);
10332                     writeback = 1;
10333                     break;
10334                 default:
10335                     tcg_temp_free_i32(tcg_ctx, addr);
10336                     goto illegal_op;
10337                 }
10338             }
10339         }
10340         if (insn & (1 << 20)) {
10341             /* Load.  */
10342             tmp = tcg_temp_new_i32(tcg_ctx);
10343             switch (op) {
10344             case 0:
10345                 gen_aa32_ld8u(s, tmp, addr, memidx);
10346                 break;
10347             case 4:
10348                 gen_aa32_ld8s(s, tmp, addr, memidx);
10349                 break;
10350             case 1:
10351                 gen_aa32_ld16u(s, tmp, addr, memidx);
10352                 break;
10353             case 5:
10354                 gen_aa32_ld16s(s, tmp, addr, memidx);
10355                 break;
10356             case 2:
10357                 gen_aa32_ld32u(s, tmp, addr, memidx);
10358                 break;
10359             default:
10360                 tcg_temp_free_i32(tcg_ctx, tmp);
10361                 tcg_temp_free_i32(tcg_ctx, addr);
10362                 goto illegal_op;
10363             }
10364             if (rs == 15) {
10365                 gen_bx(s, tmp);
10366             } else {
10367                 store_reg(s, rs, tmp);
10368             }
10369         } else {
10370             /* Store.  */
10371             tmp = load_reg(s, rs);
10372             switch (op) {
10373             case 0:
10374                 gen_aa32_st8(s, tmp, addr, memidx);
10375                 break;
10376             case 1:
10377                 gen_aa32_st16(s, tmp, addr, memidx);
10378                 break;
10379             case 2:
10380                 gen_aa32_st32(s, tmp, addr, memidx);
10381                 break;
10382             default:
10383                 tcg_temp_free_i32(tcg_ctx, tmp);
10384                 tcg_temp_free_i32(tcg_ctx, addr);
10385                 goto illegal_op;
10386             }
10387             tcg_temp_free_i32(tcg_ctx, tmp);
10388         }
10389         if (postinc)
10390             tcg_gen_addi_i32(tcg_ctx, addr, addr, imm);
10391         if (writeback) {
10392             store_reg(s, rn, addr);
10393         } else {
10394             tcg_temp_free_i32(tcg_ctx, addr);
10395         }
10396         }
10397         break;
10398     default:
10399         goto illegal_op;
10400     }
10401     return 0;
10402 illegal_op:
10403     return 1;
10404 }
10405 
disas_thumb_insn(CPUARMState * env,DisasContext * s)10406 static void disas_thumb_insn(CPUARMState *env, DisasContext *s) // qq
10407 {
10408     TCGContext *tcg_ctx = s->uc->tcg_ctx;
10409     uint32_t val, insn, op, rm, rn, rd, shift, cond;
10410     int32_t offset;
10411     int i;
10412     TCGv_i32 tmp;
10413     TCGv_i32 tmp2;
10414     TCGv_i32 addr;
10415 
10416     // Unicorn: end address tells us to stop emulation
10417     if (s->pc == s->uc->addr_end) {
10418         // imitate WFI instruction to halt emulation
10419         s->is_jmp = DISAS_WFI;
10420         return;
10421     }
10422 
10423     if (s->condexec_mask) {
10424         cond = s->condexec_cond;
10425         if (cond != 0x0e) {     /* Skip conditional when condition is AL. */
10426           s->condlabel = gen_new_label(tcg_ctx);
10427           arm_gen_test_cc(tcg_ctx, cond ^ 1, s->condlabel);
10428           s->condjmp = 1;
10429         }
10430     }
10431 
10432     insn = arm_lduw_code(env, s->pc, s->bswap_code);
10433 
10434     // Unicorn: trace this instruction on request
10435     if (HOOK_EXISTS_BOUNDED(s->uc, UC_HOOK_CODE, s->pc)) {
10436         // determine instruction size (Thumb/Thumb2)
10437         switch(insn & 0xf800) {
10438             // Thumb2: 32-bit
10439             case 0xe800:
10440             case 0xf000:
10441             case 0xf800:
10442                 gen_uc_tracecode(tcg_ctx, 4, UC_HOOK_CODE_IDX, s->uc, s->pc);
10443                 break;
10444             // Thumb: 16-bit
10445             default:
10446                 gen_uc_tracecode(tcg_ctx, 2, UC_HOOK_CODE_IDX, s->uc, s->pc);
10447                 break;
10448         }
10449         // the callback might want to stop emulation immediately
10450         check_exit_request(tcg_ctx);
10451     }
10452 
10453     s->pc += 2;
10454 
10455     switch (insn >> 12) {
10456     case 0: case 1:
10457 
10458         rd = insn & 7;
10459         op = (insn >> 11) & 3;
10460         if (op == 3) {
10461             /* add/subtract */
10462             rn = (insn >> 3) & 7;
10463             tmp = load_reg(s, rn);
10464             if (insn & (1 << 10)) {
10465                 /* immediate */
10466                 tmp2 = tcg_temp_new_i32(tcg_ctx);
10467                 tcg_gen_movi_i32(tcg_ctx, tmp2, (insn >> 6) & 7);
10468             } else {
10469                 /* reg */
10470                 rm = (insn >> 6) & 7;
10471                 tmp2 = load_reg(s, rm);
10472             }
10473             if (insn & (1 << 9)) {
10474                 if (s->condexec_mask)
10475                     tcg_gen_sub_i32(tcg_ctx, tmp, tmp, tmp2);
10476                 else
10477                     gen_sub_CC(s, tmp, tmp, tmp2);
10478             } else {
10479                 if (s->condexec_mask)
10480                     tcg_gen_add_i32(tcg_ctx, tmp, tmp, tmp2);
10481                 else
10482                     gen_add_CC(s, tmp, tmp, tmp2);
10483             }
10484             tcg_temp_free_i32(tcg_ctx, tmp2);
10485             store_reg(s, rd, tmp);
10486         } else {
10487             /* shift immediate */
10488             rm = (insn >> 3) & 7;
10489             shift = (insn >> 6) & 0x1f;
10490             tmp = load_reg(s, rm);
10491             gen_arm_shift_im(s, tmp, op, shift, s->condexec_mask == 0);
10492             if (!s->condexec_mask)
10493                 gen_logic_CC(s, tmp);
10494             store_reg(s, rd, tmp);
10495         }
10496         break;
10497     case 2: case 3:
10498         /* arithmetic large immediate */
10499         op = (insn >> 11) & 3;
10500         rd = (insn >> 8) & 0x7;
10501         if (op == 0) { /* mov */
10502             tmp = tcg_temp_new_i32(tcg_ctx);
10503             tcg_gen_movi_i32(tcg_ctx, tmp, insn & 0xff);
10504             if (!s->condexec_mask)
10505                 gen_logic_CC(s, tmp);
10506             store_reg(s, rd, tmp);
10507         } else {
10508             tmp = load_reg(s, rd);
10509             tmp2 = tcg_temp_new_i32(tcg_ctx);
10510             tcg_gen_movi_i32(tcg_ctx, tmp2, insn & 0xff);
10511             switch (op) {
10512             case 1: /* cmp */
10513                 gen_sub_CC(s, tmp, tmp, tmp2);
10514                 tcg_temp_free_i32(tcg_ctx, tmp);
10515                 tcg_temp_free_i32(tcg_ctx, tmp2);
10516                 break;
10517             case 2: /* add */
10518                 if (s->condexec_mask)
10519                     tcg_gen_add_i32(tcg_ctx, tmp, tmp, tmp2);
10520                 else
10521                     gen_add_CC(s, tmp, tmp, tmp2);
10522                 tcg_temp_free_i32(tcg_ctx, tmp2);
10523                 store_reg(s, rd, tmp);
10524                 break;
10525             case 3: /* sub */
10526                 if (s->condexec_mask)
10527                     tcg_gen_sub_i32(tcg_ctx, tmp, tmp, tmp2);
10528                 else
10529                     gen_sub_CC(s, tmp, tmp, tmp2);
10530                 tcg_temp_free_i32(tcg_ctx, tmp2);
10531                 store_reg(s, rd, tmp);
10532                 break;
10533             }
10534         }
10535         break;
10536     case 4:
10537         if (insn & (1 << 11)) {
10538             rd = (insn >> 8) & 7;
10539             /* load pc-relative.  Bit 1 of PC is ignored.  */
10540             val = s->pc + 2 + ((insn & 0xff) * 4);
10541             val &= ~(uint32_t)2;
10542             addr = tcg_temp_new_i32(tcg_ctx);
10543             tcg_gen_movi_i32(tcg_ctx, addr, val);
10544             tmp = tcg_temp_new_i32(tcg_ctx);
10545             gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
10546             tcg_temp_free_i32(tcg_ctx, addr);
10547             store_reg(s, rd, tmp);
10548             break;
10549         }
10550         if (insn & (1 << 10)) {
10551             /* data processing extended or blx */
10552             rd = (insn & 7) | ((insn >> 4) & 8);
10553             rm = (insn >> 3) & 0xf;
10554             op = (insn >> 8) & 3;
10555             switch (op) {
10556             case 0: /* add */
10557                 tmp = load_reg(s, rd);
10558                 tmp2 = load_reg(s, rm);
10559                 tcg_gen_add_i32(tcg_ctx, tmp, tmp, tmp2);
10560                 tcg_temp_free_i32(tcg_ctx, tmp2);
10561                 store_reg(s, rd, tmp);
10562                 break;
10563             case 1: /* cmp */
10564                 tmp = load_reg(s, rd);
10565                 tmp2 = load_reg(s, rm);
10566                 gen_sub_CC(s, tmp, tmp, tmp2);
10567                 tcg_temp_free_i32(tcg_ctx, tmp2);
10568                 tcg_temp_free_i32(tcg_ctx, tmp);
10569                 break;
10570             case 2: /* mov/cpy */
10571                 tmp = load_reg(s, rm);
10572                 store_reg(s, rd, tmp);
10573                 break;
10574             case 3:/* branch [and link] exchange thumb register */
10575                 tmp = load_reg(s, rm);
10576                 if (insn & (1 << 7)) {
10577                     ARCH(5);
10578                     val = (uint32_t)s->pc | 1;
10579                     tmp2 = tcg_temp_new_i32(tcg_ctx);
10580                     tcg_gen_movi_i32(tcg_ctx, tmp2, val);
10581                     store_reg(s, 14, tmp2);
10582                 }
10583                 /* already thumb, no need to check */
10584                 gen_bx(s, tmp);
10585                 break;
10586             }
10587             break;
10588         }
10589 
10590         /* data processing register */
10591         rd = insn & 7;
10592         rm = (insn >> 3) & 7;
10593         op = (insn >> 6) & 0xf;
10594         if (op == 2 || op == 3 || op == 4 || op == 7) {
10595             /* the shift/rotate ops want the operands backwards */
10596             val = rm;
10597             rm = rd;
10598             rd = val;
10599             val = 1;
10600         } else {
10601             val = 0;
10602         }
10603 
10604         if (op == 9) { /* neg */
10605             tmp = tcg_temp_new_i32(tcg_ctx);
10606             tcg_gen_movi_i32(tcg_ctx, tmp, 0);
10607         } else if (op != 0xf) { /* mvn doesn't read its first operand */
10608             tmp = load_reg(s, rd);
10609         } else {
10610             TCGV_UNUSED_I32(tmp);
10611         }
10612 
10613         tmp2 = load_reg(s, rm);
10614         switch (op) {
10615         case 0x0: /* and */
10616             tcg_gen_and_i32(tcg_ctx, tmp, tmp, tmp2);
10617             if (!s->condexec_mask)
10618                 gen_logic_CC(s, tmp);
10619             break;
10620         case 0x1: /* eor */
10621             tcg_gen_xor_i32(tcg_ctx, tmp, tmp, tmp2);
10622             if (!s->condexec_mask)
10623                 gen_logic_CC(s, tmp);
10624             break;
10625         case 0x2: /* lsl */
10626             if (s->condexec_mask) {
10627                 gen_shl(s, tmp2, tmp2, tmp);
10628             } else {
10629                 gen_helper_shl_cc(tcg_ctx, tmp2, tcg_ctx->cpu_env, tmp2, tmp);
10630                 gen_logic_CC(s, tmp2);
10631             }
10632             break;
10633         case 0x3: /* lsr */
10634             if (s->condexec_mask) {
10635                 gen_shr(s, tmp2, tmp2, tmp);
10636             } else {
10637                 gen_helper_shr_cc(tcg_ctx, tmp2, tcg_ctx->cpu_env, tmp2, tmp);
10638                 gen_logic_CC(s, tmp2);
10639             }
10640             break;
10641         case 0x4: /* asr */
10642             if (s->condexec_mask) {
10643                 gen_sar(s, tmp2, tmp2, tmp);
10644             } else {
10645                 gen_helper_sar_cc(tcg_ctx, tmp2, tcg_ctx->cpu_env, tmp2, tmp);
10646                 gen_logic_CC(s, tmp2);
10647             }
10648             break;
10649         case 0x5: /* adc */
10650             if (s->condexec_mask) {
10651                 gen_adc(s, tmp, tmp2);
10652             } else {
10653                 gen_adc_CC(s, tmp, tmp, tmp2);
10654             }
10655             break;
10656         case 0x6: /* sbc */
10657             if (s->condexec_mask) {
10658                 gen_sub_carry(s, tmp, tmp, tmp2);
10659             } else {
10660                 gen_sbc_CC(s, tmp, tmp, tmp2);
10661             }
10662             break;
10663         case 0x7: /* ror */
10664             if (s->condexec_mask) {
10665                 tcg_gen_andi_i32(tcg_ctx, tmp, tmp, 0x1f);
10666                 tcg_gen_rotr_i32(tcg_ctx, tmp2, tmp2, tmp);
10667             } else {
10668                 gen_helper_ror_cc(tcg_ctx, tmp2, tcg_ctx->cpu_env, tmp2, tmp);
10669                 gen_logic_CC(s, tmp2);
10670             }
10671             break;
10672         case 0x8: /* tst */
10673             tcg_gen_and_i32(tcg_ctx, tmp, tmp, tmp2);
10674             gen_logic_CC(s, tmp);
10675             rd = 16;
10676             break;
10677         case 0x9: /* neg */
10678             if (s->condexec_mask)
10679                 tcg_gen_neg_i32(tcg_ctx, tmp, tmp2);
10680             else
10681                 gen_sub_CC(s, tmp, tmp, tmp2);
10682             break;
10683         case 0xa: /* cmp */
10684             gen_sub_CC(s, tmp, tmp, tmp2);
10685             rd = 16;
10686             break;
10687         case 0xb: /* cmn */
10688             gen_add_CC(s, tmp, tmp, tmp2);
10689             rd = 16;
10690             break;
10691         case 0xc: /* orr */
10692             tcg_gen_or_i32(tcg_ctx, tmp, tmp, tmp2);
10693             if (!s->condexec_mask)
10694                 gen_logic_CC(s, tmp);
10695             break;
10696         case 0xd: /* mul */
10697             tcg_gen_mul_i32(tcg_ctx, tmp, tmp, tmp2);
10698             if (!s->condexec_mask)
10699                 gen_logic_CC(s, tmp);
10700             break;
10701         case 0xe: /* bic */
10702             tcg_gen_andc_i32(tcg_ctx, tmp, tmp, tmp2);
10703             if (!s->condexec_mask)
10704                 gen_logic_CC(s, tmp);
10705             break;
10706         case 0xf: /* mvn */
10707             tcg_gen_not_i32(tcg_ctx, tmp2, tmp2);
10708             if (!s->condexec_mask)
10709                 gen_logic_CC(s, tmp2);
10710             val = 1;
10711             rm = rd;
10712             break;
10713         }
10714         if (rd != 16) {
10715             if (val) {
10716                 store_reg(s, rm, tmp2);
10717                 if (op != 0xf)
10718                     tcg_temp_free_i32(tcg_ctx, tmp);
10719             } else {
10720                 store_reg(s, rd, tmp);
10721                 tcg_temp_free_i32(tcg_ctx, tmp2);
10722             }
10723         } else {
10724             tcg_temp_free_i32(tcg_ctx, tmp);
10725             tcg_temp_free_i32(tcg_ctx, tmp2);
10726         }
10727         break;
10728 
10729     case 5:
10730         /* load/store register offset.  */
10731         rd = insn & 7;
10732         rn = (insn >> 3) & 7;
10733         rm = (insn >> 6) & 7;
10734         op = (insn >> 9) & 7;
10735         addr = load_reg(s, rn);
10736         tmp = load_reg(s, rm);
10737         tcg_gen_add_i32(tcg_ctx, addr, addr, tmp);
10738         tcg_temp_free_i32(tcg_ctx, tmp);
10739 
10740         if (op < 3) { /* store */
10741             tmp = load_reg(s, rd);
10742         } else {
10743             tmp = tcg_temp_new_i32(tcg_ctx);
10744         }
10745 
10746         switch (op) {
10747         case 0: /* str */
10748             gen_aa32_st32(s, tmp, addr, get_mem_index(s));
10749             break;
10750         case 1: /* strh */
10751             gen_aa32_st16(s, tmp, addr, get_mem_index(s));
10752             break;
10753         case 2: /* strb */
10754             gen_aa32_st8(s, tmp, addr, get_mem_index(s));
10755             break;
10756         case 3: /* ldrsb */
10757             gen_aa32_ld8s(s, tmp, addr, get_mem_index(s));
10758             break;
10759         case 4: /* ldr */
10760             gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
10761             break;
10762         case 5: /* ldrh */
10763             gen_aa32_ld16u(s, tmp, addr, get_mem_index(s));
10764             break;
10765         case 6: /* ldrb */
10766             gen_aa32_ld8u(s, tmp, addr, get_mem_index(s));
10767             break;
10768         case 7: /* ldrsh */
10769             gen_aa32_ld16s(s, tmp, addr, get_mem_index(s));
10770             break;
10771         }
10772         if (op >= 3) { /* load */
10773             store_reg(s, rd, tmp);
10774         } else {
10775             tcg_temp_free_i32(tcg_ctx, tmp);
10776         }
10777         tcg_temp_free_i32(tcg_ctx, addr);
10778         break;
10779 
10780     case 6:
10781         /* load/store word immediate offset */
10782         rd = insn & 7;
10783         rn = (insn >> 3) & 7;
10784         addr = load_reg(s, rn);
10785         val = (insn >> 4) & 0x7c;
10786         tcg_gen_addi_i32(tcg_ctx, addr, addr, val);
10787 
10788         if (insn & (1 << 11)) {
10789             /* load */
10790             tmp = tcg_temp_new_i32(tcg_ctx);
10791             gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
10792             store_reg(s, rd, tmp);
10793         } else {
10794             /* store */
10795             tmp = load_reg(s, rd);
10796             gen_aa32_st32(s, tmp, addr, get_mem_index(s));
10797             tcg_temp_free_i32(tcg_ctx, tmp);
10798         }
10799         tcg_temp_free_i32(tcg_ctx, addr);
10800         break;
10801 
10802     case 7:
10803         /* load/store byte immediate offset */
10804         rd = insn & 7;
10805         rn = (insn >> 3) & 7;
10806         addr = load_reg(s, rn);
10807         val = (insn >> 6) & 0x1f;
10808         tcg_gen_addi_i32(tcg_ctx, addr, addr, val);
10809 
10810         if (insn & (1 << 11)) {
10811             /* load */
10812             tmp = tcg_temp_new_i32(tcg_ctx);
10813             gen_aa32_ld8u(s, tmp, addr, get_mem_index(s));
10814             store_reg(s, rd, tmp);
10815         } else {
10816             /* store */
10817             tmp = load_reg(s, rd);
10818             gen_aa32_st8(s, tmp, addr, get_mem_index(s));
10819             tcg_temp_free_i32(tcg_ctx, tmp);
10820         }
10821         tcg_temp_free_i32(tcg_ctx, addr);
10822         break;
10823 
10824     case 8:
10825         /* load/store halfword immediate offset */
10826         rd = insn & 7;
10827         rn = (insn >> 3) & 7;
10828         addr = load_reg(s, rn);
10829         val = (insn >> 5) & 0x3e;
10830         tcg_gen_addi_i32(tcg_ctx, addr, addr, val);
10831 
10832         if (insn & (1 << 11)) {
10833             /* load */
10834             tmp = tcg_temp_new_i32(tcg_ctx);
10835             gen_aa32_ld16u(s, tmp, addr, get_mem_index(s));
10836             store_reg(s, rd, tmp);
10837         } else {
10838             /* store */
10839             tmp = load_reg(s, rd);
10840             gen_aa32_st16(s, tmp, addr, get_mem_index(s));
10841             tcg_temp_free_i32(tcg_ctx, tmp);
10842         }
10843         tcg_temp_free_i32(tcg_ctx, addr);
10844         break;
10845 
10846     case 9:
10847         /* load/store from stack */
10848         rd = (insn >> 8) & 7;
10849         addr = load_reg(s, 13);
10850         val = (insn & 0xff) * 4;
10851         tcg_gen_addi_i32(tcg_ctx, addr, addr, val);
10852 
10853         if (insn & (1 << 11)) {
10854             /* load */
10855             tmp = tcg_temp_new_i32(tcg_ctx);
10856             gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
10857             store_reg(s, rd, tmp);
10858         } else {
10859             /* store */
10860             tmp = load_reg(s, rd);
10861             gen_aa32_st32(s, tmp, addr, get_mem_index(s));
10862             tcg_temp_free_i32(tcg_ctx, tmp);
10863         }
10864         tcg_temp_free_i32(tcg_ctx, addr);
10865         break;
10866 
10867     case 10:
10868         /* add to high reg */
10869         rd = (insn >> 8) & 7;
10870         if (insn & (1 << 11)) {
10871             /* SP */
10872             tmp = load_reg(s, 13);
10873         } else {
10874             /* PC. bit 1 is ignored.  */
10875             tmp = tcg_temp_new_i32(tcg_ctx);
10876             tcg_gen_movi_i32(tcg_ctx, tmp, (s->pc + 2) & ~(uint32_t)2);
10877         }
10878         val = (insn & 0xff) * 4;
10879         tcg_gen_addi_i32(tcg_ctx, tmp, tmp, val);
10880         store_reg(s, rd, tmp);
10881         break;
10882 
10883     case 11:
10884         /* misc */
10885         op = (insn >> 8) & 0xf;
10886         switch (op) {
10887         case 0:
10888             /* adjust stack pointer */
10889             tmp = load_reg(s, 13);
10890             val = (insn & 0x7f) * 4;
10891             if (insn & (1 << 7))
10892                 val = -(int32_t)val;
10893             tcg_gen_addi_i32(tcg_ctx, tmp, tmp, val);
10894             store_reg(s, 13, tmp);
10895             break;
10896 
10897         case 2: /* sign/zero extend.  */
10898             ARCH(6);
10899             rd = insn & 7;
10900             rm = (insn >> 3) & 7;
10901             tmp = load_reg(s, rm);
10902             switch ((insn >> 6) & 3) {
10903             case 0: gen_sxth(tmp); break;
10904             case 1: gen_sxtb(tmp); break;
10905             case 2: gen_uxth(tmp); break;
10906             case 3: gen_uxtb(tmp); break;
10907             }
10908             store_reg(s, rd, tmp);
10909             break;
10910         case 4: case 5: case 0xc: case 0xd:
10911             /* push/pop */
10912             addr = load_reg(s, 13);
10913             if (insn & (1 << 8))
10914                 offset = 4;
10915             else
10916                 offset = 0;
10917             for (i = 0; i < 8; i++) {
10918                 if (insn & (1 << i))
10919                     offset += 4;
10920             }
10921             if ((insn & (1 << 11)) == 0) {
10922                 tcg_gen_addi_i32(tcg_ctx, addr, addr, -offset);
10923             }
10924             for (i = 0; i < 8; i++) {
10925                 if (insn & (1 << i)) {
10926                     if (insn & (1 << 11)) {
10927                         /* pop */
10928                         tmp = tcg_temp_new_i32(tcg_ctx);
10929                         gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
10930                         store_reg(s, i, tmp);
10931                     } else {
10932                         /* push */
10933                         tmp = load_reg(s, i);
10934                         gen_aa32_st32(s, tmp, addr, get_mem_index(s));
10935                         tcg_temp_free_i32(tcg_ctx, tmp);
10936                     }
10937                     /* advance to the next address.  */
10938                     tcg_gen_addi_i32(tcg_ctx, addr, addr, 4);
10939                 }
10940             }
10941             TCGV_UNUSED_I32(tmp);
10942             if (insn & (1 << 8)) {
10943                 if (insn & (1 << 11)) {
10944                     /* pop pc */
10945                     tmp = tcg_temp_new_i32(tcg_ctx);
10946                     gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
10947                     /* don't set the pc until the rest of the instruction
10948                        has completed */
10949                 } else {
10950                     /* push lr */
10951                     tmp = load_reg(s, 14);
10952                     gen_aa32_st32(s, tmp, addr, get_mem_index(s));
10953                     tcg_temp_free_i32(tcg_ctx, tmp);
10954                 }
10955                 tcg_gen_addi_i32(tcg_ctx, addr, addr, 4);
10956             }
10957             if ((insn & (1 << 11)) == 0) {
10958                 tcg_gen_addi_i32(tcg_ctx, addr, addr, -offset);
10959             }
10960             /* write back the new stack pointer */
10961             store_reg(s, 13, addr);
10962             /* set the new PC value */
10963             if ((insn & 0x0900) == 0x0900) {
10964                 store_reg_from_load(s, 15, tmp);
10965             }
10966             break;
10967 
10968         case 1: case 3: case 9: case 11: /* czb */
10969             rm = insn & 7;
10970             tmp = load_reg(s, rm);
10971             s->condlabel = gen_new_label(tcg_ctx);
10972             s->condjmp = 1;
10973             if (insn & (1 << 11))
10974                 tcg_gen_brcondi_i32(tcg_ctx, TCG_COND_EQ, tmp, 0, s->condlabel);
10975             else
10976                 tcg_gen_brcondi_i32(tcg_ctx, TCG_COND_NE, tmp, 0, s->condlabel);
10977             tcg_temp_free_i32(tcg_ctx, tmp);
10978             offset = ((insn & 0xf8) >> 2) | (insn & 0x200) >> 3;
10979             val = (uint32_t)s->pc + 2;
10980             val += offset;
10981             gen_jmp(s, val);
10982             break;
10983 
10984         case 15: /* IT, nop-hint.  */
10985             if ((insn & 0xf) == 0) {
10986                 gen_nop_hint(s, (insn >> 4) & 0xf);
10987                 break;
10988             }
10989             /* If Then.  */
10990             s->condexec_cond = (insn >> 4) & 0xe;
10991             s->condexec_mask = insn & 0x1f;
10992             /* No actual code generated for this insn, just setup state.  */
10993             break;
10994 
10995         case 0xe: /* bkpt */
10996         {
10997             int imm8 = extract32(insn, 0, 8);
10998             ARCH(5);
10999             gen_exception_insn(s, 2, EXCP_BKPT, syn_aa32_bkpt(imm8, true));
11000             break;
11001         }
11002 
11003         case 0xa: /* rev */
11004             ARCH(6);
11005             rn = (insn >> 3) & 0x7;
11006             rd = insn & 0x7;
11007             tmp = load_reg(s, rn);
11008             switch ((insn >> 6) & 3) {
11009             case 0: tcg_gen_bswap32_i32(tcg_ctx, tmp, tmp); break;
11010             case 1: gen_rev16(s, tmp); break;
11011             case 3: gen_revsh(s, tmp); break;
11012             default: goto illegal_op;
11013             }
11014             store_reg(s, rd, tmp);
11015             break;
11016 
11017         case 6:
11018             switch ((insn >> 5) & 7) {
11019             case 2:
11020                 /* setend */
11021                 ARCH(6);
11022                 if (((insn >> 3) & 1) != s->bswap_code) {
11023                     /* Dynamic endianness switching not implemented. */
11024                     qemu_log_mask(LOG_UNIMP, "arm: unimplemented setend\n");
11025                     goto illegal_op;
11026                 }
11027                 break;
11028             case 3:
11029                 /* cps */
11030                 ARCH(6);
11031                 if (IS_USER(s)) {
11032                     break;
11033                 }
11034                 if (arm_dc_feature(s, ARM_FEATURE_M)) {
11035                     tmp = tcg_const_i32(tcg_ctx, (insn & (1 << 4)) != 0);
11036                     /* FAULTMASK */
11037                     if (insn & 1) {
11038                         addr = tcg_const_i32(tcg_ctx, 19);
11039                         gen_helper_v7m_msr(tcg_ctx, tcg_ctx->cpu_env, addr, tmp);
11040                         tcg_temp_free_i32(tcg_ctx, addr);
11041                     }
11042                     /* PRIMASK */
11043                     if (insn & 2) {
11044                         addr = tcg_const_i32(tcg_ctx, 16);
11045                         gen_helper_v7m_msr(tcg_ctx, tcg_ctx->cpu_env, addr, tmp);
11046                         tcg_temp_free_i32(tcg_ctx, addr);
11047                     }
11048                     tcg_temp_free_i32(tcg_ctx, tmp);
11049                     gen_lookup_tb(s);
11050                 } else {
11051                     if (insn & (1 << 4)) {
11052                         shift = CPSR_A | CPSR_I | CPSR_F;
11053                     } else {
11054                         shift = 0;
11055                     }
11056                     gen_set_psr_im(s, ((insn & 7) << 6), 0, shift);
11057                 }
11058                 break;
11059             default:
11060                 goto undef;
11061             }
11062             break;
11063 
11064         default:
11065             goto undef;
11066         }
11067         break;
11068 
11069     case 12:
11070     {
11071         /* load/store multiple */
11072         TCGv_i32 loaded_var;
11073         TCGV_UNUSED_I32(loaded_var);
11074         rn = (insn >> 8) & 0x7;
11075         addr = load_reg(s, rn);
11076         for (i = 0; i < 8; i++) {
11077             if (insn & (1 << i)) {
11078                 if (insn & (1 << 11)) {
11079                     /* load */
11080                     tmp = tcg_temp_new_i32(tcg_ctx);
11081                     gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
11082                     if (i == rn) {
11083                         loaded_var = tmp;
11084                     } else {
11085                         store_reg(s, i, tmp);
11086                     }
11087                 } else {
11088                     /* store */
11089                     tmp = load_reg(s, i);
11090                     gen_aa32_st32(s, tmp, addr, get_mem_index(s));
11091                     tcg_temp_free_i32(tcg_ctx, tmp);
11092                 }
11093                 /* advance to the next address */
11094                 tcg_gen_addi_i32(tcg_ctx, addr, addr, 4);
11095             }
11096         }
11097         if ((insn & (1 << rn)) == 0) {
11098             /* base reg not in list: base register writeback */
11099             store_reg(s, rn, addr);
11100         } else {
11101             /* base reg in list: if load, complete it now */
11102             if (insn & (1 << 11)) {
11103                 store_reg(s, rn, loaded_var);
11104             }
11105             tcg_temp_free_i32(tcg_ctx, addr);
11106         }
11107         break;
11108     }
11109     case 13:
11110         /* conditional branch or swi */
11111         cond = (insn >> 8) & 0xf;
11112         if (cond == 0xe)
11113             goto undef;
11114 
11115         if (cond == 0xf) {
11116             /* swi */
11117             gen_set_pc_im(s, s->pc);
11118             s->svc_imm = extract32(insn, 0, 8);
11119             s->is_jmp = DISAS_SWI;
11120             break;
11121         }
11122         /* generate a conditional jump to next instruction */
11123         s->condlabel = gen_new_label(tcg_ctx);
11124         arm_gen_test_cc(tcg_ctx, cond ^ 1, s->condlabel);
11125         s->condjmp = 1;
11126 
11127         /* jump to the offset */
11128         val = (uint32_t)s->pc + 2;
11129         offset = ((int32_t)((uint32_t)insn << 24)) >> 24;
11130         val += (int32_t)((uint32_t)offset << 1);
11131         gen_jmp(s, val);
11132         break;
11133 
11134     case 14:
11135         if (insn & (1 << 11)) {
11136             if (disas_thumb2_insn(env, s, insn))
11137               goto undef32;
11138             break;
11139         }
11140         /* unconditional branch */
11141         val = (uint32_t)s->pc;
11142         offset = ((int32_t)((uint32_t)insn << 21)) >> 21;
11143         val += (int32_t)((uint32_t)offset << 1) + 2;
11144         gen_jmp(s, val);
11145         break;
11146 
11147     case 15:
11148         if (disas_thumb2_insn(env, s, insn))
11149             goto undef32;
11150         break;
11151     }
11152 
11153     return;
11154 undef32:
11155     gen_exception_insn(s, 4, EXCP_UDEF, syn_uncategorized());
11156     return;
11157 illegal_op:
11158 undef:
11159     gen_exception_insn(s, 2, EXCP_UDEF, syn_uncategorized());
11160 }
11161 
11162 /* generate intermediate code in gen_opc_buf and gen_opparam_buf for
11163    basic block 'tb'. If search_pc is TRUE, also generate PC
11164    information for each intermediate instruction. */
gen_intermediate_code_internal(ARMCPU * cpu,TranslationBlock * tb,bool search_pc)11165 static inline void gen_intermediate_code_internal(ARMCPU *cpu,
11166                                                   TranslationBlock *tb,
11167                                                   bool search_pc)
11168 {
11169     CPUState *cs = CPU(cpu);
11170     CPUARMState *env = &cpu->env;
11171     DisasContext dc1, *dc = &dc1;
11172     CPUBreakpoint *bp;
11173     uint16_t *gen_opc_end;
11174     int j, lj;
11175     target_ulong pc_start;
11176     target_ulong next_page_start;
11177     int num_insns;
11178     int max_insns;
11179     TCGContext *tcg_ctx = env->uc->tcg_ctx;
11180     bool block_full = false;
11181 
11182     /* generate intermediate code */
11183 
11184     /* The A64 decoder has its own top level loop, because it doesn't need
11185      * the A32/T32 complexity to do with conditional execution/IT blocks/etc.
11186      */
11187     if (ARM_TBFLAG_AARCH64_STATE(tb->flags)) {
11188         gen_intermediate_code_internal_a64(cpu, tb, search_pc);
11189         return;
11190     }
11191 
11192     pc_start = tb->pc;
11193 
11194     dc->uc = env->uc;
11195     dc->tb = tb;
11196 
11197     gen_opc_end = tcg_ctx->gen_opc_buf + OPC_MAX_SIZE;
11198 
11199     dc->is_jmp = DISAS_NEXT;
11200     dc->pc = pc_start;
11201 
11202     dc->singlestep_enabled = cs->singlestep_enabled;
11203     dc->condjmp = 0;
11204 
11205     dc->aarch64 = 0;
11206     dc->thumb = ARM_TBFLAG_THUMB(tb->flags);    // qq
11207     dc->bswap_code = ARM_TBFLAG_BSWAP_CODE(tb->flags);
11208     dc->condexec_mask = (ARM_TBFLAG_CONDEXEC(tb->flags) & 0xf) << 1;
11209     dc->condexec_cond = ARM_TBFLAG_CONDEXEC(tb->flags) >> 4;
11210 #if !defined(CONFIG_USER_ONLY)
11211     dc->user = (ARM_TBFLAG_PRIV(tb->flags) == 0);
11212 #endif
11213     dc->cpacr_fpen = ARM_TBFLAG_CPACR_FPEN(tb->flags);
11214     dc->vfp_enabled = ARM_TBFLAG_VFPEN(tb->flags);
11215     dc->vec_len = ARM_TBFLAG_VECLEN(tb->flags);
11216     dc->vec_stride = ARM_TBFLAG_VECSTRIDE(tb->flags);
11217     dc->c15_cpar = ARM_TBFLAG_XSCALE_CPAR(tb->flags);
11218     dc->cp_regs = cpu->cp_regs;
11219     dc->current_el = arm_current_el(env);
11220     dc->features = env->features;
11221 
11222     /* Single step state. The code-generation logic here is:
11223      *  SS_ACTIVE == 0:
11224      *   generate code with no special handling for single-stepping (except
11225      *   that anything that can make us go to SS_ACTIVE == 1 must end the TB;
11226      *   this happens anyway because those changes are all system register or
11227      *   PSTATE writes).
11228      *  SS_ACTIVE == 1, PSTATE.SS == 1: (active-not-pending)
11229      *   emit code for one insn
11230      *   emit code to clear PSTATE.SS
11231      *   emit code to generate software step exception for completed step
11232      *   end TB (as usual for having generated an exception)
11233      *  SS_ACTIVE == 1, PSTATE.SS == 0: (active-pending)
11234      *   emit code to generate a software step exception
11235      *   end the TB
11236      */
11237     dc->ss_active = ARM_TBFLAG_SS_ACTIVE(tb->flags);
11238     dc->pstate_ss = ARM_TBFLAG_PSTATE_SS(tb->flags);
11239     dc->is_ldex = false;
11240     dc->ss_same_el = false; /* Can't be true since EL_d must be AArch64 */
11241 
11242     tcg_ctx->cpu_F0s = tcg_temp_new_i32(tcg_ctx);
11243     tcg_ctx->cpu_F1s = tcg_temp_new_i32(tcg_ctx);
11244     tcg_ctx->cpu_F0d = tcg_temp_new_i64(tcg_ctx);
11245     tcg_ctx->cpu_F1d = tcg_temp_new_i64(tcg_ctx);
11246     tcg_ctx->cpu_V0 = tcg_ctx->cpu_F0d;
11247     tcg_ctx->cpu_V1 = tcg_ctx->cpu_F1d;
11248     /* FIXME: tcg_ctx->cpu_M0 can probably be the same as tcg_ctx->cpu_V0.  */
11249     tcg_ctx->cpu_M0 = tcg_temp_new_i64(tcg_ctx);
11250     next_page_start = (pc_start & TARGET_PAGE_MASK) + TARGET_PAGE_SIZE;
11251     lj = -1;
11252     num_insns = 0;
11253     max_insns = tb->cflags & CF_COUNT_MASK;
11254     if (max_insns == 0)
11255         max_insns = CF_COUNT_MASK;
11256 
11257     tcg_clear_temp_count();
11258 
11259     // Unicorn: early check to see if the address of this block is the until address
11260     if (tb->pc == env->uc->addr_end) {
11261         // imitate WFI instruction to halt emulation
11262         gen_tb_start(tcg_ctx);
11263         dc->is_jmp = DISAS_WFI;
11264         goto tb_end;
11265     }
11266 
11267     // Unicorn: trace this block on request
11268     // Only hook this block if it is not broken from previous translation due to
11269     // full translation cache
11270     if (!env->uc->block_full && HOOK_EXISTS_BOUNDED(env->uc, UC_HOOK_BLOCK, pc_start)) {
11271         // save block address to see if we need to patch block size later
11272         env->uc->block_addr = pc_start;
11273         env->uc->size_arg = tcg_ctx->gen_opparam_buf - tcg_ctx->gen_opparam_ptr + 1;
11274         gen_uc_tracecode(tcg_ctx, 0xf8f8f8f8, UC_HOOK_BLOCK_IDX, env->uc, pc_start);
11275     } else {
11276         env->uc->size_arg = -1;
11277     }
11278 
11279     gen_tb_start(tcg_ctx);
11280 
11281     /* A note on handling of the condexec (IT) bits:
11282      *
11283      * We want to avoid the overhead of having to write the updated condexec
11284      * bits back to the CPUARMState for every instruction in an IT block. So:
11285      * (1) if the condexec bits are not already zero then we write
11286      * zero back into the CPUARMState now. This avoids complications trying
11287      * to do it at the end of the block. (For example if we don't do this
11288      * it's hard to identify whether we can safely skip writing condexec
11289      * at the end of the TB, which we definitely want to do for the case
11290      * where a TB doesn't do anything with the IT state at all.)
11291      * (2) if we are going to leave the TB then we call gen_set_condexec()
11292      * which will write the correct value into CPUARMState if zero is wrong.
11293      * This is done both for leaving the TB at the end, and for leaving
11294      * it because of an exception we know will happen, which is done in
11295      * gen_exception_insn(). The latter is necessary because we need to
11296      * leave the TB with the PC/IT state just prior to execution of the
11297      * instruction which caused the exception.
11298      * (3) if we leave the TB unexpectedly (eg a data abort on a load)
11299      * then the CPUARMState will be wrong and we need to reset it.
11300      * This is handled in the same way as restoration of the
11301      * PC in these situations: we will be called again with search_pc=1
11302      * and generate a mapping of the condexec bits for each PC in
11303      * gen_opc_condexec_bits[]. restore_state_to_opc() then uses
11304      * this to restore the condexec bits.
11305      *
11306      * Note that there are no instructions which can read the condexec
11307      * bits, and none which can write non-static values to them, so
11308      * we don't need to care about whether CPUARMState is correct in the
11309      * middle of a TB.
11310      */
11311 
11312     /* Reset the conditional execution bits immediately. This avoids
11313        complications trying to do it at the end of the block.  */
11314     if (dc->condexec_mask || dc->condexec_cond)
11315       {
11316         TCGv_i32 tmp = tcg_temp_new_i32(tcg_ctx);
11317         tcg_gen_movi_i32(tcg_ctx, tmp, 0);
11318         store_cpu_field(tcg_ctx, tmp, condexec_bits);
11319       }
11320     do {
11321         //printf(">>> arm pc = %x\n", dc->pc);
11322 #ifdef CONFIG_USER_ONLY
11323         /* Intercept jump to the magic kernel page.  */
11324         if (dc->pc >= 0xffff0000) {
11325             /* We always get here via a jump, so know we are not in a
11326                conditional execution block.  */
11327             gen_exception_internal(dc, EXCP_KERNEL_TRAP);
11328             dc->is_jmp = DISAS_UPDATE;
11329             break;
11330         }
11331 #else
11332         if (dc->pc >= 0xfffffff0 && arm_dc_feature(dc, ARM_FEATURE_M)) {
11333             /* We always get here via a jump, so know we are not in a
11334                conditional execution block.  */
11335             gen_exception_internal(dc, EXCP_EXCEPTION_EXIT);
11336             dc->is_jmp = DISAS_UPDATE;
11337             break;
11338         }
11339 #endif
11340 
11341         if (unlikely(!QTAILQ_EMPTY(&cs->breakpoints))) {
11342             QTAILQ_FOREACH(bp, &cs->breakpoints, entry) {
11343                 if (bp->pc == dc->pc) {
11344                     gen_exception_internal_insn(dc, 0, EXCP_DEBUG);
11345                     /* Advance PC so that clearing the breakpoint will
11346                        invalidate this TB.  */
11347                     dc->pc += 2;
11348                     goto done_generating;
11349                 }
11350             }
11351         }
11352         if (search_pc) {
11353             j = tcg_ctx->gen_opc_ptr - tcg_ctx->gen_opc_buf;
11354             if (lj < j) {
11355                 lj++;
11356                 while (lj < j)
11357                     tcg_ctx->gen_opc_instr_start[lj++] = 0;
11358             }
11359             tcg_ctx->gen_opc_pc[lj] = dc->pc;
11360             tcg_ctx->gen_opc_condexec_bits[lj] = (dc->condexec_cond << 4) | (dc->condexec_mask >> 1);
11361             tcg_ctx->gen_opc_instr_start[lj] = 1;
11362             //tcg_ctx->gen_opc_icount[lj] = num_insns;
11363         }
11364 
11365         //if (num_insns + 1 == max_insns && (tb->cflags & CF_LAST_IO))
11366         //    gen_io_start();
11367 
11368         if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP | CPU_LOG_TB_OP_OPT))) {
11369             tcg_gen_debug_insn_start(tcg_ctx, dc->pc);
11370         }
11371 
11372         if (dc->ss_active && !dc->pstate_ss) {
11373             /* Singlestep state is Active-pending.
11374              * If we're in this state at the start of a TB then either
11375              *  a) we just took an exception to an EL which is being debugged
11376              *     and this is the first insn in the exception handler
11377              *  b) debug exceptions were masked and we just unmasked them
11378              *     without changing EL (eg by clearing PSTATE.D)
11379              * In either case we're going to take a swstep exception in the
11380              * "did not step an insn" case, and so the syndrome ISV and EX
11381              * bits should be zero.
11382              */
11383             assert(num_insns == 0);
11384             gen_exception(dc, EXCP_UDEF, syn_swstep(dc->ss_same_el, 0, 0));
11385             goto done_generating;
11386         }
11387 
11388         if (dc->thumb) {    // qq
11389             disas_thumb_insn(env, dc);
11390             if (dc->condexec_mask) {
11391                 dc->condexec_cond = (dc->condexec_cond & 0xe)
11392                                    | ((dc->condexec_mask >> 4) & 1);
11393                 dc->condexec_mask = (dc->condexec_mask << 1) & 0x1f;
11394                 if (dc->condexec_mask == 0) {
11395                     dc->condexec_cond = 0;
11396                 }
11397             }
11398         } else {
11399             unsigned int insn;
11400 
11401             // end address tells us to stop emulation
11402             if (dc->pc == dc->uc->addr_end) {
11403                 // imitate WFI instruction to halt emulation
11404                 dc->is_jmp = DISAS_WFI;
11405             } else {
11406                 insn = arm_ldl_code(env, dc->pc, dc->bswap_code);
11407                 dc->pc += 4;
11408                 disas_arm_insn(dc, insn);
11409             }
11410         }
11411 
11412         if (dc->condjmp && !dc->is_jmp) {
11413             gen_set_label(tcg_ctx, dc->condlabel);
11414             dc->condjmp = 0;
11415         }
11416 
11417         if (tcg_check_temp_count()) {
11418             fprintf(stderr, "TCG temporary leak before "TARGET_FMT_lx"\n",
11419                     dc->pc);
11420         }
11421 
11422         /* Translation stops when a conditional branch is encountered.
11423          * Otherwise the subsequent code could get translated several times.
11424          * Also stop translation when a page boundary is reached.  This
11425          * ensures prefetch aborts occur at the right place.  */
11426         num_insns ++;
11427     } while (!dc->is_jmp && tcg_ctx->gen_opc_ptr < gen_opc_end &&
11428              !cs->singlestep_enabled &&
11429              !dc->ss_active &&
11430              dc->pc < next_page_start &&
11431              num_insns < max_insns);
11432 
11433     if (tb->cflags & CF_LAST_IO) {
11434         if (dc->condjmp) {
11435             /* FIXME:  This can theoretically happen with self-modifying
11436                code.  */
11437             cpu_abort(cs, "IO on conditional branch instruction");
11438         }
11439         //gen_io_end();
11440     }
11441 
11442     /* if too long translation, save this info */
11443     if (tcg_ctx->gen_opc_ptr >= gen_opc_end || num_insns >= max_insns) {
11444         block_full = true;
11445     }
11446 
11447 tb_end:
11448 
11449     /* At this stage dc->condjmp will only be set when the skipped
11450        instruction was a conditional branch or trap, and the PC has
11451        already been written.  */
11452     if (unlikely(cs->singlestep_enabled || dc->ss_active)) {
11453         /* Make sure the pc is updated, and raise a debug exception.  */
11454         if (dc->condjmp) {
11455             gen_set_condexec(dc);
11456             if (dc->is_jmp == DISAS_SWI) {
11457                 gen_ss_advance(dc);
11458                 gen_exception(dc, EXCP_SWI, syn_aa32_svc(dc->svc_imm, dc->thumb));
11459             } else if (dc->is_jmp == DISAS_HVC) {
11460                 gen_ss_advance(dc);
11461                 gen_exception(dc, EXCP_HVC, syn_aa32_hvc(dc->svc_imm));
11462             } else if (dc->is_jmp == DISAS_SMC) {
11463                 gen_ss_advance(dc);
11464                 gen_exception(dc, EXCP_SMC, syn_aa32_smc());
11465             } else if (dc->ss_active) {
11466                 gen_step_complete_exception(dc);
11467             } else {
11468                 gen_exception_internal(dc, EXCP_DEBUG);
11469             }
11470             gen_set_label(tcg_ctx, dc->condlabel);
11471         }
11472         if (dc->condjmp || !dc->is_jmp) {
11473             gen_set_pc_im(dc, dc->pc);
11474             dc->condjmp = 0;
11475         }
11476         gen_set_condexec(dc);
11477         if (dc->is_jmp == DISAS_SWI && !dc->condjmp) {
11478             gen_ss_advance(dc);
11479             gen_exception(dc, EXCP_SWI, syn_aa32_svc(dc->svc_imm, dc->thumb));
11480         } else if (dc->is_jmp == DISAS_HVC && !dc->condjmp) {
11481             gen_ss_advance(dc);
11482             gen_exception(dc, EXCP_HVC, syn_aa32_hvc(dc->svc_imm));
11483         } else if (dc->is_jmp == DISAS_SMC && !dc->condjmp) {
11484             gen_ss_advance(dc);
11485             gen_exception(dc, EXCP_SMC, syn_aa32_smc());
11486         } else if (dc->ss_active) {
11487             gen_step_complete_exception(dc);
11488         } else {
11489             /* FIXME: Single stepping a WFI insn will not halt
11490                the CPU.  */
11491             gen_exception_internal(dc, EXCP_DEBUG);
11492         }
11493     } else {
11494         /* While branches must always occur at the end of an IT block,
11495            there are a few other things that can cause us to terminate
11496            the TB in the middle of an IT block:
11497             - Exception generating instructions (bkpt, swi, undefined).
11498             - Page boundaries.
11499             - Hardware watchpoints.
11500            Hardware breakpoints have already been handled and skip this code.
11501          */
11502         gen_set_condexec(dc);
11503         switch(dc->is_jmp) {
11504         case DISAS_NEXT:
11505             gen_goto_tb(dc, 1, dc->pc);
11506             break;
11507         default:
11508         case DISAS_JUMP:
11509         case DISAS_UPDATE:
11510             /* indicate that the hash table must be used to find the next TB */
11511             tcg_gen_exit_tb(tcg_ctx, 0);
11512             break;
11513         case DISAS_TB_JUMP:
11514             /* nothing more to generate */
11515             break;
11516         case DISAS_WFI:
11517             gen_helper_wfi(tcg_ctx, tcg_ctx->cpu_env);
11518             break;
11519         case DISAS_WFE:
11520             gen_helper_wfe(tcg_ctx, tcg_ctx->cpu_env);
11521             break;
11522         case DISAS_SWI:
11523             gen_exception(dc, EXCP_SWI, syn_aa32_svc(dc->svc_imm, dc->thumb));
11524             break;
11525         case DISAS_HVC:
11526             gen_exception(dc, EXCP_HVC, syn_aa32_hvc(dc->svc_imm));
11527             break;
11528         case DISAS_SMC:
11529             gen_exception(dc, EXCP_SMC, syn_aa32_smc());
11530             break;
11531         }
11532         if (dc->condjmp) {
11533             gen_set_label(tcg_ctx, dc->condlabel);
11534             gen_set_condexec(dc);
11535             gen_goto_tb(dc, 1, dc->pc);
11536             dc->condjmp = 0;
11537         }
11538     }
11539 
11540 done_generating:
11541     gen_tb_end(tcg_ctx, tb, num_insns);
11542     *tcg_ctx->gen_opc_ptr = INDEX_op_end;
11543 
11544     if (search_pc) {
11545         j = tcg_ctx->gen_opc_ptr - tcg_ctx->gen_opc_buf;
11546         lj++;
11547         while (lj <= j)
11548             tcg_ctx->gen_opc_instr_start[lj++] = 0;
11549     } else {
11550         tb->size = dc->pc - pc_start;
11551         //tb->icount = num_insns;
11552     }
11553 
11554     env->uc->block_full = block_full;
11555 }
11556 
gen_intermediate_code(CPUARMState * env,TranslationBlock * tb)11557 void gen_intermediate_code(CPUARMState *env, TranslationBlock *tb)
11558 {
11559     gen_intermediate_code_internal(arm_env_get_cpu(env), tb, false);
11560 }
11561 
gen_intermediate_code_pc(CPUARMState * env,TranslationBlock * tb)11562 void gen_intermediate_code_pc(CPUARMState *env, TranslationBlock *tb)
11563 {
11564     gen_intermediate_code_internal(arm_env_get_cpu(env), tb, true);
11565 }
11566 
11567 #if 0
11568 static const char *cpu_mode_names[16] = {
11569   "usr", "fiq", "irq", "svc", "???", "???", "mon", "abt",
11570   "???", "???", "hyp", "und", "???", "???", "???", "sys"
11571 };
11572 
11573 void arm_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf,
11574                         int flags)
11575 {
11576     ARMCPU *cpu = ARM_CPU(cs);
11577     CPUARMState *env = &cpu->env;
11578     int i;
11579     uint32_t psr;
11580 
11581     if (is_a64(env)) {
11582         aarch64_cpu_dump_state(cs, f, cpu_fprintf, flags);
11583         return;
11584     }
11585 
11586     for(i=0;i<16;i++) {
11587         cpu_fprintf(f, "R%02d=%08x", i, env->regs[i]);
11588         if ((i % 4) == 3)
11589             cpu_fprintf(f, "\n");
11590         else
11591             cpu_fprintf(f, " ");
11592     }
11593     psr = cpsr_read(env);
11594     cpu_fprintf(f, "PSR=%08x %c%c%c%c %c %s%d\n",
11595                 psr,
11596                 psr & (1 << 31) ? 'N' : '-',
11597                 psr & (1 << 30) ? 'Z' : '-',
11598                 psr & (1 << 29) ? 'C' : '-',
11599                 psr & (1 << 28) ? 'V' : '-',
11600                 psr & CPSR_T ? 'T' : 'A',
11601                 cpu_mode_names[psr & 0xf], (psr & 0x10) ? 32 : 26);
11602 
11603     if (flags & CPU_DUMP_FPU) {
11604         int numvfpregs = 0;
11605         if (arm_feature(env, ARM_FEATURE_VFP)) {
11606             numvfpregs += 16;
11607         }
11608         if (arm_feature(env, ARM_FEATURE_VFP3)) {
11609             numvfpregs += 16;
11610         }
11611         for (i = 0; i < numvfpregs; i++) {
11612             uint64_t v = float64_val(env->vfp.regs[i]);
11613             cpu_fprintf(f, "s%02d=%08x s%02d=%08x d%02d=%016" PRIx64 "\n",
11614                         i * 2, (uint32_t)v,
11615                         i * 2 + 1, (uint32_t)(v >> 32),
11616                         i, v);
11617         }
11618         cpu_fprintf(f, "FPSCR: %08x\n", (int)env->vfp.xregs[ARM_VFP_FPSCR]);
11619     }
11620 }
11621 #endif
11622 
restore_state_to_opc(CPUARMState * env,TranslationBlock * tb,int pc_pos)11623 void restore_state_to_opc(CPUARMState *env, TranslationBlock *tb, int pc_pos)
11624 {
11625     TCGContext *tcg_ctx = env->uc->tcg_ctx;
11626     if (is_a64(env)) {
11627         env->pc = tcg_ctx->gen_opc_pc[pc_pos];
11628         env->condexec_bits = 0;
11629     } else {
11630         env->regs[15] = tcg_ctx->gen_opc_pc[pc_pos];
11631         env->condexec_bits = tcg_ctx->gen_opc_condexec_bits[pc_pos];
11632     }
11633 }
11634