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