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