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