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