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