]> git.proxmox.com Git - qemu.git/blob - target-arm/translate.c
target-arm: add support for neon vld1.64/vst1.64 instructions
[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 store_cpu_field(tmp, vfp.xregs[rn]);
2792 gen_lookup_tb(s);
2793 break;
2794 case ARM_VFP_FPINST:
2795 case ARM_VFP_FPINST2:
2796 store_cpu_field(tmp, vfp.xregs[rn]);
2797 break;
2798 default:
2799 return 1;
2800 }
2801 } else {
2802 gen_vfp_msr(tmp);
2803 gen_mov_vreg_F0(0, rn);
2804 }
2805 }
2806 }
2807 } else {
2808 /* data processing */
2809 /* The opcode is in bits 23, 21, 20 and 6. */
2810 op = ((insn >> 20) & 8) | ((insn >> 19) & 6) | ((insn >> 6) & 1);
2811 if (dp) {
2812 if (op == 15) {
2813 /* rn is opcode */
2814 rn = ((insn >> 15) & 0x1e) | ((insn >> 7) & 1);
2815 } else {
2816 /* rn is register number */
2817 VFP_DREG_N(rn, insn);
2818 }
2819
2820 if (op == 15 && (rn == 15 || rn > 17)) {
2821 /* Integer or single precision destination. */
2822 rd = VFP_SREG_D(insn);
2823 } else {
2824 VFP_DREG_D(rd, insn);
2825 }
2826
2827 if (op == 15 && (rn == 16 || rn == 17)) {
2828 /* Integer source. */
2829 rm = ((insn << 1) & 0x1e) | ((insn >> 5) & 1);
2830 } else {
2831 VFP_DREG_M(rm, insn);
2832 }
2833 } else {
2834 rn = VFP_SREG_N(insn);
2835 if (op == 15 && rn == 15) {
2836 /* Double precision destination. */
2837 VFP_DREG_D(rd, insn);
2838 } else {
2839 rd = VFP_SREG_D(insn);
2840 }
2841 rm = VFP_SREG_M(insn);
2842 }
2843
2844 veclen = env->vfp.vec_len;
2845 if (op == 15 && rn > 3)
2846 veclen = 0;
2847
2848 /* Shut up compiler warnings. */
2849 delta_m = 0;
2850 delta_d = 0;
2851 bank_mask = 0;
2852
2853 if (veclen > 0) {
2854 if (dp)
2855 bank_mask = 0xc;
2856 else
2857 bank_mask = 0x18;
2858
2859 /* Figure out what type of vector operation this is. */
2860 if ((rd & bank_mask) == 0) {
2861 /* scalar */
2862 veclen = 0;
2863 } else {
2864 if (dp)
2865 delta_d = (env->vfp.vec_stride >> 1) + 1;
2866 else
2867 delta_d = env->vfp.vec_stride + 1;
2868
2869 if ((rm & bank_mask) == 0) {
2870 /* mixed scalar/vector */
2871 delta_m = 0;
2872 } else {
2873 /* vector */
2874 delta_m = delta_d;
2875 }
2876 }
2877 }
2878
2879 /* Load the initial operands. */
2880 if (op == 15) {
2881 switch (rn) {
2882 case 16:
2883 case 17:
2884 /* Integer source */
2885 gen_mov_F0_vreg(0, rm);
2886 break;
2887 case 8:
2888 case 9:
2889 /* Compare */
2890 gen_mov_F0_vreg(dp, rd);
2891 gen_mov_F1_vreg(dp, rm);
2892 break;
2893 case 10:
2894 case 11:
2895 /* Compare with zero */
2896 gen_mov_F0_vreg(dp, rd);
2897 gen_vfp_F1_ld0(dp);
2898 break;
2899 case 20:
2900 case 21:
2901 case 22:
2902 case 23:
2903 case 28:
2904 case 29:
2905 case 30:
2906 case 31:
2907 /* Source and destination the same. */
2908 gen_mov_F0_vreg(dp, rd);
2909 break;
2910 default:
2911 /* One source operand. */
2912 gen_mov_F0_vreg(dp, rm);
2913 break;
2914 }
2915 } else {
2916 /* Two source operands. */
2917 gen_mov_F0_vreg(dp, rn);
2918 gen_mov_F1_vreg(dp, rm);
2919 }
2920
2921 for (;;) {
2922 /* Perform the calculation. */
2923 switch (op) {
2924 case 0: /* mac: fd + (fn * fm) */
2925 gen_vfp_mul(dp);
2926 gen_mov_F1_vreg(dp, rd);
2927 gen_vfp_add(dp);
2928 break;
2929 case 1: /* nmac: fd - (fn * fm) */
2930 gen_vfp_mul(dp);
2931 gen_vfp_neg(dp);
2932 gen_mov_F1_vreg(dp, rd);
2933 gen_vfp_add(dp);
2934 break;
2935 case 2: /* msc: -fd + (fn * fm) */
2936 gen_vfp_mul(dp);
2937 gen_mov_F1_vreg(dp, rd);
2938 gen_vfp_sub(dp);
2939 break;
2940 case 3: /* nmsc: -fd - (fn * fm) */
2941 gen_vfp_mul(dp);
2942 gen_vfp_neg(dp);
2943 gen_mov_F1_vreg(dp, rd);
2944 gen_vfp_sub(dp);
2945 break;
2946 case 4: /* mul: fn * fm */
2947 gen_vfp_mul(dp);
2948 break;
2949 case 5: /* nmul: -(fn * fm) */
2950 gen_vfp_mul(dp);
2951 gen_vfp_neg(dp);
2952 break;
2953 case 6: /* add: fn + fm */
2954 gen_vfp_add(dp);
2955 break;
2956 case 7: /* sub: fn - fm */
2957 gen_vfp_sub(dp);
2958 break;
2959 case 8: /* div: fn / fm */
2960 gen_vfp_div(dp);
2961 break;
2962 case 14: /* fconst */
2963 if (!arm_feature(env, ARM_FEATURE_VFP3))
2964 return 1;
2965
2966 n = (insn << 12) & 0x80000000;
2967 i = ((insn >> 12) & 0x70) | (insn & 0xf);
2968 if (dp) {
2969 if (i & 0x40)
2970 i |= 0x3f80;
2971 else
2972 i |= 0x4000;
2973 n |= i << 16;
2974 tcg_gen_movi_i64(cpu_F0d, ((uint64_t)n) << 32);
2975 } else {
2976 if (i & 0x40)
2977 i |= 0x780;
2978 else
2979 i |= 0x800;
2980 n |= i << 19;
2981 tcg_gen_movi_i32(cpu_F0s, n);
2982 }
2983 break;
2984 case 15: /* extension space */
2985 switch (rn) {
2986 case 0: /* cpy */
2987 /* no-op */
2988 break;
2989 case 1: /* abs */
2990 gen_vfp_abs(dp);
2991 break;
2992 case 2: /* neg */
2993 gen_vfp_neg(dp);
2994 break;
2995 case 3: /* sqrt */
2996 gen_vfp_sqrt(dp);
2997 break;
2998 case 8: /* cmp */
2999 gen_vfp_cmp(dp);
3000 break;
3001 case 9: /* cmpe */
3002 gen_vfp_cmpe(dp);
3003 break;
3004 case 10: /* cmpz */
3005 gen_vfp_cmp(dp);
3006 break;
3007 case 11: /* cmpez */
3008 gen_vfp_F1_ld0(dp);
3009 gen_vfp_cmpe(dp);
3010 break;
3011 case 15: /* single<->double conversion */
3012 if (dp)
3013 gen_helper_vfp_fcvtsd(cpu_F0s, cpu_F0d, cpu_env);
3014 else
3015 gen_helper_vfp_fcvtds(cpu_F0d, cpu_F0s, cpu_env);
3016 break;
3017 case 16: /* fuito */
3018 gen_vfp_uito(dp);
3019 break;
3020 case 17: /* fsito */
3021 gen_vfp_sito(dp);
3022 break;
3023 case 20: /* fshto */
3024 if (!arm_feature(env, ARM_FEATURE_VFP3))
3025 return 1;
3026 gen_vfp_shto(dp, 16 - rm);
3027 break;
3028 case 21: /* fslto */
3029 if (!arm_feature(env, ARM_FEATURE_VFP3))
3030 return 1;
3031 gen_vfp_slto(dp, 32 - rm);
3032 break;
3033 case 22: /* fuhto */
3034 if (!arm_feature(env, ARM_FEATURE_VFP3))
3035 return 1;
3036 gen_vfp_uhto(dp, 16 - rm);
3037 break;
3038 case 23: /* fulto */
3039 if (!arm_feature(env, ARM_FEATURE_VFP3))
3040 return 1;
3041 gen_vfp_ulto(dp, 32 - rm);
3042 break;
3043 case 24: /* ftoui */
3044 gen_vfp_toui(dp);
3045 break;
3046 case 25: /* ftouiz */
3047 gen_vfp_touiz(dp);
3048 break;
3049 case 26: /* ftosi */
3050 gen_vfp_tosi(dp);
3051 break;
3052 case 27: /* ftosiz */
3053 gen_vfp_tosiz(dp);
3054 break;
3055 case 28: /* ftosh */
3056 if (!arm_feature(env, ARM_FEATURE_VFP3))
3057 return 1;
3058 gen_vfp_tosh(dp, 16 - rm);
3059 break;
3060 case 29: /* ftosl */
3061 if (!arm_feature(env, ARM_FEATURE_VFP3))
3062 return 1;
3063 gen_vfp_tosl(dp, 32 - rm);
3064 break;
3065 case 30: /* ftouh */
3066 if (!arm_feature(env, ARM_FEATURE_VFP3))
3067 return 1;
3068 gen_vfp_touh(dp, 16 - rm);
3069 break;
3070 case 31: /* ftoul */
3071 if (!arm_feature(env, ARM_FEATURE_VFP3))
3072 return 1;
3073 gen_vfp_toul(dp, 32 - rm);
3074 break;
3075 default: /* undefined */
3076 printf ("rn:%d\n", rn);
3077 return 1;
3078 }
3079 break;
3080 default: /* undefined */
3081 printf ("op:%d\n", op);
3082 return 1;
3083 }
3084
3085 /* Write back the result. */
3086 if (op == 15 && (rn >= 8 && rn <= 11))
3087 ; /* Comparison, do nothing. */
3088 else if (op == 15 && rn > 17)
3089 /* Integer result. */
3090 gen_mov_vreg_F0(0, rd);
3091 else if (op == 15 && rn == 15)
3092 /* conversion */
3093 gen_mov_vreg_F0(!dp, rd);
3094 else
3095 gen_mov_vreg_F0(dp, rd);
3096
3097 /* break out of the loop if we have finished */
3098 if (veclen == 0)
3099 break;
3100
3101 if (op == 15 && delta_m == 0) {
3102 /* single source one-many */
3103 while (veclen--) {
3104 rd = ((rd + delta_d) & (bank_mask - 1))
3105 | (rd & bank_mask);
3106 gen_mov_vreg_F0(dp, rd);
3107 }
3108 break;
3109 }
3110 /* Setup the next operands. */
3111 veclen--;
3112 rd = ((rd + delta_d) & (bank_mask - 1))
3113 | (rd & bank_mask);
3114
3115 if (op == 15) {
3116 /* One source operand. */
3117 rm = ((rm + delta_m) & (bank_mask - 1))
3118 | (rm & bank_mask);
3119 gen_mov_F0_vreg(dp, rm);
3120 } else {
3121 /* Two source operands. */
3122 rn = ((rn + delta_d) & (bank_mask - 1))
3123 | (rn & bank_mask);
3124 gen_mov_F0_vreg(dp, rn);
3125 if (delta_m) {
3126 rm = ((rm + delta_m) & (bank_mask - 1))
3127 | (rm & bank_mask);
3128 gen_mov_F1_vreg(dp, rm);
3129 }
3130 }
3131 }
3132 }
3133 break;
3134 case 0xc:
3135 case 0xd:
3136 if (dp && (insn & 0x03e00000) == 0x00400000) {
3137 /* two-register transfer */
3138 rn = (insn >> 16) & 0xf;
3139 rd = (insn >> 12) & 0xf;
3140 if (dp) {
3141 VFP_DREG_M(rm, insn);
3142 } else {
3143 rm = VFP_SREG_M(insn);
3144 }
3145
3146 if (insn & ARM_CP_RW_BIT) {
3147 /* vfp->arm */
3148 if (dp) {
3149 gen_mov_F0_vreg(0, rm * 2);
3150 tmp = gen_vfp_mrs();
3151 store_reg(s, rd, tmp);
3152 gen_mov_F0_vreg(0, rm * 2 + 1);
3153 tmp = gen_vfp_mrs();
3154 store_reg(s, rn, tmp);
3155 } else {
3156 gen_mov_F0_vreg(0, rm);
3157 tmp = gen_vfp_mrs();
3158 store_reg(s, rn, tmp);
3159 gen_mov_F0_vreg(0, rm + 1);
3160 tmp = gen_vfp_mrs();
3161 store_reg(s, rd, tmp);
3162 }
3163 } else {
3164 /* arm->vfp */
3165 if (dp) {
3166 tmp = load_reg(s, rd);
3167 gen_vfp_msr(tmp);
3168 gen_mov_vreg_F0(0, rm * 2);
3169 tmp = load_reg(s, rn);
3170 gen_vfp_msr(tmp);
3171 gen_mov_vreg_F0(0, rm * 2 + 1);
3172 } else {
3173 tmp = load_reg(s, rn);
3174 gen_vfp_msr(tmp);
3175 gen_mov_vreg_F0(0, rm);
3176 tmp = load_reg(s, rd);
3177 gen_vfp_msr(tmp);
3178 gen_mov_vreg_F0(0, rm + 1);
3179 }
3180 }
3181 } else {
3182 /* Load/store */
3183 rn = (insn >> 16) & 0xf;
3184 if (dp)
3185 VFP_DREG_D(rd, insn);
3186 else
3187 rd = VFP_SREG_D(insn);
3188 if (s->thumb && rn == 15) {
3189 addr = new_tmp();
3190 tcg_gen_movi_i32(addr, s->pc & ~2);
3191 } else {
3192 addr = load_reg(s, rn);
3193 }
3194 if ((insn & 0x01200000) == 0x01000000) {
3195 /* Single load/store */
3196 offset = (insn & 0xff) << 2;
3197 if ((insn & (1 << 23)) == 0)
3198 offset = -offset;
3199 tcg_gen_addi_i32(addr, addr, offset);
3200 if (insn & (1 << 20)) {
3201 gen_vfp_ld(s, dp, addr);
3202 gen_mov_vreg_F0(dp, rd);
3203 } else {
3204 gen_mov_F0_vreg(dp, rd);
3205 gen_vfp_st(s, dp, addr);
3206 }
3207 dead_tmp(addr);
3208 } else {
3209 /* load/store multiple */
3210 if (dp)
3211 n = (insn >> 1) & 0x7f;
3212 else
3213 n = insn & 0xff;
3214
3215 if (insn & (1 << 24)) /* pre-decrement */
3216 tcg_gen_addi_i32(addr, addr, -((insn & 0xff) << 2));
3217
3218 if (dp)
3219 offset = 8;
3220 else
3221 offset = 4;
3222 for (i = 0; i < n; i++) {
3223 if (insn & ARM_CP_RW_BIT) {
3224 /* load */
3225 gen_vfp_ld(s, dp, addr);
3226 gen_mov_vreg_F0(dp, rd + i);
3227 } else {
3228 /* store */
3229 gen_mov_F0_vreg(dp, rd + i);
3230 gen_vfp_st(s, dp, addr);
3231 }
3232 tcg_gen_addi_i32(addr, addr, offset);
3233 }
3234 if (insn & (1 << 21)) {
3235 /* writeback */
3236 if (insn & (1 << 24))
3237 offset = -offset * n;
3238 else if (dp && (insn & 1))
3239 offset = 4;
3240 else
3241 offset = 0;
3242
3243 if (offset != 0)
3244 tcg_gen_addi_i32(addr, addr, offset);
3245 store_reg(s, rn, addr);
3246 } else {
3247 dead_tmp(addr);
3248 }
3249 }
3250 }
3251 break;
3252 default:
3253 /* Should never happen. */
3254 return 1;
3255 }
3256 return 0;
3257 }
3258
3259 static inline void gen_goto_tb(DisasContext *s, int n, uint32_t dest)
3260 {
3261 TranslationBlock *tb;
3262
3263 tb = s->tb;
3264 if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK)) {
3265 tcg_gen_goto_tb(n);
3266 gen_set_pc_im(dest);
3267 tcg_gen_exit_tb((long)tb + n);
3268 } else {
3269 gen_set_pc_im(dest);
3270 tcg_gen_exit_tb(0);
3271 }
3272 }
3273
3274 static inline void gen_jmp (DisasContext *s, uint32_t dest)
3275 {
3276 if (unlikely(s->singlestep_enabled)) {
3277 /* An indirect jump so that we still trigger the debug exception. */
3278 if (s->thumb)
3279 dest |= 1;
3280 gen_bx_im(s, dest);
3281 } else {
3282 gen_goto_tb(s, 0, dest);
3283 s->is_jmp = DISAS_TB_JUMP;
3284 }
3285 }
3286
3287 static inline void gen_mulxy(TCGv t0, TCGv t1, int x, int y)
3288 {
3289 if (x)
3290 tcg_gen_sari_i32(t0, t0, 16);
3291 else
3292 gen_sxth(t0);
3293 if (y)
3294 tcg_gen_sari_i32(t1, t1, 16);
3295 else
3296 gen_sxth(t1);
3297 tcg_gen_mul_i32(t0, t0, t1);
3298 }
3299
3300 /* Return the mask of PSR bits set by a MSR instruction. */
3301 static uint32_t msr_mask(CPUState *env, DisasContext *s, int flags, int spsr) {
3302 uint32_t mask;
3303
3304 mask = 0;
3305 if (flags & (1 << 0))
3306 mask |= 0xff;
3307 if (flags & (1 << 1))
3308 mask |= 0xff00;
3309 if (flags & (1 << 2))
3310 mask |= 0xff0000;
3311 if (flags & (1 << 3))
3312 mask |= 0xff000000;
3313
3314 /* Mask out undefined bits. */
3315 mask &= ~CPSR_RESERVED;
3316 if (!arm_feature(env, ARM_FEATURE_V6))
3317 mask &= ~(CPSR_E | CPSR_GE);
3318 if (!arm_feature(env, ARM_FEATURE_THUMB2))
3319 mask &= ~CPSR_IT;
3320 /* Mask out execution state bits. */
3321 if (!spsr)
3322 mask &= ~CPSR_EXEC;
3323 /* Mask out privileged bits. */
3324 if (IS_USER(s))
3325 mask &= CPSR_USER;
3326 return mask;
3327 }
3328
3329 /* Returns nonzero if access to the PSR is not permitted. Marks t0 as dead. */
3330 static int gen_set_psr(DisasContext *s, uint32_t mask, int spsr, TCGv t0)
3331 {
3332 TCGv tmp;
3333 if (spsr) {
3334 /* ??? This is also undefined in system mode. */
3335 if (IS_USER(s))
3336 return 1;
3337
3338 tmp = load_cpu_field(spsr);
3339 tcg_gen_andi_i32(tmp, tmp, ~mask);
3340 tcg_gen_andi_i32(t0, t0, mask);
3341 tcg_gen_or_i32(tmp, tmp, t0);
3342 store_cpu_field(tmp, spsr);
3343 } else {
3344 gen_set_cpsr(t0, mask);
3345 }
3346 dead_tmp(t0);
3347 gen_lookup_tb(s);
3348 return 0;
3349 }
3350
3351 /* Returns nonzero if access to the PSR is not permitted. */
3352 static int gen_set_psr_im(DisasContext *s, uint32_t mask, int spsr, uint32_t val)
3353 {
3354 TCGv tmp;
3355 tmp = new_tmp();
3356 tcg_gen_movi_i32(tmp, val);
3357 return gen_set_psr(s, mask, spsr, tmp);
3358 }
3359
3360 /* Generate an old-style exception return. Marks pc as dead. */
3361 static void gen_exception_return(DisasContext *s, TCGv pc)
3362 {
3363 TCGv tmp;
3364 store_reg(s, 15, pc);
3365 tmp = load_cpu_field(spsr);
3366 gen_set_cpsr(tmp, 0xffffffff);
3367 dead_tmp(tmp);
3368 s->is_jmp = DISAS_UPDATE;
3369 }
3370
3371 /* Generate a v6 exception return. Marks both values as dead. */
3372 static void gen_rfe(DisasContext *s, TCGv pc, TCGv cpsr)
3373 {
3374 gen_set_cpsr(cpsr, 0xffffffff);
3375 dead_tmp(cpsr);
3376 store_reg(s, 15, pc);
3377 s->is_jmp = DISAS_UPDATE;
3378 }
3379
3380 static inline void
3381 gen_set_condexec (DisasContext *s)
3382 {
3383 if (s->condexec_mask) {
3384 uint32_t val = (s->condexec_cond << 4) | (s->condexec_mask >> 1);
3385 TCGv tmp = new_tmp();
3386 tcg_gen_movi_i32(tmp, val);
3387 store_cpu_field(tmp, condexec_bits);
3388 }
3389 }
3390
3391 static void gen_nop_hint(DisasContext *s, int val)
3392 {
3393 switch (val) {
3394 case 3: /* wfi */
3395 gen_set_pc_im(s->pc);
3396 s->is_jmp = DISAS_WFI;
3397 break;
3398 case 2: /* wfe */
3399 case 4: /* sev */
3400 /* TODO: Implement SEV and WFE. May help SMP performance. */
3401 default: /* nop */
3402 break;
3403 }
3404 }
3405
3406 #define CPU_V001 cpu_V0, cpu_V0, cpu_V1
3407
3408 static inline int gen_neon_add(int size, TCGv t0, TCGv t1)
3409 {
3410 switch (size) {
3411 case 0: gen_helper_neon_add_u8(t0, t0, t1); break;
3412 case 1: gen_helper_neon_add_u16(t0, t0, t1); break;
3413 case 2: tcg_gen_add_i32(t0, t0, t1); break;
3414 default: return 1;
3415 }
3416 return 0;
3417 }
3418
3419 static inline void gen_neon_rsb(int size, TCGv t0, TCGv t1)
3420 {
3421 switch (size) {
3422 case 0: gen_helper_neon_sub_u8(t0, t1, t0); break;
3423 case 1: gen_helper_neon_sub_u16(t0, t1, t0); break;
3424 case 2: tcg_gen_sub_i32(t0, t1, t0); break;
3425 default: return;
3426 }
3427 }
3428
3429 /* 32-bit pairwise ops end up the same as the elementwise versions. */
3430 #define gen_helper_neon_pmax_s32 gen_helper_neon_max_s32
3431 #define gen_helper_neon_pmax_u32 gen_helper_neon_max_u32
3432 #define gen_helper_neon_pmin_s32 gen_helper_neon_min_s32
3433 #define gen_helper_neon_pmin_u32 gen_helper_neon_min_u32
3434
3435 /* FIXME: This is wrong. They set the wrong overflow bit. */
3436 #define gen_helper_neon_qadd_s32(a, e, b, c) gen_helper_add_saturate(a, b, c)
3437 #define gen_helper_neon_qadd_u32(a, e, b, c) gen_helper_add_usaturate(a, b, c)
3438 #define gen_helper_neon_qsub_s32(a, e, b, c) gen_helper_sub_saturate(a, b, c)
3439 #define gen_helper_neon_qsub_u32(a, e, b, c) gen_helper_sub_usaturate(a, b, c)
3440
3441 #define GEN_NEON_INTEGER_OP_ENV(name) do { \
3442 switch ((size << 1) | u) { \
3443 case 0: \
3444 gen_helper_neon_##name##_s8(tmp, cpu_env, tmp, tmp2); \
3445 break; \
3446 case 1: \
3447 gen_helper_neon_##name##_u8(tmp, cpu_env, tmp, tmp2); \
3448 break; \
3449 case 2: \
3450 gen_helper_neon_##name##_s16(tmp, cpu_env, tmp, tmp2); \
3451 break; \
3452 case 3: \
3453 gen_helper_neon_##name##_u16(tmp, cpu_env, tmp, tmp2); \
3454 break; \
3455 case 4: \
3456 gen_helper_neon_##name##_s32(tmp, cpu_env, tmp, tmp2); \
3457 break; \
3458 case 5: \
3459 gen_helper_neon_##name##_u32(tmp, cpu_env, tmp, tmp2); \
3460 break; \
3461 default: return 1; \
3462 }} while (0)
3463
3464 #define GEN_NEON_INTEGER_OP(name) do { \
3465 switch ((size << 1) | u) { \
3466 case 0: \
3467 gen_helper_neon_##name##_s8(tmp, tmp, tmp2); \
3468 break; \
3469 case 1: \
3470 gen_helper_neon_##name##_u8(tmp, tmp, tmp2); \
3471 break; \
3472 case 2: \
3473 gen_helper_neon_##name##_s16(tmp, tmp, tmp2); \
3474 break; \
3475 case 3: \
3476 gen_helper_neon_##name##_u16(tmp, tmp, tmp2); \
3477 break; \
3478 case 4: \
3479 gen_helper_neon_##name##_s32(tmp, tmp, tmp2); \
3480 break; \
3481 case 5: \
3482 gen_helper_neon_##name##_u32(tmp, tmp, tmp2); \
3483 break; \
3484 default: return 1; \
3485 }} while (0)
3486
3487 static TCGv neon_load_scratch(int scratch)
3488 {
3489 TCGv tmp = new_tmp();
3490 tcg_gen_ld_i32(tmp, cpu_env, offsetof(CPUARMState, vfp.scratch[scratch]));
3491 return tmp;
3492 }
3493
3494 static void neon_store_scratch(int scratch, TCGv var)
3495 {
3496 tcg_gen_st_i32(var, cpu_env, offsetof(CPUARMState, vfp.scratch[scratch]));
3497 dead_tmp(var);
3498 }
3499
3500 static inline TCGv neon_get_scalar(int size, int reg)
3501 {
3502 TCGv tmp;
3503 if (size == 1) {
3504 tmp = neon_load_reg(reg >> 1, reg & 1);
3505 } else {
3506 tmp = neon_load_reg(reg >> 2, (reg >> 1) & 1);
3507 if (reg & 1) {
3508 gen_neon_dup_low16(tmp);
3509 } else {
3510 gen_neon_dup_high16(tmp);
3511 }
3512 }
3513 return tmp;
3514 }
3515
3516 static void gen_neon_unzip_u8(TCGv t0, TCGv t1)
3517 {
3518 TCGv rd, rm, tmp;
3519
3520 rd = new_tmp();
3521 rm = new_tmp();
3522 tmp = new_tmp();
3523
3524 tcg_gen_andi_i32(rd, t0, 0xff);
3525 tcg_gen_shri_i32(tmp, t0, 8);
3526 tcg_gen_andi_i32(tmp, tmp, 0xff00);
3527 tcg_gen_or_i32(rd, rd, tmp);
3528 tcg_gen_shli_i32(tmp, t1, 16);
3529 tcg_gen_andi_i32(tmp, tmp, 0xff0000);
3530 tcg_gen_or_i32(rd, rd, tmp);
3531 tcg_gen_shli_i32(tmp, t1, 8);
3532 tcg_gen_andi_i32(tmp, tmp, 0xff000000);
3533 tcg_gen_or_i32(rd, rd, tmp);
3534
3535 tcg_gen_shri_i32(rm, t0, 8);
3536 tcg_gen_andi_i32(rm, rm, 0xff);
3537 tcg_gen_shri_i32(tmp, t0, 16);
3538 tcg_gen_andi_i32(tmp, tmp, 0xff00);
3539 tcg_gen_or_i32(rm, rm, tmp);
3540 tcg_gen_shli_i32(tmp, t1, 8);
3541 tcg_gen_andi_i32(tmp, tmp, 0xff0000);
3542 tcg_gen_or_i32(rm, rm, tmp);
3543 tcg_gen_andi_i32(tmp, t1, 0xff000000);
3544 tcg_gen_or_i32(t1, rm, tmp);
3545 tcg_gen_mov_i32(t0, rd);
3546
3547 dead_tmp(tmp);
3548 dead_tmp(rm);
3549 dead_tmp(rd);
3550 }
3551
3552 static void gen_neon_zip_u8(TCGv t0, TCGv t1)
3553 {
3554 TCGv rd, rm, tmp;
3555
3556 rd = new_tmp();
3557 rm = new_tmp();
3558 tmp = new_tmp();
3559
3560 tcg_gen_andi_i32(rd, t0, 0xff);
3561 tcg_gen_shli_i32(tmp, t1, 8);
3562 tcg_gen_andi_i32(tmp, tmp, 0xff00);
3563 tcg_gen_or_i32(rd, rd, tmp);
3564 tcg_gen_shli_i32(tmp, t0, 16);
3565 tcg_gen_andi_i32(tmp, tmp, 0xff0000);
3566 tcg_gen_or_i32(rd, rd, tmp);
3567 tcg_gen_shli_i32(tmp, t1, 24);
3568 tcg_gen_andi_i32(tmp, tmp, 0xff000000);
3569 tcg_gen_or_i32(rd, rd, tmp);
3570
3571 tcg_gen_andi_i32(rm, t1, 0xff000000);
3572 tcg_gen_shri_i32(tmp, t0, 8);
3573 tcg_gen_andi_i32(tmp, tmp, 0xff0000);
3574 tcg_gen_or_i32(rm, rm, tmp);
3575 tcg_gen_shri_i32(tmp, t1, 8);
3576 tcg_gen_andi_i32(tmp, tmp, 0xff00);
3577 tcg_gen_or_i32(rm, rm, tmp);
3578 tcg_gen_shri_i32(tmp, t0, 16);
3579 tcg_gen_andi_i32(tmp, tmp, 0xff);
3580 tcg_gen_or_i32(t1, rm, tmp);
3581 tcg_gen_mov_i32(t0, rd);
3582
3583 dead_tmp(tmp);
3584 dead_tmp(rm);
3585 dead_tmp(rd);
3586 }
3587
3588 static void gen_neon_zip_u16(TCGv t0, TCGv t1)
3589 {
3590 TCGv tmp, tmp2;
3591
3592 tmp = new_tmp();
3593 tmp2 = new_tmp();
3594
3595 tcg_gen_andi_i32(tmp, t0, 0xffff);
3596 tcg_gen_shli_i32(tmp2, t1, 16);
3597 tcg_gen_or_i32(tmp, tmp, tmp2);
3598 tcg_gen_andi_i32(t1, t1, 0xffff0000);
3599 tcg_gen_shri_i32(tmp2, t0, 16);
3600 tcg_gen_or_i32(t1, t1, tmp2);
3601 tcg_gen_mov_i32(t0, tmp);
3602
3603 dead_tmp(tmp2);
3604 dead_tmp(tmp);
3605 }
3606
3607 static void gen_neon_unzip(int reg, int q, int tmp, int size)
3608 {
3609 int n;
3610 TCGv t0, t1;
3611
3612 for (n = 0; n < q + 1; n += 2) {
3613 t0 = neon_load_reg(reg, n);
3614 t1 = neon_load_reg(reg, n + 1);
3615 switch (size) {
3616 case 0: gen_neon_unzip_u8(t0, t1); break;
3617 case 1: gen_neon_zip_u16(t0, t1); break; /* zip and unzip are the same. */
3618 case 2: /* no-op */; break;
3619 default: abort();
3620 }
3621 neon_store_scratch(tmp + n, t0);
3622 neon_store_scratch(tmp + n + 1, t1);
3623 }
3624 }
3625
3626 static void gen_neon_trn_u8(TCGv t0, TCGv t1)
3627 {
3628 TCGv rd, tmp;
3629
3630 rd = new_tmp();
3631 tmp = new_tmp();
3632
3633 tcg_gen_shli_i32(rd, t0, 8);
3634 tcg_gen_andi_i32(rd, rd, 0xff00ff00);
3635 tcg_gen_andi_i32(tmp, t1, 0x00ff00ff);
3636 tcg_gen_or_i32(rd, rd, tmp);
3637
3638 tcg_gen_shri_i32(t1, t1, 8);
3639 tcg_gen_andi_i32(t1, t1, 0x00ff00ff);
3640 tcg_gen_andi_i32(tmp, t0, 0xff00ff00);
3641 tcg_gen_or_i32(t1, t1, tmp);
3642 tcg_gen_mov_i32(t0, rd);
3643
3644 dead_tmp(tmp);
3645 dead_tmp(rd);
3646 }
3647
3648 static void gen_neon_trn_u16(TCGv t0, TCGv t1)
3649 {
3650 TCGv rd, tmp;
3651
3652 rd = new_tmp();
3653 tmp = new_tmp();
3654
3655 tcg_gen_shli_i32(rd, t0, 16);
3656 tcg_gen_andi_i32(tmp, t1, 0xffff);
3657 tcg_gen_or_i32(rd, rd, tmp);
3658 tcg_gen_shri_i32(t1, t1, 16);
3659 tcg_gen_andi_i32(tmp, t0, 0xffff0000);
3660 tcg_gen_or_i32(t1, t1, tmp);
3661 tcg_gen_mov_i32(t0, rd);
3662
3663 dead_tmp(tmp);
3664 dead_tmp(rd);
3665 }
3666
3667
3668 static struct {
3669 int nregs;
3670 int interleave;
3671 int spacing;
3672 } neon_ls_element_type[11] = {
3673 {4, 4, 1},
3674 {4, 4, 2},
3675 {4, 1, 1},
3676 {4, 2, 1},
3677 {3, 3, 1},
3678 {3, 3, 2},
3679 {3, 1, 1},
3680 {1, 1, 1},
3681 {2, 2, 1},
3682 {2, 2, 2},
3683 {2, 1, 1}
3684 };
3685
3686 /* Translate a NEON load/store element instruction. Return nonzero if the
3687 instruction is invalid. */
3688 static int disas_neon_ls_insn(CPUState * env, DisasContext *s, uint32_t insn)
3689 {
3690 int rd, rn, rm;
3691 int op;
3692 int nregs;
3693 int interleave;
3694 int spacing;
3695 int stride;
3696 int size;
3697 int reg;
3698 int pass;
3699 int load;
3700 int shift;
3701 int n;
3702 TCGv addr;
3703 TCGv tmp;
3704 TCGv tmp2;
3705 TCGv_i64 tmp64;
3706
3707 if (!vfp_enabled(env))
3708 return 1;
3709 VFP_DREG_D(rd, insn);
3710 rn = (insn >> 16) & 0xf;
3711 rm = insn & 0xf;
3712 load = (insn & (1 << 21)) != 0;
3713 addr = new_tmp();
3714 if ((insn & (1 << 23)) == 0) {
3715 /* Load store all elements. */
3716 op = (insn >> 8) & 0xf;
3717 size = (insn >> 6) & 3;
3718 if (op > 10)
3719 return 1;
3720 nregs = neon_ls_element_type[op].nregs;
3721 interleave = neon_ls_element_type[op].interleave;
3722 spacing = neon_ls_element_type[op].spacing;
3723 if (size == 3 && (interleave | spacing) != 1)
3724 return 1;
3725 load_reg_var(s, addr, rn);
3726 stride = (1 << size) * interleave;
3727 for (reg = 0; reg < nregs; reg++) {
3728 if (interleave > 2 || (interleave == 2 && nregs == 2)) {
3729 load_reg_var(s, addr, rn);
3730 tcg_gen_addi_i32(addr, addr, (1 << size) * reg);
3731 } else if (interleave == 2 && nregs == 4 && reg == 2) {
3732 load_reg_var(s, addr, rn);
3733 tcg_gen_addi_i32(addr, addr, 1 << size);
3734 }
3735 if (size == 3) {
3736 if (load) {
3737 tmp64 = gen_ld64(addr, IS_USER(s));
3738 neon_store_reg64(tmp64, rd);
3739 tcg_temp_free_i64(tmp64);
3740 } else {
3741 tmp64 = tcg_temp_new_i64();
3742 neon_load_reg64(tmp64, rd);
3743 gen_st64(tmp64, addr, IS_USER(s));
3744 }
3745 tcg_gen_addi_i32(addr, addr, stride);
3746 } else {
3747 for (pass = 0; pass < 2; pass++) {
3748 if (size == 2) {
3749 if (load) {
3750 tmp = gen_ld32(addr, IS_USER(s));
3751 neon_store_reg(rd, pass, tmp);
3752 } else {
3753 tmp = neon_load_reg(rd, pass);
3754 gen_st32(tmp, addr, IS_USER(s));
3755 }
3756 tcg_gen_addi_i32(addr, addr, stride);
3757 } else if (size == 1) {
3758 if (load) {
3759 tmp = gen_ld16u(addr, IS_USER(s));
3760 tcg_gen_addi_i32(addr, addr, stride);
3761 tmp2 = gen_ld16u(addr, IS_USER(s));
3762 tcg_gen_addi_i32(addr, addr, stride);
3763 gen_bfi(tmp, tmp, tmp2, 16, 0xffff);
3764 dead_tmp(tmp2);
3765 neon_store_reg(rd, pass, tmp);
3766 } else {
3767 tmp = neon_load_reg(rd, pass);
3768 tmp2 = new_tmp();
3769 tcg_gen_shri_i32(tmp2, tmp, 16);
3770 gen_st16(tmp, addr, IS_USER(s));
3771 tcg_gen_addi_i32(addr, addr, stride);
3772 gen_st16(tmp2, addr, IS_USER(s));
3773 tcg_gen_addi_i32(addr, addr, stride);
3774 }
3775 } else /* size == 0 */ {
3776 if (load) {
3777 TCGV_UNUSED(tmp2);
3778 for (n = 0; n < 4; n++) {
3779 tmp = gen_ld8u(addr, IS_USER(s));
3780 tcg_gen_addi_i32(addr, addr, stride);
3781 if (n == 0) {
3782 tmp2 = tmp;
3783 } else {
3784 gen_bfi(tmp2, tmp2, tmp, n * 8, 0xff);
3785 dead_tmp(tmp);
3786 }
3787 }
3788 neon_store_reg(rd, pass, tmp2);
3789 } else {
3790 tmp2 = neon_load_reg(rd, pass);
3791 for (n = 0; n < 4; n++) {
3792 tmp = new_tmp();
3793 if (n == 0) {
3794 tcg_gen_mov_i32(tmp, tmp2);
3795 } else {
3796 tcg_gen_shri_i32(tmp, tmp2, n * 8);
3797 }
3798 gen_st8(tmp, addr, IS_USER(s));
3799 tcg_gen_addi_i32(addr, addr, stride);
3800 }
3801 dead_tmp(tmp2);
3802 }
3803 }
3804 }
3805 }
3806 rd += spacing;
3807 }
3808 stride = nregs * 8;
3809 } else {
3810 size = (insn >> 10) & 3;
3811 if (size == 3) {
3812 /* Load single element to all lanes. */
3813 if (!load)
3814 return 1;
3815 size = (insn >> 6) & 3;
3816 nregs = ((insn >> 8) & 3) + 1;
3817 stride = (insn & (1 << 5)) ? 2 : 1;
3818 load_reg_var(s, addr, rn);
3819 for (reg = 0; reg < nregs; reg++) {
3820 switch (size) {
3821 case 0:
3822 tmp = gen_ld8u(addr, IS_USER(s));
3823 gen_neon_dup_u8(tmp, 0);
3824 break;
3825 case 1:
3826 tmp = gen_ld16u(addr, IS_USER(s));
3827 gen_neon_dup_low16(tmp);
3828 break;
3829 case 2:
3830 tmp = gen_ld32(addr, IS_USER(s));
3831 break;
3832 case 3:
3833 return 1;
3834 default: /* Avoid compiler warnings. */
3835 abort();
3836 }
3837 tcg_gen_addi_i32(addr, addr, 1 << size);
3838 tmp2 = new_tmp();
3839 tcg_gen_mov_i32(tmp2, tmp);
3840 neon_store_reg(rd, 0, tmp2);
3841 neon_store_reg(rd, 1, tmp);
3842 rd += stride;
3843 }
3844 stride = (1 << size) * nregs;
3845 } else {
3846 /* Single element. */
3847 pass = (insn >> 7) & 1;
3848 switch (size) {
3849 case 0:
3850 shift = ((insn >> 5) & 3) * 8;
3851 stride = 1;
3852 break;
3853 case 1:
3854 shift = ((insn >> 6) & 1) * 16;
3855 stride = (insn & (1 << 5)) ? 2 : 1;
3856 break;
3857 case 2:
3858 shift = 0;
3859 stride = (insn & (1 << 6)) ? 2 : 1;
3860 break;
3861 default:
3862 abort();
3863 }
3864 nregs = ((insn >> 8) & 3) + 1;
3865 load_reg_var(s, addr, rn);
3866 for (reg = 0; reg < nregs; reg++) {
3867 if (load) {
3868 switch (size) {
3869 case 0:
3870 tmp = gen_ld8u(addr, IS_USER(s));
3871 break;
3872 case 1:
3873 tmp = gen_ld16u(addr, IS_USER(s));
3874 break;
3875 case 2:
3876 tmp = gen_ld32(addr, IS_USER(s));
3877 break;
3878 default: /* Avoid compiler warnings. */
3879 abort();
3880 }
3881 if (size != 2) {
3882 tmp2 = neon_load_reg(rd, pass);
3883 gen_bfi(tmp, tmp2, tmp, shift, size ? 0xffff : 0xff);
3884 dead_tmp(tmp2);
3885 }
3886 neon_store_reg(rd, pass, tmp);
3887 } else { /* Store */
3888 tmp = neon_load_reg(rd, pass);
3889 if (shift)
3890 tcg_gen_shri_i32(tmp, tmp, shift);
3891 switch (size) {
3892 case 0:
3893 gen_st8(tmp, addr, IS_USER(s));
3894 break;
3895 case 1:
3896 gen_st16(tmp, addr, IS_USER(s));
3897 break;
3898 case 2:
3899 gen_st32(tmp, addr, IS_USER(s));
3900 break;
3901 }
3902 }
3903 rd += stride;
3904 tcg_gen_addi_i32(addr, addr, 1 << size);
3905 }
3906 stride = nregs * (1 << size);
3907 }
3908 }
3909 dead_tmp(addr);
3910 if (rm != 15) {
3911 TCGv base;
3912
3913 base = load_reg(s, rn);
3914 if (rm == 13) {
3915 tcg_gen_addi_i32(base, base, stride);
3916 } else {
3917 TCGv index;
3918 index = load_reg(s, rm);
3919 tcg_gen_add_i32(base, base, index);
3920 dead_tmp(index);
3921 }
3922 store_reg(s, rn, base);
3923 }
3924 return 0;
3925 }
3926
3927 /* Bitwise select. dest = c ? t : f. Clobbers T and F. */
3928 static void gen_neon_bsl(TCGv dest, TCGv t, TCGv f, TCGv c)
3929 {
3930 tcg_gen_and_i32(t, t, c);
3931 tcg_gen_bic_i32(f, f, c);
3932 tcg_gen_or_i32(dest, t, f);
3933 }
3934
3935 static inline void gen_neon_narrow(int size, TCGv dest, TCGv_i64 src)
3936 {
3937 switch (size) {
3938 case 0: gen_helper_neon_narrow_u8(dest, src); break;
3939 case 1: gen_helper_neon_narrow_u16(dest, src); break;
3940 case 2: tcg_gen_trunc_i64_i32(dest, src); break;
3941 default: abort();
3942 }
3943 }
3944
3945 static inline void gen_neon_narrow_sats(int size, TCGv dest, TCGv_i64 src)
3946 {
3947 switch (size) {
3948 case 0: gen_helper_neon_narrow_sat_s8(dest, cpu_env, src); break;
3949 case 1: gen_helper_neon_narrow_sat_s16(dest, cpu_env, src); break;
3950 case 2: gen_helper_neon_narrow_sat_s32(dest, cpu_env, src); break;
3951 default: abort();
3952 }
3953 }
3954
3955 static inline void gen_neon_narrow_satu(int size, TCGv dest, TCGv_i64 src)
3956 {
3957 switch (size) {
3958 case 0: gen_helper_neon_narrow_sat_u8(dest, cpu_env, src); break;
3959 case 1: gen_helper_neon_narrow_sat_u16(dest, cpu_env, src); break;
3960 case 2: gen_helper_neon_narrow_sat_u32(dest, cpu_env, src); break;
3961 default: abort();
3962 }
3963 }
3964
3965 static inline void gen_neon_shift_narrow(int size, TCGv var, TCGv shift,
3966 int q, int u)
3967 {
3968 if (q) {
3969 if (u) {
3970 switch (size) {
3971 case 1: gen_helper_neon_rshl_u16(var, var, shift); break;
3972 case 2: gen_helper_neon_rshl_u32(var, var, shift); break;
3973 default: abort();
3974 }
3975 } else {
3976 switch (size) {
3977 case 1: gen_helper_neon_rshl_s16(var, var, shift); break;
3978 case 2: gen_helper_neon_rshl_s32(var, var, shift); break;
3979 default: abort();
3980 }
3981 }
3982 } else {
3983 if (u) {
3984 switch (size) {
3985 case 1: gen_helper_neon_rshl_u16(var, var, shift); break;
3986 case 2: gen_helper_neon_rshl_u32(var, var, shift); break;
3987 default: abort();
3988 }
3989 } else {
3990 switch (size) {
3991 case 1: gen_helper_neon_shl_s16(var, var, shift); break;
3992 case 2: gen_helper_neon_shl_s32(var, var, shift); break;
3993 default: abort();
3994 }
3995 }
3996 }
3997 }
3998
3999 static inline void gen_neon_widen(TCGv_i64 dest, TCGv src, int size, int u)
4000 {
4001 if (u) {
4002 switch (size) {
4003 case 0: gen_helper_neon_widen_u8(dest, src); break;
4004 case 1: gen_helper_neon_widen_u16(dest, src); break;
4005 case 2: tcg_gen_extu_i32_i64(dest, src); break;
4006 default: abort();
4007 }
4008 } else {
4009 switch (size) {
4010 case 0: gen_helper_neon_widen_s8(dest, src); break;
4011 case 1: gen_helper_neon_widen_s16(dest, src); break;
4012 case 2: tcg_gen_ext_i32_i64(dest, src); break;
4013 default: abort();
4014 }
4015 }
4016 dead_tmp(src);
4017 }
4018
4019 static inline void gen_neon_addl(int size)
4020 {
4021 switch (size) {
4022 case 0: gen_helper_neon_addl_u16(CPU_V001); break;
4023 case 1: gen_helper_neon_addl_u32(CPU_V001); break;
4024 case 2: tcg_gen_add_i64(CPU_V001); break;
4025 default: abort();
4026 }
4027 }
4028
4029 static inline void gen_neon_subl(int size)
4030 {
4031 switch (size) {
4032 case 0: gen_helper_neon_subl_u16(CPU_V001); break;
4033 case 1: gen_helper_neon_subl_u32(CPU_V001); break;
4034 case 2: tcg_gen_sub_i64(CPU_V001); break;
4035 default: abort();
4036 }
4037 }
4038
4039 static inline void gen_neon_negl(TCGv_i64 var, int size)
4040 {
4041 switch (size) {
4042 case 0: gen_helper_neon_negl_u16(var, var); break;
4043 case 1: gen_helper_neon_negl_u32(var, var); break;
4044 case 2: gen_helper_neon_negl_u64(var, var); break;
4045 default: abort();
4046 }
4047 }
4048
4049 static inline void gen_neon_addl_saturate(TCGv_i64 op0, TCGv_i64 op1, int size)
4050 {
4051 switch (size) {
4052 case 1: gen_helper_neon_addl_saturate_s32(op0, cpu_env, op0, op1); break;
4053 case 2: gen_helper_neon_addl_saturate_s64(op0, cpu_env, op0, op1); break;
4054 default: abort();
4055 }
4056 }
4057
4058 static inline void gen_neon_mull(TCGv_i64 dest, TCGv a, TCGv b, int size, int u)
4059 {
4060 TCGv_i64 tmp;
4061
4062 switch ((size << 1) | u) {
4063 case 0: gen_helper_neon_mull_s8(dest, a, b); break;
4064 case 1: gen_helper_neon_mull_u8(dest, a, b); break;
4065 case 2: gen_helper_neon_mull_s16(dest, a, b); break;
4066 case 3: gen_helper_neon_mull_u16(dest, a, b); break;
4067 case 4:
4068 tmp = gen_muls_i64_i32(a, b);
4069 tcg_gen_mov_i64(dest, tmp);
4070 break;
4071 case 5:
4072 tmp = gen_mulu_i64_i32(a, b);
4073 tcg_gen_mov_i64(dest, tmp);
4074 break;
4075 default: abort();
4076 }
4077 }
4078
4079 /* Translate a NEON data processing instruction. Return nonzero if the
4080 instruction is invalid.
4081 We process data in a mixture of 32-bit and 64-bit chunks.
4082 Mostly we use 32-bit chunks so we can use normal scalar instructions. */
4083
4084 static int disas_neon_data_insn(CPUState * env, DisasContext *s, uint32_t insn)
4085 {
4086 int op;
4087 int q;
4088 int rd, rn, rm;
4089 int size;
4090 int shift;
4091 int pass;
4092 int count;
4093 int pairwise;
4094 int u;
4095 int n;
4096 uint32_t imm;
4097 TCGv tmp, tmp2, tmp3, tmp4, tmp5;
4098 TCGv_i64 tmp64;
4099
4100 if (!vfp_enabled(env))
4101 return 1;
4102 q = (insn & (1 << 6)) != 0;
4103 u = (insn >> 24) & 1;
4104 VFP_DREG_D(rd, insn);
4105 VFP_DREG_N(rn, insn);
4106 VFP_DREG_M(rm, insn);
4107 size = (insn >> 20) & 3;
4108 if ((insn & (1 << 23)) == 0) {
4109 /* Three register same length. */
4110 op = ((insn >> 7) & 0x1e) | ((insn >> 4) & 1);
4111 if (size == 3 && (op == 1 || op == 5 || op == 8 || op == 9
4112 || op == 10 || op == 11 || op == 16)) {
4113 /* 64-bit element instructions. */
4114 for (pass = 0; pass < (q ? 2 : 1); pass++) {
4115 neon_load_reg64(cpu_V0, rn + pass);
4116 neon_load_reg64(cpu_V1, rm + pass);
4117 switch (op) {
4118 case 1: /* VQADD */
4119 if (u) {
4120 gen_helper_neon_add_saturate_u64(CPU_V001);
4121 } else {
4122 gen_helper_neon_add_saturate_s64(CPU_V001);
4123 }
4124 break;
4125 case 5: /* VQSUB */
4126 if (u) {
4127 gen_helper_neon_sub_saturate_u64(CPU_V001);
4128 } else {
4129 gen_helper_neon_sub_saturate_s64(CPU_V001);
4130 }
4131 break;
4132 case 8: /* VSHL */
4133 if (u) {
4134 gen_helper_neon_shl_u64(cpu_V0, cpu_V1, cpu_V0);
4135 } else {
4136 gen_helper_neon_shl_s64(cpu_V0, cpu_V1, cpu_V0);
4137 }
4138 break;
4139 case 9: /* VQSHL */
4140 if (u) {
4141 gen_helper_neon_qshl_u64(cpu_V0, cpu_env,
4142 cpu_V0, cpu_V0);
4143 } else {
4144 gen_helper_neon_qshl_s64(cpu_V1, cpu_env,
4145 cpu_V1, cpu_V0);
4146 }
4147 break;
4148 case 10: /* VRSHL */
4149 if (u) {
4150 gen_helper_neon_rshl_u64(cpu_V0, cpu_V1, cpu_V0);
4151 } else {
4152 gen_helper_neon_rshl_s64(cpu_V0, cpu_V1, cpu_V0);
4153 }
4154 break;
4155 case 11: /* VQRSHL */
4156 if (u) {
4157 gen_helper_neon_qrshl_u64(cpu_V0, cpu_env,
4158 cpu_V1, cpu_V0);
4159 } else {
4160 gen_helper_neon_qrshl_s64(cpu_V0, cpu_env,
4161 cpu_V1, cpu_V0);
4162 }
4163 break;
4164 case 16:
4165 if (u) {
4166 tcg_gen_sub_i64(CPU_V001);
4167 } else {
4168 tcg_gen_add_i64(CPU_V001);
4169 }
4170 break;
4171 default:
4172 abort();
4173 }
4174 neon_store_reg64(cpu_V0, rd + pass);
4175 }
4176 return 0;
4177 }
4178 switch (op) {
4179 case 8: /* VSHL */
4180 case 9: /* VQSHL */
4181 case 10: /* VRSHL */
4182 case 11: /* VQRSHL */
4183 {
4184 int rtmp;
4185 /* Shift instruction operands are reversed. */
4186 rtmp = rn;
4187 rn = rm;
4188 rm = rtmp;
4189 pairwise = 0;
4190 }
4191 break;
4192 case 20: /* VPMAX */
4193 case 21: /* VPMIN */
4194 case 23: /* VPADD */
4195 pairwise = 1;
4196 break;
4197 case 26: /* VPADD (float) */
4198 pairwise = (u && size < 2);
4199 break;
4200 case 30: /* VPMIN/VPMAX (float) */
4201 pairwise = u;
4202 break;
4203 default:
4204 pairwise = 0;
4205 break;
4206 }
4207
4208 for (pass = 0; pass < (q ? 4 : 2); pass++) {
4209
4210 if (pairwise) {
4211 /* Pairwise. */
4212 if (q)
4213 n = (pass & 1) * 2;
4214 else
4215 n = 0;
4216 if (pass < q + 1) {
4217 tmp = neon_load_reg(rn, n);
4218 tmp2 = neon_load_reg(rn, n + 1);
4219 } else {
4220 tmp = neon_load_reg(rm, n);
4221 tmp2 = neon_load_reg(rm, n + 1);
4222 }
4223 } else {
4224 /* Elementwise. */
4225 tmp = neon_load_reg(rn, pass);
4226 tmp2 = neon_load_reg(rm, pass);
4227 }
4228 switch (op) {
4229 case 0: /* VHADD */
4230 GEN_NEON_INTEGER_OP(hadd);
4231 break;
4232 case 1: /* VQADD */
4233 GEN_NEON_INTEGER_OP_ENV(qadd);
4234 break;
4235 case 2: /* VRHADD */
4236 GEN_NEON_INTEGER_OP(rhadd);
4237 break;
4238 case 3: /* Logic ops. */
4239 switch ((u << 2) | size) {
4240 case 0: /* VAND */
4241 tcg_gen_and_i32(tmp, tmp, tmp2);
4242 break;
4243 case 1: /* BIC */
4244 tcg_gen_bic_i32(tmp, tmp, tmp2);
4245 break;
4246 case 2: /* VORR */
4247 tcg_gen_or_i32(tmp, tmp, tmp2);
4248 break;
4249 case 3: /* VORN */
4250 tcg_gen_not_i32(tmp2, tmp2);
4251 tcg_gen_or_i32(tmp, tmp, tmp2);
4252 break;
4253 case 4: /* VEOR */
4254 tcg_gen_xor_i32(tmp, tmp, tmp2);
4255 break;
4256 case 5: /* VBSL */
4257 tmp3 = neon_load_reg(rd, pass);
4258 gen_neon_bsl(tmp, tmp, tmp2, tmp3);
4259 dead_tmp(tmp3);
4260 break;
4261 case 6: /* VBIT */
4262 tmp3 = neon_load_reg(rd, pass);
4263 gen_neon_bsl(tmp, tmp, tmp3, tmp2);
4264 dead_tmp(tmp3);
4265 break;
4266 case 7: /* VBIF */
4267 tmp3 = neon_load_reg(rd, pass);
4268 gen_neon_bsl(tmp, tmp3, tmp, tmp2);
4269 dead_tmp(tmp3);
4270 break;
4271 }
4272 break;
4273 case 4: /* VHSUB */
4274 GEN_NEON_INTEGER_OP(hsub);
4275 break;
4276 case 5: /* VQSUB */
4277 GEN_NEON_INTEGER_OP_ENV(qsub);
4278 break;
4279 case 6: /* VCGT */
4280 GEN_NEON_INTEGER_OP(cgt);
4281 break;
4282 case 7: /* VCGE */
4283 GEN_NEON_INTEGER_OP(cge);
4284 break;
4285 case 8: /* VSHL */
4286 GEN_NEON_INTEGER_OP(shl);
4287 break;
4288 case 9: /* VQSHL */
4289 GEN_NEON_INTEGER_OP_ENV(qshl);
4290 break;
4291 case 10: /* VRSHL */
4292 GEN_NEON_INTEGER_OP(rshl);
4293 break;
4294 case 11: /* VQRSHL */
4295 GEN_NEON_INTEGER_OP_ENV(qrshl);
4296 break;
4297 case 12: /* VMAX */
4298 GEN_NEON_INTEGER_OP(max);
4299 break;
4300 case 13: /* VMIN */
4301 GEN_NEON_INTEGER_OP(min);
4302 break;
4303 case 14: /* VABD */
4304 GEN_NEON_INTEGER_OP(abd);
4305 break;
4306 case 15: /* VABA */
4307 GEN_NEON_INTEGER_OP(abd);
4308 dead_tmp(tmp2);
4309 tmp2 = neon_load_reg(rd, pass);
4310 gen_neon_add(size, tmp, tmp2);
4311 break;
4312 case 16:
4313 if (!u) { /* VADD */
4314 if (gen_neon_add(size, tmp, tmp2))
4315 return 1;
4316 } else { /* VSUB */
4317 switch (size) {
4318 case 0: gen_helper_neon_sub_u8(tmp, tmp, tmp2); break;
4319 case 1: gen_helper_neon_sub_u16(tmp, tmp, tmp2); break;
4320 case 2: tcg_gen_sub_i32(tmp, tmp, tmp2); break;
4321 default: return 1;
4322 }
4323 }
4324 break;
4325 case 17:
4326 if (!u) { /* VTST */
4327 switch (size) {
4328 case 0: gen_helper_neon_tst_u8(tmp, tmp, tmp2); break;
4329 case 1: gen_helper_neon_tst_u16(tmp, tmp, tmp2); break;
4330 case 2: gen_helper_neon_tst_u32(tmp, tmp, tmp2); break;
4331 default: return 1;
4332 }
4333 } else { /* VCEQ */
4334 switch (size) {
4335 case 0: gen_helper_neon_ceq_u8(tmp, tmp, tmp2); break;
4336 case 1: gen_helper_neon_ceq_u16(tmp, tmp, tmp2); break;
4337 case 2: gen_helper_neon_ceq_u32(tmp, tmp, tmp2); break;
4338 default: return 1;
4339 }
4340 }
4341 break;
4342 case 18: /* Multiply. */
4343 switch (size) {
4344 case 0: gen_helper_neon_mul_u8(tmp, tmp, tmp2); break;
4345 case 1: gen_helper_neon_mul_u16(tmp, tmp, tmp2); break;
4346 case 2: tcg_gen_mul_i32(tmp, tmp, tmp2); break;
4347 default: return 1;
4348 }
4349 dead_tmp(tmp2);
4350 tmp2 = neon_load_reg(rd, pass);
4351 if (u) { /* VMLS */
4352 gen_neon_rsb(size, tmp, tmp2);
4353 } else { /* VMLA */
4354 gen_neon_add(size, tmp, tmp2);
4355 }
4356 break;
4357 case 19: /* VMUL */
4358 if (u) { /* polynomial */
4359 gen_helper_neon_mul_p8(tmp, tmp, tmp2);
4360 } else { /* Integer */
4361 switch (size) {
4362 case 0: gen_helper_neon_mul_u8(tmp, tmp, tmp2); break;
4363 case 1: gen_helper_neon_mul_u16(tmp, tmp, tmp2); break;
4364 case 2: tcg_gen_mul_i32(tmp, tmp, tmp2); break;
4365 default: return 1;
4366 }
4367 }
4368 break;
4369 case 20: /* VPMAX */
4370 GEN_NEON_INTEGER_OP(pmax);
4371 break;
4372 case 21: /* VPMIN */
4373 GEN_NEON_INTEGER_OP(pmin);
4374 break;
4375 case 22: /* Hultiply high. */
4376 if (!u) { /* VQDMULH */
4377 switch (size) {
4378 case 1: gen_helper_neon_qdmulh_s16(tmp, cpu_env, tmp, tmp2); break;
4379 case 2: gen_helper_neon_qdmulh_s32(tmp, cpu_env, tmp, tmp2); break;
4380 default: return 1;
4381 }
4382 } else { /* VQRDHMUL */
4383 switch (size) {
4384 case 1: gen_helper_neon_qrdmulh_s16(tmp, cpu_env, tmp, tmp2); break;
4385 case 2: gen_helper_neon_qrdmulh_s32(tmp, cpu_env, tmp, tmp2); break;
4386 default: return 1;
4387 }
4388 }
4389 break;
4390 case 23: /* VPADD */
4391 if (u)
4392 return 1;
4393 switch (size) {
4394 case 0: gen_helper_neon_padd_u8(tmp, tmp, tmp2); break;
4395 case 1: gen_helper_neon_padd_u16(tmp, tmp, tmp2); break;
4396 case 2: tcg_gen_add_i32(tmp, tmp, tmp2); break;
4397 default: return 1;
4398 }
4399 break;
4400 case 26: /* Floating point arithnetic. */
4401 switch ((u << 2) | size) {
4402 case 0: /* VADD */
4403 gen_helper_neon_add_f32(tmp, tmp, tmp2);
4404 break;
4405 case 2: /* VSUB */
4406 gen_helper_neon_sub_f32(tmp, tmp, tmp2);
4407 break;
4408 case 4: /* VPADD */
4409 gen_helper_neon_add_f32(tmp, tmp, tmp2);
4410 break;
4411 case 6: /* VABD */
4412 gen_helper_neon_abd_f32(tmp, tmp, tmp2);
4413 break;
4414 default:
4415 return 1;
4416 }
4417 break;
4418 case 27: /* Float multiply. */
4419 gen_helper_neon_mul_f32(tmp, tmp, tmp2);
4420 if (!u) {
4421 dead_tmp(tmp2);
4422 tmp2 = neon_load_reg(rd, pass);
4423 if (size == 0) {
4424 gen_helper_neon_add_f32(tmp, tmp, tmp2);
4425 } else {
4426 gen_helper_neon_sub_f32(tmp, tmp2, tmp);
4427 }
4428 }
4429 break;
4430 case 28: /* Float compare. */
4431 if (!u) {
4432 gen_helper_neon_ceq_f32(tmp, tmp, tmp2);
4433 } else {
4434 if (size == 0)
4435 gen_helper_neon_cge_f32(tmp, tmp, tmp2);
4436 else
4437 gen_helper_neon_cgt_f32(tmp, tmp, tmp2);
4438 }
4439 break;
4440 case 29: /* Float compare absolute. */
4441 if (!u)
4442 return 1;
4443 if (size == 0)
4444 gen_helper_neon_acge_f32(tmp, tmp, tmp2);
4445 else
4446 gen_helper_neon_acgt_f32(tmp, tmp, tmp2);
4447 break;
4448 case 30: /* Float min/max. */
4449 if (size == 0)
4450 gen_helper_neon_max_f32(tmp, tmp, tmp2);
4451 else
4452 gen_helper_neon_min_f32(tmp, tmp, tmp2);
4453 break;
4454 case 31:
4455 if (size == 0)
4456 gen_helper_recps_f32(tmp, tmp, tmp2, cpu_env);
4457 else
4458 gen_helper_rsqrts_f32(tmp, tmp, tmp2, cpu_env);
4459 break;
4460 default:
4461 abort();
4462 }
4463 dead_tmp(tmp2);
4464
4465 /* Save the result. For elementwise operations we can put it
4466 straight into the destination register. For pairwise operations
4467 we have to be careful to avoid clobbering the source operands. */
4468 if (pairwise && rd == rm) {
4469 neon_store_scratch(pass, tmp);
4470 } else {
4471 neon_store_reg(rd, pass, tmp);
4472 }
4473
4474 } /* for pass */
4475 if (pairwise && rd == rm) {
4476 for (pass = 0; pass < (q ? 4 : 2); pass++) {
4477 tmp = neon_load_scratch(pass);
4478 neon_store_reg(rd, pass, tmp);
4479 }
4480 }
4481 /* End of 3 register same size operations. */
4482 } else if (insn & (1 << 4)) {
4483 if ((insn & 0x00380080) != 0) {
4484 /* Two registers and shift. */
4485 op = (insn >> 8) & 0xf;
4486 if (insn & (1 << 7)) {
4487 /* 64-bit shift. */
4488 size = 3;
4489 } else {
4490 size = 2;
4491 while ((insn & (1 << (size + 19))) == 0)
4492 size--;
4493 }
4494 shift = (insn >> 16) & ((1 << (3 + size)) - 1);
4495 /* To avoid excessive dumplication of ops we implement shift
4496 by immediate using the variable shift operations. */
4497 if (op < 8) {
4498 /* Shift by immediate:
4499 VSHR, VSRA, VRSHR, VRSRA, VSRI, VSHL, VQSHL, VQSHLU. */
4500 /* Right shifts are encoded as N - shift, where N is the
4501 element size in bits. */
4502 if (op <= 4)
4503 shift = shift - (1 << (size + 3));
4504 if (size == 3) {
4505 count = q + 1;
4506 } else {
4507 count = q ? 4: 2;
4508 }
4509 switch (size) {
4510 case 0:
4511 imm = (uint8_t) shift;
4512 imm |= imm << 8;
4513 imm |= imm << 16;
4514 break;
4515 case 1:
4516 imm = (uint16_t) shift;
4517 imm |= imm << 16;
4518 break;
4519 case 2:
4520 case 3:
4521 imm = shift;
4522 break;
4523 default:
4524 abort();
4525 }
4526
4527 for (pass = 0; pass < count; pass++) {
4528 if (size == 3) {
4529 neon_load_reg64(cpu_V0, rm + pass);
4530 tcg_gen_movi_i64(cpu_V1, imm);
4531 switch (op) {
4532 case 0: /* VSHR */
4533 case 1: /* VSRA */
4534 if (u)
4535 gen_helper_neon_shl_u64(cpu_V0, cpu_V0, cpu_V1);
4536 else
4537 gen_helper_neon_shl_s64(cpu_V0, cpu_V0, cpu_V1);
4538 break;
4539 case 2: /* VRSHR */
4540 case 3: /* VRSRA */
4541 if (u)
4542 gen_helper_neon_rshl_u64(cpu_V0, cpu_V0, cpu_V1);
4543 else
4544 gen_helper_neon_rshl_s64(cpu_V0, cpu_V0, cpu_V1);
4545 break;
4546 case 4: /* VSRI */
4547 if (!u)
4548 return 1;
4549 gen_helper_neon_shl_u64(cpu_V0, cpu_V0, cpu_V1);
4550 break;
4551 case 5: /* VSHL, VSLI */
4552 gen_helper_neon_shl_u64(cpu_V0, cpu_V0, cpu_V1);
4553 break;
4554 case 6: /* VQSHL */
4555 if (u)
4556 gen_helper_neon_qshl_u64(cpu_V0, cpu_env, cpu_V0, cpu_V1);
4557 else
4558 gen_helper_neon_qshl_s64(cpu_V0, cpu_env, cpu_V0, cpu_V1);
4559 break;
4560 case 7: /* VQSHLU */
4561 gen_helper_neon_qshl_u64(cpu_V0, cpu_env, cpu_V0, cpu_V1);
4562 break;
4563 }
4564 if (op == 1 || op == 3) {
4565 /* Accumulate. */
4566 neon_load_reg64(cpu_V0, rd + pass);
4567 tcg_gen_add_i64(cpu_V0, cpu_V0, cpu_V1);
4568 } else if (op == 4 || (op == 5 && u)) {
4569 /* Insert */
4570 cpu_abort(env, "VS[LR]I.64 not implemented");
4571 }
4572 neon_store_reg64(cpu_V0, rd + pass);
4573 } else { /* size < 3 */
4574 /* Operands in T0 and T1. */
4575 tmp = neon_load_reg(rm, pass);
4576 tmp2 = new_tmp();
4577 tcg_gen_movi_i32(tmp2, imm);
4578 switch (op) {
4579 case 0: /* VSHR */
4580 case 1: /* VSRA */
4581 GEN_NEON_INTEGER_OP(shl);
4582 break;
4583 case 2: /* VRSHR */
4584 case 3: /* VRSRA */
4585 GEN_NEON_INTEGER_OP(rshl);
4586 break;
4587 case 4: /* VSRI */
4588 if (!u)
4589 return 1;
4590 GEN_NEON_INTEGER_OP(shl);
4591 break;
4592 case 5: /* VSHL, VSLI */
4593 switch (size) {
4594 case 0: gen_helper_neon_shl_u8(tmp, tmp, tmp2); break;
4595 case 1: gen_helper_neon_shl_u16(tmp, tmp, tmp2); break;
4596 case 2: gen_helper_neon_shl_u32(tmp, tmp, tmp2); break;
4597 default: return 1;
4598 }
4599 break;
4600 case 6: /* VQSHL */
4601 GEN_NEON_INTEGER_OP_ENV(qshl);
4602 break;
4603 case 7: /* VQSHLU */
4604 switch (size) {
4605 case 0: gen_helper_neon_qshl_u8(tmp, cpu_env, tmp, tmp2); break;
4606 case 1: gen_helper_neon_qshl_u16(tmp, cpu_env, tmp, tmp2); break;
4607 case 2: gen_helper_neon_qshl_u32(tmp, cpu_env, tmp, tmp2); break;
4608 default: return 1;
4609 }
4610 break;
4611 }
4612 dead_tmp(tmp2);
4613
4614 if (op == 1 || op == 3) {
4615 /* Accumulate. */
4616 tmp2 = neon_load_reg(rd, pass);
4617 gen_neon_add(size, tmp2, tmp);
4618 dead_tmp(tmp2);
4619 } else if (op == 4 || (op == 5 && u)) {
4620 /* Insert */
4621 switch (size) {
4622 case 0:
4623 if (op == 4)
4624 imm = 0xff >> -shift;
4625 else
4626 imm = (uint8_t)(0xff << shift);
4627 imm |= imm << 8;
4628 imm |= imm << 16;
4629 break;
4630 case 1:
4631 if (op == 4)
4632 imm = 0xffff >> -shift;
4633 else
4634 imm = (uint16_t)(0xffff << shift);
4635 imm |= imm << 16;
4636 break;
4637 case 2:
4638 if (op == 4)
4639 imm = 0xffffffffu >> -shift;
4640 else
4641 imm = 0xffffffffu << shift;
4642 break;
4643 default:
4644 abort();
4645 }
4646 tmp2 = neon_load_reg(rd, pass);
4647 tcg_gen_andi_i32(tmp, tmp, imm);
4648 tcg_gen_andi_i32(tmp2, tmp2, ~imm);
4649 tcg_gen_or_i32(tmp, tmp, tmp2);
4650 dead_tmp(tmp2);
4651 }
4652 neon_store_reg(rd, pass, tmp);
4653 }
4654 } /* for pass */
4655 } else if (op < 10) {
4656 /* Shift by immediate and narrow:
4657 VSHRN, VRSHRN, VQSHRN, VQRSHRN. */
4658 shift = shift - (1 << (size + 3));
4659 size++;
4660 switch (size) {
4661 case 1:
4662 imm = (uint16_t)shift;
4663 imm |= imm << 16;
4664 tmp2 = tcg_const_i32(imm);
4665 TCGV_UNUSED_I64(tmp64);
4666 break;
4667 case 2:
4668 imm = (uint32_t)shift;
4669 tmp2 = tcg_const_i32(imm);
4670 TCGV_UNUSED_I64(tmp64);
4671 break;
4672 case 3:
4673 tmp64 = tcg_const_i64(shift);
4674 TCGV_UNUSED(tmp2);
4675 break;
4676 default:
4677 abort();
4678 }
4679
4680 for (pass = 0; pass < 2; pass++) {
4681 if (size == 3) {
4682 neon_load_reg64(cpu_V0, rm + pass);
4683 if (q) {
4684 if (u)
4685 gen_helper_neon_rshl_u64(cpu_V0, cpu_V0, tmp64);
4686 else
4687 gen_helper_neon_rshl_s64(cpu_V0, cpu_V0, tmp64);
4688 } else {
4689 if (u)
4690 gen_helper_neon_shl_u64(cpu_V0, cpu_V0, tmp64);
4691 else
4692 gen_helper_neon_shl_s64(cpu_V0, cpu_V0, tmp64);
4693 }
4694 } else {
4695 tmp = neon_load_reg(rm + pass, 0);
4696 gen_neon_shift_narrow(size, tmp, tmp2, q, u);
4697 tmp3 = neon_load_reg(rm + pass, 1);
4698 gen_neon_shift_narrow(size, tmp3, tmp2, q, u);
4699 tcg_gen_concat_i32_i64(cpu_V0, tmp, tmp3);
4700 dead_tmp(tmp);
4701 dead_tmp(tmp3);
4702 }
4703 tmp = new_tmp();
4704 if (op == 8 && !u) {
4705 gen_neon_narrow(size - 1, tmp, cpu_V0);
4706 } else {
4707 if (op == 8)
4708 gen_neon_narrow_sats(size - 1, tmp, cpu_V0);
4709 else
4710 gen_neon_narrow_satu(size - 1, tmp, cpu_V0);
4711 }
4712 neon_store_reg(rd, pass, tmp);
4713 } /* for pass */
4714 if (size == 3) {
4715 tcg_temp_free_i64(tmp64);
4716 } else {
4717 dead_tmp(tmp2);
4718 }
4719 } else if (op == 10) {
4720 /* VSHLL */
4721 if (q || size == 3)
4722 return 1;
4723 tmp = neon_load_reg(rm, 0);
4724 tmp2 = neon_load_reg(rm, 1);
4725 for (pass = 0; pass < 2; pass++) {
4726 if (pass == 1)
4727 tmp = tmp2;
4728
4729 gen_neon_widen(cpu_V0, tmp, size, u);
4730
4731 if (shift != 0) {
4732 /* The shift is less than the width of the source
4733 type, so we can just shift the whole register. */
4734 tcg_gen_shli_i64(cpu_V0, cpu_V0, shift);
4735 if (size < 2 || !u) {
4736 uint64_t imm64;
4737 if (size == 0) {
4738 imm = (0xffu >> (8 - shift));
4739 imm |= imm << 16;
4740 } else {
4741 imm = 0xffff >> (16 - shift);
4742 }
4743 imm64 = imm | (((uint64_t)imm) << 32);
4744 tcg_gen_andi_i64(cpu_V0, cpu_V0, imm64);
4745 }
4746 }
4747 neon_store_reg64(cpu_V0, rd + pass);
4748 }
4749 } else if (op == 15 || op == 16) {
4750 /* VCVT fixed-point. */
4751 for (pass = 0; pass < (q ? 4 : 2); pass++) {
4752 tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, pass));
4753 if (op & 1) {
4754 if (u)
4755 gen_vfp_ulto(0, shift);
4756 else
4757 gen_vfp_slto(0, shift);
4758 } else {
4759 if (u)
4760 gen_vfp_toul(0, shift);
4761 else
4762 gen_vfp_tosl(0, shift);
4763 }
4764 tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, pass));
4765 }
4766 } else {
4767 return 1;
4768 }
4769 } else { /* (insn & 0x00380080) == 0 */
4770 int invert;
4771
4772 op = (insn >> 8) & 0xf;
4773 /* One register and immediate. */
4774 imm = (u << 7) | ((insn >> 12) & 0x70) | (insn & 0xf);
4775 invert = (insn & (1 << 5)) != 0;
4776 switch (op) {
4777 case 0: case 1:
4778 /* no-op */
4779 break;
4780 case 2: case 3:
4781 imm <<= 8;
4782 break;
4783 case 4: case 5:
4784 imm <<= 16;
4785 break;
4786 case 6: case 7:
4787 imm <<= 24;
4788 break;
4789 case 8: case 9:
4790 imm |= imm << 16;
4791 break;
4792 case 10: case 11:
4793 imm = (imm << 8) | (imm << 24);
4794 break;
4795 case 12:
4796 imm = (imm < 8) | 0xff;
4797 break;
4798 case 13:
4799 imm = (imm << 16) | 0xffff;
4800 break;
4801 case 14:
4802 imm |= (imm << 8) | (imm << 16) | (imm << 24);
4803 if (invert)
4804 imm = ~imm;
4805 break;
4806 case 15:
4807 imm = ((imm & 0x80) << 24) | ((imm & 0x3f) << 19)
4808 | ((imm & 0x40) ? (0x1f << 25) : (1 << 30));
4809 break;
4810 }
4811 if (invert)
4812 imm = ~imm;
4813
4814 for (pass = 0; pass < (q ? 4 : 2); pass++) {
4815 if (op & 1 && op < 12) {
4816 tmp = neon_load_reg(rd, pass);
4817 if (invert) {
4818 /* The immediate value has already been inverted, so
4819 BIC becomes AND. */
4820 tcg_gen_andi_i32(tmp, tmp, imm);
4821 } else {
4822 tcg_gen_ori_i32(tmp, tmp, imm);
4823 }
4824 } else {
4825 /* VMOV, VMVN. */
4826 tmp = new_tmp();
4827 if (op == 14 && invert) {
4828 uint32_t val;
4829 val = 0;
4830 for (n = 0; n < 4; n++) {
4831 if (imm & (1 << (n + (pass & 1) * 4)))
4832 val |= 0xff << (n * 8);
4833 }
4834 tcg_gen_movi_i32(tmp, val);
4835 } else {
4836 tcg_gen_movi_i32(tmp, imm);
4837 }
4838 }
4839 neon_store_reg(rd, pass, tmp);
4840 }
4841 }
4842 } else { /* (insn & 0x00800010 == 0x00800000) */
4843 if (size != 3) {
4844 op = (insn >> 8) & 0xf;
4845 if ((insn & (1 << 6)) == 0) {
4846 /* Three registers of different lengths. */
4847 int src1_wide;
4848 int src2_wide;
4849 int prewiden;
4850 /* prewiden, src1_wide, src2_wide */
4851 static const int neon_3reg_wide[16][3] = {
4852 {1, 0, 0}, /* VADDL */
4853 {1, 1, 0}, /* VADDW */
4854 {1, 0, 0}, /* VSUBL */
4855 {1, 1, 0}, /* VSUBW */
4856 {0, 1, 1}, /* VADDHN */
4857 {0, 0, 0}, /* VABAL */
4858 {0, 1, 1}, /* VSUBHN */
4859 {0, 0, 0}, /* VABDL */
4860 {0, 0, 0}, /* VMLAL */
4861 {0, 0, 0}, /* VQDMLAL */
4862 {0, 0, 0}, /* VMLSL */
4863 {0, 0, 0}, /* VQDMLSL */
4864 {0, 0, 0}, /* Integer VMULL */
4865 {0, 0, 0}, /* VQDMULL */
4866 {0, 0, 0} /* Polynomial VMULL */
4867 };
4868
4869 prewiden = neon_3reg_wide[op][0];
4870 src1_wide = neon_3reg_wide[op][1];
4871 src2_wide = neon_3reg_wide[op][2];
4872
4873 if (size == 0 && (op == 9 || op == 11 || op == 13))
4874 return 1;
4875
4876 /* Avoid overlapping operands. Wide source operands are
4877 always aligned so will never overlap with wide
4878 destinations in problematic ways. */
4879 if (rd == rm && !src2_wide) {
4880 tmp = neon_load_reg(rm, 1);
4881 neon_store_scratch(2, tmp);
4882 } else if (rd == rn && !src1_wide) {
4883 tmp = neon_load_reg(rn, 1);
4884 neon_store_scratch(2, tmp);
4885 }
4886 TCGV_UNUSED(tmp3);
4887 for (pass = 0; pass < 2; pass++) {
4888 if (src1_wide) {
4889 neon_load_reg64(cpu_V0, rn + pass);
4890 TCGV_UNUSED(tmp);
4891 } else {
4892 if (pass == 1 && rd == rn) {
4893 tmp = neon_load_scratch(2);
4894 } else {
4895 tmp = neon_load_reg(rn, pass);
4896 }
4897 if (prewiden) {
4898 gen_neon_widen(cpu_V0, tmp, size, u);
4899 }
4900 }
4901 if (src2_wide) {
4902 neon_load_reg64(cpu_V1, rm + pass);
4903 TCGV_UNUSED(tmp2);
4904 } else {
4905 if (pass == 1 && rd == rm) {
4906 tmp2 = neon_load_scratch(2);
4907 } else {
4908 tmp2 = neon_load_reg(rm, pass);
4909 }
4910 if (prewiden) {
4911 gen_neon_widen(cpu_V1, tmp2, size, u);
4912 }
4913 }
4914 switch (op) {
4915 case 0: case 1: case 4: /* VADDL, VADDW, VADDHN, VRADDHN */
4916 gen_neon_addl(size);
4917 break;
4918 case 2: case 3: case 6: /* VSUBL, VSUBW, VSUBHL, VRSUBHL */
4919 gen_neon_subl(size);
4920 break;
4921 case 5: case 7: /* VABAL, VABDL */
4922 switch ((size << 1) | u) {
4923 case 0:
4924 gen_helper_neon_abdl_s16(cpu_V0, tmp, tmp2);
4925 break;
4926 case 1:
4927 gen_helper_neon_abdl_u16(cpu_V0, tmp, tmp2);
4928 break;
4929 case 2:
4930 gen_helper_neon_abdl_s32(cpu_V0, tmp, tmp2);
4931 break;
4932 case 3:
4933 gen_helper_neon_abdl_u32(cpu_V0, tmp, tmp2);
4934 break;
4935 case 4:
4936 gen_helper_neon_abdl_s64(cpu_V0, tmp, tmp2);
4937 break;
4938 case 5:
4939 gen_helper_neon_abdl_u64(cpu_V0, tmp, tmp2);
4940 break;
4941 default: abort();
4942 }
4943 dead_tmp(tmp2);
4944 dead_tmp(tmp);
4945 break;
4946 case 8: case 9: case 10: case 11: case 12: case 13:
4947 /* VMLAL, VQDMLAL, VMLSL, VQDMLSL, VMULL, VQDMULL */
4948 gen_neon_mull(cpu_V0, tmp, tmp2, size, u);
4949 dead_tmp(tmp2);
4950 dead_tmp(tmp);
4951 break;
4952 case 14: /* Polynomial VMULL */
4953 cpu_abort(env, "Polynomial VMULL not implemented");
4954
4955 default: /* 15 is RESERVED. */
4956 return 1;
4957 }
4958 if (op == 5 || op == 13 || (op >= 8 && op <= 11)) {
4959 /* Accumulate. */
4960 if (op == 10 || op == 11) {
4961 gen_neon_negl(cpu_V0, size);
4962 }
4963
4964 if (op != 13) {
4965 neon_load_reg64(cpu_V1, rd + pass);
4966 }
4967
4968 switch (op) {
4969 case 5: case 8: case 10: /* VABAL, VMLAL, VMLSL */
4970 gen_neon_addl(size);
4971 break;
4972 case 9: case 11: /* VQDMLAL, VQDMLSL */
4973 gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
4974 gen_neon_addl_saturate(cpu_V0, cpu_V1, size);
4975 break;
4976 /* Fall through. */
4977 case 13: /* VQDMULL */
4978 gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
4979 break;
4980 default:
4981 abort();
4982 }
4983 neon_store_reg64(cpu_V0, rd + pass);
4984 } else if (op == 4 || op == 6) {
4985 /* Narrowing operation. */
4986 tmp = new_tmp();
4987 if (u) {
4988 switch (size) {
4989 case 0:
4990 gen_helper_neon_narrow_high_u8(tmp, cpu_V0);
4991 break;
4992 case 1:
4993 gen_helper_neon_narrow_high_u16(tmp, cpu_V0);
4994 break;
4995 case 2:
4996 tcg_gen_shri_i64(cpu_V0, cpu_V0, 32);
4997 tcg_gen_trunc_i64_i32(tmp, cpu_V0);
4998 break;
4999 default: abort();
5000 }
5001 } else {
5002 switch (size) {
5003 case 0:
5004 gen_helper_neon_narrow_round_high_u8(tmp, cpu_V0);
5005 break;
5006 case 1:
5007 gen_helper_neon_narrow_round_high_u16(tmp, cpu_V0);
5008 break;
5009 case 2:
5010 tcg_gen_addi_i64(cpu_V0, cpu_V0, 1u << 31);
5011 tcg_gen_shri_i64(cpu_V0, cpu_V0, 32);
5012 tcg_gen_trunc_i64_i32(tmp, cpu_V0);
5013 break;
5014 default: abort();
5015 }
5016 }
5017 if (pass == 0) {
5018 tmp3 = tmp;
5019 } else {
5020 neon_store_reg(rd, 0, tmp3);
5021 neon_store_reg(rd, 1, tmp);
5022 }
5023 } else {
5024 /* Write back the result. */
5025 neon_store_reg64(cpu_V0, rd + pass);
5026 }
5027 }
5028 } else {
5029 /* Two registers and a scalar. */
5030 switch (op) {
5031 case 0: /* Integer VMLA scalar */
5032 case 1: /* Float VMLA scalar */
5033 case 4: /* Integer VMLS scalar */
5034 case 5: /* Floating point VMLS scalar */
5035 case 8: /* Integer VMUL scalar */
5036 case 9: /* Floating point VMUL scalar */
5037 case 12: /* VQDMULH scalar */
5038 case 13: /* VQRDMULH scalar */
5039 tmp = neon_get_scalar(size, rm);
5040 neon_store_scratch(0, tmp);
5041 for (pass = 0; pass < (u ? 4 : 2); pass++) {
5042 tmp = neon_load_scratch(0);
5043 tmp2 = neon_load_reg(rn, pass);
5044 if (op == 12) {
5045 if (size == 1) {
5046 gen_helper_neon_qdmulh_s16(tmp, cpu_env, tmp, tmp2);
5047 } else {
5048 gen_helper_neon_qdmulh_s32(tmp, cpu_env, tmp, tmp2);
5049 }
5050 } else if (op == 13) {
5051 if (size == 1) {
5052 gen_helper_neon_qrdmulh_s16(tmp, cpu_env, tmp, tmp2);
5053 } else {
5054 gen_helper_neon_qrdmulh_s32(tmp, cpu_env, tmp, tmp2);
5055 }
5056 } else if (op & 1) {
5057 gen_helper_neon_mul_f32(tmp, tmp, tmp2);
5058 } else {
5059 switch (size) {
5060 case 0: gen_helper_neon_mul_u8(tmp, tmp, tmp2); break;
5061 case 1: gen_helper_neon_mul_u16(tmp, tmp, tmp2); break;
5062 case 2: tcg_gen_mul_i32(tmp, tmp, tmp2); break;
5063 default: return 1;
5064 }
5065 }
5066 dead_tmp(tmp2);
5067 if (op < 8) {
5068 /* Accumulate. */
5069 tmp2 = neon_load_reg(rd, pass);
5070 switch (op) {
5071 case 0:
5072 gen_neon_add(size, tmp, tmp2);
5073 break;
5074 case 1:
5075 gen_helper_neon_add_f32(tmp, tmp, tmp2);
5076 break;
5077 case 4:
5078 gen_neon_rsb(size, tmp, tmp2);
5079 break;
5080 case 5:
5081 gen_helper_neon_sub_f32(tmp, tmp2, tmp);
5082 break;
5083 default:
5084 abort();
5085 }
5086 dead_tmp(tmp2);
5087 }
5088 neon_store_reg(rd, pass, tmp);
5089 }
5090 break;
5091 case 2: /* VMLAL sclar */
5092 case 3: /* VQDMLAL scalar */
5093 case 6: /* VMLSL scalar */
5094 case 7: /* VQDMLSL scalar */
5095 case 10: /* VMULL scalar */
5096 case 11: /* VQDMULL scalar */
5097 if (size == 0 && (op == 3 || op == 7 || op == 11))
5098 return 1;
5099
5100 tmp2 = neon_get_scalar(size, rm);
5101 tmp3 = neon_load_reg(rn, 1);
5102
5103 for (pass = 0; pass < 2; pass++) {
5104 if (pass == 0) {
5105 tmp = neon_load_reg(rn, 0);
5106 } else {
5107 tmp = tmp3;
5108 }
5109 gen_neon_mull(cpu_V0, tmp, tmp2, size, u);
5110 dead_tmp(tmp);
5111 if (op == 6 || op == 7) {
5112 gen_neon_negl(cpu_V0, size);
5113 }
5114 if (op != 11) {
5115 neon_load_reg64(cpu_V1, rd + pass);
5116 }
5117 switch (op) {
5118 case 2: case 6:
5119 gen_neon_addl(size);
5120 break;
5121 case 3: case 7:
5122 gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
5123 gen_neon_addl_saturate(cpu_V0, cpu_V1, size);
5124 break;
5125 case 10:
5126 /* no-op */
5127 break;
5128 case 11:
5129 gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
5130 break;
5131 default:
5132 abort();
5133 }
5134 neon_store_reg64(cpu_V0, rd + pass);
5135 }
5136
5137 dead_tmp(tmp2);
5138
5139 break;
5140 default: /* 14 and 15 are RESERVED */
5141 return 1;
5142 }
5143 }
5144 } else { /* size == 3 */
5145 if (!u) {
5146 /* Extract. */
5147 imm = (insn >> 8) & 0xf;
5148 count = q + 1;
5149
5150 if (imm > 7 && !q)
5151 return 1;
5152
5153 if (imm == 0) {
5154 neon_load_reg64(cpu_V0, rn);
5155 if (q) {
5156 neon_load_reg64(cpu_V1, rn + 1);
5157 }
5158 } else if (imm == 8) {
5159 neon_load_reg64(cpu_V0, rn + 1);
5160 if (q) {
5161 neon_load_reg64(cpu_V1, rm);
5162 }
5163 } else if (q) {
5164 tmp64 = tcg_temp_new_i64();
5165 if (imm < 8) {
5166 neon_load_reg64(cpu_V0, rn);
5167 neon_load_reg64(tmp64, rn + 1);
5168 } else {
5169 neon_load_reg64(cpu_V0, rn + 1);
5170 neon_load_reg64(tmp64, rm);
5171 }
5172 tcg_gen_shri_i64(cpu_V0, cpu_V0, (imm & 7) * 8);
5173 tcg_gen_shli_i64(cpu_V1, tmp64, 64 - ((imm & 7) * 8));
5174 tcg_gen_or_i64(cpu_V0, cpu_V0, cpu_V1);
5175 if (imm < 8) {
5176 neon_load_reg64(cpu_V1, rm);
5177 } else {
5178 neon_load_reg64(cpu_V1, rm + 1);
5179 imm -= 8;
5180 }
5181 tcg_gen_shli_i64(cpu_V1, cpu_V1, 64 - (imm * 8));
5182 tcg_gen_shri_i64(tmp64, tmp64, imm * 8);
5183 tcg_gen_or_i64(cpu_V1, cpu_V1, tmp64);
5184 tcg_temp_free_i64(tmp64);
5185 } else {
5186 /* BUGFIX */
5187 neon_load_reg64(cpu_V0, rn);
5188 tcg_gen_shri_i64(cpu_V0, cpu_V0, imm * 8);
5189 neon_load_reg64(cpu_V1, rm);
5190 tcg_gen_shli_i64(cpu_V1, cpu_V1, 64 - (imm * 8));
5191 tcg_gen_or_i64(cpu_V0, cpu_V0, cpu_V1);
5192 }
5193 neon_store_reg64(cpu_V0, rd);
5194 if (q) {
5195 neon_store_reg64(cpu_V1, rd + 1);
5196 }
5197 } else if ((insn & (1 << 11)) == 0) {
5198 /* Two register misc. */
5199 op = ((insn >> 12) & 0x30) | ((insn >> 7) & 0xf);
5200 size = (insn >> 18) & 3;
5201 switch (op) {
5202 case 0: /* VREV64 */
5203 if (size == 3)
5204 return 1;
5205 for (pass = 0; pass < (q ? 2 : 1); pass++) {
5206 tmp = neon_load_reg(rm, pass * 2);
5207 tmp2 = neon_load_reg(rm, pass * 2 + 1);
5208 switch (size) {
5209 case 0: tcg_gen_bswap32_i32(tmp, tmp); break;
5210 case 1: gen_swap_half(tmp); break;
5211 case 2: /* no-op */ break;
5212 default: abort();
5213 }
5214 neon_store_reg(rd, pass * 2 + 1, tmp);
5215 if (size == 2) {
5216 neon_store_reg(rd, pass * 2, tmp2);
5217 } else {
5218 switch (size) {
5219 case 0: tcg_gen_bswap32_i32(tmp2, tmp2); break;
5220 case 1: gen_swap_half(tmp2); break;
5221 default: abort();
5222 }
5223 neon_store_reg(rd, pass * 2, tmp2);
5224 }
5225 }
5226 break;
5227 case 4: case 5: /* VPADDL */
5228 case 12: case 13: /* VPADAL */
5229 if (size == 3)
5230 return 1;
5231 for (pass = 0; pass < q + 1; pass++) {
5232 tmp = neon_load_reg(rm, pass * 2);
5233 gen_neon_widen(cpu_V0, tmp, size, op & 1);
5234 tmp = neon_load_reg(rm, pass * 2 + 1);
5235 gen_neon_widen(cpu_V1, tmp, size, op & 1);
5236 switch (size) {
5237 case 0: gen_helper_neon_paddl_u16(CPU_V001); break;
5238 case 1: gen_helper_neon_paddl_u32(CPU_V001); break;
5239 case 2: tcg_gen_add_i64(CPU_V001); break;
5240 default: abort();
5241 }
5242 if (op >= 12) {
5243 /* Accumulate. */
5244 neon_load_reg64(cpu_V1, rd + pass);
5245 gen_neon_addl(size);
5246 }
5247 neon_store_reg64(cpu_V0, rd + pass);
5248 }
5249 break;
5250 case 33: /* VTRN */
5251 if (size == 2) {
5252 for (n = 0; n < (q ? 4 : 2); n += 2) {
5253 tmp = neon_load_reg(rm, n);
5254 tmp2 = neon_load_reg(rd, n + 1);
5255 neon_store_reg(rm, n, tmp2);
5256 neon_store_reg(rd, n + 1, tmp);
5257 }
5258 } else {
5259 goto elementwise;
5260 }
5261 break;
5262 case 34: /* VUZP */
5263 /* Reg Before After
5264 Rd A3 A2 A1 A0 B2 B0 A2 A0
5265 Rm B3 B2 B1 B0 B3 B1 A3 A1
5266 */
5267 if (size == 3)
5268 return 1;
5269 gen_neon_unzip(rd, q, 0, size);
5270 gen_neon_unzip(rm, q, 4, size);
5271 if (q) {
5272 static int unzip_order_q[8] =
5273 {0, 2, 4, 6, 1, 3, 5, 7};
5274 for (n = 0; n < 8; n++) {
5275 int reg = (n < 4) ? rd : rm;
5276 tmp = neon_load_scratch(unzip_order_q[n]);
5277 neon_store_reg(reg, n % 4, tmp);
5278 }
5279 } else {
5280 static int unzip_order[4] =
5281 {0, 4, 1, 5};
5282 for (n = 0; n < 4; n++) {
5283 int reg = (n < 2) ? rd : rm;
5284 tmp = neon_load_scratch(unzip_order[n]);
5285 neon_store_reg(reg, n % 2, tmp);
5286 }
5287 }
5288 break;
5289 case 35: /* VZIP */
5290 /* Reg Before After
5291 Rd A3 A2 A1 A0 B1 A1 B0 A0
5292 Rm B3 B2 B1 B0 B3 A3 B2 A2
5293 */
5294 if (size == 3)
5295 return 1;
5296 count = (q ? 4 : 2);
5297 for (n = 0; n < count; n++) {
5298 tmp = neon_load_reg(rd, n);
5299 tmp2 = neon_load_reg(rd, n);
5300 switch (size) {
5301 case 0: gen_neon_zip_u8(tmp, tmp2); break;
5302 case 1: gen_neon_zip_u16(tmp, tmp2); break;
5303 case 2: /* no-op */; break;
5304 default: abort();
5305 }
5306 neon_store_scratch(n * 2, tmp);
5307 neon_store_scratch(n * 2 + 1, tmp2);
5308 }
5309 for (n = 0; n < count * 2; n++) {
5310 int reg = (n < count) ? rd : rm;
5311 tmp = neon_load_scratch(n);
5312 neon_store_reg(reg, n % count, tmp);
5313 }
5314 break;
5315 case 36: case 37: /* VMOVN, VQMOVUN, VQMOVN */
5316 if (size == 3)
5317 return 1;
5318 TCGV_UNUSED(tmp2);
5319 for (pass = 0; pass < 2; pass++) {
5320 neon_load_reg64(cpu_V0, rm + pass);
5321 tmp = new_tmp();
5322 if (op == 36 && q == 0) {
5323 gen_neon_narrow(size, tmp, cpu_V0);
5324 } else if (q) {
5325 gen_neon_narrow_satu(size, tmp, cpu_V0);
5326 } else {
5327 gen_neon_narrow_sats(size, tmp, cpu_V0);
5328 }
5329 if (pass == 0) {
5330 tmp2 = tmp;
5331 } else {
5332 neon_store_reg(rd, 0, tmp2);
5333 neon_store_reg(rd, 1, tmp);
5334 }
5335 }
5336 break;
5337 case 38: /* VSHLL */
5338 if (q || size == 3)
5339 return 1;
5340 tmp = neon_load_reg(rm, 0);
5341 tmp2 = neon_load_reg(rm, 1);
5342 for (pass = 0; pass < 2; pass++) {
5343 if (pass == 1)
5344 tmp = tmp2;
5345 gen_neon_widen(cpu_V0, tmp, size, 1);
5346 neon_store_reg64(cpu_V0, rd + pass);
5347 }
5348 break;
5349 default:
5350 elementwise:
5351 for (pass = 0; pass < (q ? 4 : 2); pass++) {
5352 if (op == 30 || op == 31 || op >= 58) {
5353 tcg_gen_ld_f32(cpu_F0s, cpu_env,
5354 neon_reg_offset(rm, pass));
5355 TCGV_UNUSED(tmp);
5356 } else {
5357 tmp = neon_load_reg(rm, pass);
5358 }
5359 switch (op) {
5360 case 1: /* VREV32 */
5361 switch (size) {
5362 case 0: tcg_gen_bswap32_i32(tmp, tmp); break;
5363 case 1: gen_swap_half(tmp); break;
5364 default: return 1;
5365 }
5366 break;
5367 case 2: /* VREV16 */
5368 if (size != 0)
5369 return 1;
5370 gen_rev16(tmp);
5371 break;
5372 case 8: /* CLS */
5373 switch (size) {
5374 case 0: gen_helper_neon_cls_s8(tmp, tmp); break;
5375 case 1: gen_helper_neon_cls_s16(tmp, tmp); break;
5376 case 2: gen_helper_neon_cls_s32(tmp, tmp); break;
5377 default: return 1;
5378 }
5379 break;
5380 case 9: /* CLZ */
5381 switch (size) {
5382 case 0: gen_helper_neon_clz_u8(tmp, tmp); break;
5383 case 1: gen_helper_neon_clz_u16(tmp, tmp); break;
5384 case 2: gen_helper_clz(tmp, tmp); break;
5385 default: return 1;
5386 }
5387 break;
5388 case 10: /* CNT */
5389 if (size != 0)
5390 return 1;
5391 gen_helper_neon_cnt_u8(tmp, tmp);
5392 break;
5393 case 11: /* VNOT */
5394 if (size != 0)
5395 return 1;
5396 tcg_gen_not_i32(tmp, tmp);
5397 break;
5398 case 14: /* VQABS */
5399 switch (size) {
5400 case 0: gen_helper_neon_qabs_s8(tmp, cpu_env, tmp); break;
5401 case 1: gen_helper_neon_qabs_s16(tmp, cpu_env, tmp); break;
5402 case 2: gen_helper_neon_qabs_s32(tmp, cpu_env, tmp); break;
5403 default: return 1;
5404 }
5405 break;
5406 case 15: /* VQNEG */
5407 switch (size) {
5408 case 0: gen_helper_neon_qneg_s8(tmp, cpu_env, tmp); break;
5409 case 1: gen_helper_neon_qneg_s16(tmp, cpu_env, tmp); break;
5410 case 2: gen_helper_neon_qneg_s32(tmp, cpu_env, tmp); break;
5411 default: return 1;
5412 }
5413 break;
5414 case 16: case 19: /* VCGT #0, VCLE #0 */
5415 tmp2 = tcg_const_i32(0);
5416 switch(size) {
5417 case 0: gen_helper_neon_cgt_s8(tmp, tmp, tmp2); break;
5418 case 1: gen_helper_neon_cgt_s16(tmp, tmp, tmp2); break;
5419 case 2: gen_helper_neon_cgt_s32(tmp, tmp, tmp2); break;
5420 default: return 1;
5421 }
5422 tcg_temp_free(tmp2);
5423 if (op == 19)
5424 tcg_gen_not_i32(tmp, tmp);
5425 break;
5426 case 17: case 20: /* VCGE #0, VCLT #0 */
5427 tmp2 = tcg_const_i32(0);
5428 switch(size) {
5429 case 0: gen_helper_neon_cge_s8(tmp, tmp, tmp2); break;
5430 case 1: gen_helper_neon_cge_s16(tmp, tmp, tmp2); break;
5431 case 2: gen_helper_neon_cge_s32(tmp, tmp, tmp2); break;
5432 default: return 1;
5433 }
5434 tcg_temp_free(tmp2);
5435 if (op == 20)
5436 tcg_gen_not_i32(tmp, tmp);
5437 break;
5438 case 18: /* VCEQ #0 */
5439 tmp2 = tcg_const_i32(0);
5440 switch(size) {
5441 case 0: gen_helper_neon_ceq_u8(tmp, tmp, tmp2); break;
5442 case 1: gen_helper_neon_ceq_u16(tmp, tmp, tmp2); break;
5443 case 2: gen_helper_neon_ceq_u32(tmp, tmp, tmp2); break;
5444 default: return 1;
5445 }
5446 tcg_temp_free(tmp2);
5447 break;
5448 case 22: /* VABS */
5449 switch(size) {
5450 case 0: gen_helper_neon_abs_s8(tmp, tmp); break;
5451 case 1: gen_helper_neon_abs_s16(tmp, tmp); break;
5452 case 2: tcg_gen_abs_i32(tmp, tmp); break;
5453 default: return 1;
5454 }
5455 break;
5456 case 23: /* VNEG */
5457 if (size == 3)
5458 return 1;
5459 tmp2 = tcg_const_i32(0);
5460 gen_neon_rsb(size, tmp, tmp2);
5461 tcg_temp_free(tmp2);
5462 break;
5463 case 24: case 27: /* Float VCGT #0, Float VCLE #0 */
5464 tmp2 = tcg_const_i32(0);
5465 gen_helper_neon_cgt_f32(tmp, tmp, tmp2);
5466 tcg_temp_free(tmp2);
5467 if (op == 27)
5468 tcg_gen_not_i32(tmp, tmp);
5469 break;
5470 case 25: case 28: /* Float VCGE #0, Float VCLT #0 */
5471 tmp2 = tcg_const_i32(0);
5472 gen_helper_neon_cge_f32(tmp, tmp, tmp2);
5473 tcg_temp_free(tmp2);
5474 if (op == 28)
5475 tcg_gen_not_i32(tmp, tmp);
5476 break;
5477 case 26: /* Float VCEQ #0 */
5478 tmp2 = tcg_const_i32(0);
5479 gen_helper_neon_ceq_f32(tmp, tmp, tmp2);
5480 tcg_temp_free(tmp2);
5481 break;
5482 case 30: /* Float VABS */
5483 gen_vfp_abs(0);
5484 break;
5485 case 31: /* Float VNEG */
5486 gen_vfp_neg(0);
5487 break;
5488 case 32: /* VSWP */
5489 tmp2 = neon_load_reg(rd, pass);
5490 neon_store_reg(rm, pass, tmp2);
5491 break;
5492 case 33: /* VTRN */
5493 tmp2 = neon_load_reg(rd, pass);
5494 switch (size) {
5495 case 0: gen_neon_trn_u8(tmp, tmp2); break;
5496 case 1: gen_neon_trn_u16(tmp, tmp2); break;
5497 case 2: abort();
5498 default: return 1;
5499 }
5500 neon_store_reg(rm, pass, tmp2);
5501 break;
5502 case 56: /* Integer VRECPE */
5503 gen_helper_recpe_u32(tmp, tmp, cpu_env);
5504 break;
5505 case 57: /* Integer VRSQRTE */
5506 gen_helper_rsqrte_u32(tmp, tmp, cpu_env);
5507 break;
5508 case 58: /* Float VRECPE */
5509 gen_helper_recpe_f32(cpu_F0s, cpu_F0s, cpu_env);
5510 break;
5511 case 59: /* Float VRSQRTE */
5512 gen_helper_rsqrte_f32(cpu_F0s, cpu_F0s, cpu_env);
5513 break;
5514 case 60: /* VCVT.F32.S32 */
5515 gen_vfp_tosiz(0);
5516 break;
5517 case 61: /* VCVT.F32.U32 */
5518 gen_vfp_touiz(0);
5519 break;
5520 case 62: /* VCVT.S32.F32 */
5521 gen_vfp_sito(0);
5522 break;
5523 case 63: /* VCVT.U32.F32 */
5524 gen_vfp_uito(0);
5525 break;
5526 default:
5527 /* Reserved: 21, 29, 39-56 */
5528 return 1;
5529 }
5530 if (op == 30 || op == 31 || op >= 58) {
5531 tcg_gen_st_f32(cpu_F0s, cpu_env,
5532 neon_reg_offset(rd, pass));
5533 } else {
5534 neon_store_reg(rd, pass, tmp);
5535 }
5536 }
5537 break;
5538 }
5539 } else if ((insn & (1 << 10)) == 0) {
5540 /* VTBL, VTBX. */
5541 n = ((insn >> 5) & 0x18) + 8;
5542 if (insn & (1 << 6)) {
5543 tmp = neon_load_reg(rd, 0);
5544 } else {
5545 tmp = new_tmp();
5546 tcg_gen_movi_i32(tmp, 0);
5547 }
5548 tmp2 = neon_load_reg(rm, 0);
5549 tmp4 = tcg_const_i32(rn);
5550 tmp5 = tcg_const_i32(n);
5551 gen_helper_neon_tbl(tmp2, tmp2, tmp, tmp4, tmp5);
5552 dead_tmp(tmp);
5553 if (insn & (1 << 6)) {
5554 tmp = neon_load_reg(rd, 1);
5555 } else {
5556 tmp = new_tmp();
5557 tcg_gen_movi_i32(tmp, 0);
5558 }
5559 tmp3 = neon_load_reg(rm, 1);
5560 gen_helper_neon_tbl(tmp3, tmp3, tmp, tmp4, tmp5);
5561 tcg_temp_free_i32(tmp5);
5562 tcg_temp_free_i32(tmp4);
5563 neon_store_reg(rd, 0, tmp2);
5564 neon_store_reg(rd, 1, tmp3);
5565 dead_tmp(tmp);
5566 } else if ((insn & 0x380) == 0) {
5567 /* VDUP */
5568 if (insn & (1 << 19)) {
5569 tmp = neon_load_reg(rm, 1);
5570 } else {
5571 tmp = neon_load_reg(rm, 0);
5572 }
5573 if (insn & (1 << 16)) {
5574 gen_neon_dup_u8(tmp, ((insn >> 17) & 3) * 8);
5575 } else if (insn & (1 << 17)) {
5576 if ((insn >> 18) & 1)
5577 gen_neon_dup_high16(tmp);
5578 else
5579 gen_neon_dup_low16(tmp);
5580 }
5581 for (pass = 0; pass < (q ? 4 : 2); pass++) {
5582 tmp2 = new_tmp();
5583 tcg_gen_mov_i32(tmp2, tmp);
5584 neon_store_reg(rd, pass, tmp2);
5585 }
5586 dead_tmp(tmp);
5587 } else {
5588 return 1;
5589 }
5590 }
5591 }
5592 return 0;
5593 }
5594
5595 static int disas_cp14_read(CPUState * env, DisasContext *s, uint32_t insn)
5596 {
5597 int crn = (insn >> 16) & 0xf;
5598 int crm = insn & 0xf;
5599 int op1 = (insn >> 21) & 7;
5600 int op2 = (insn >> 5) & 7;
5601 int rt = (insn >> 12) & 0xf;
5602 TCGv tmp;
5603
5604 if (arm_feature(env, ARM_FEATURE_THUMB2EE)) {
5605 if (op1 == 6 && crn == 0 && crm == 0 && op2 == 0) {
5606 /* TEECR */
5607 if (IS_USER(s))
5608 return 1;
5609 tmp = load_cpu_field(teecr);
5610 store_reg(s, rt, tmp);
5611 return 0;
5612 }
5613 if (op1 == 6 && crn == 1 && crm == 0 && op2 == 0) {
5614 /* TEEHBR */
5615 if (IS_USER(s) && (env->teecr & 1))
5616 return 1;
5617 tmp = load_cpu_field(teehbr);
5618 store_reg(s, rt, tmp);
5619 return 0;
5620 }
5621 }
5622 fprintf(stderr, "Unknown cp14 read op1:%d crn:%d crm:%d op2:%d\n",
5623 op1, crn, crm, op2);
5624 return 1;
5625 }
5626
5627 static int disas_cp14_write(CPUState * env, DisasContext *s, uint32_t insn)
5628 {
5629 int crn = (insn >> 16) & 0xf;
5630 int crm = insn & 0xf;
5631 int op1 = (insn >> 21) & 7;
5632 int op2 = (insn >> 5) & 7;
5633 int rt = (insn >> 12) & 0xf;
5634 TCGv tmp;
5635
5636 if (arm_feature(env, ARM_FEATURE_THUMB2EE)) {
5637 if (op1 == 6 && crn == 0 && crm == 0 && op2 == 0) {
5638 /* TEECR */
5639 if (IS_USER(s))
5640 return 1;
5641 tmp = load_reg(s, rt);
5642 gen_helper_set_teecr(cpu_env, tmp);
5643 dead_tmp(tmp);
5644 return 0;
5645 }
5646 if (op1 == 6 && crn == 1 && crm == 0 && op2 == 0) {
5647 /* TEEHBR */
5648 if (IS_USER(s) && (env->teecr & 1))
5649 return 1;
5650 tmp = load_reg(s, rt);
5651 store_cpu_field(tmp, teehbr);
5652 return 0;
5653 }
5654 }
5655 fprintf(stderr, "Unknown cp14 write op1:%d crn:%d crm:%d op2:%d\n",
5656 op1, crn, crm, op2);
5657 return 1;
5658 }
5659
5660 static int disas_coproc_insn(CPUState * env, DisasContext *s, uint32_t insn)
5661 {
5662 int cpnum;
5663
5664 cpnum = (insn >> 8) & 0xf;
5665 if (arm_feature(env, ARM_FEATURE_XSCALE)
5666 && ((env->cp15.c15_cpar ^ 0x3fff) & (1 << cpnum)))
5667 return 1;
5668
5669 switch (cpnum) {
5670 case 0:
5671 case 1:
5672 if (arm_feature(env, ARM_FEATURE_IWMMXT)) {
5673 return disas_iwmmxt_insn(env, s, insn);
5674 } else if (arm_feature(env, ARM_FEATURE_XSCALE)) {
5675 return disas_dsp_insn(env, s, insn);
5676 }
5677 return 1;
5678 case 10:
5679 case 11:
5680 return disas_vfp_insn (env, s, insn);
5681 case 14:
5682 /* Coprocessors 7-15 are architecturally reserved by ARM.
5683 Unfortunately Intel decided to ignore this. */
5684 if (arm_feature(env, ARM_FEATURE_XSCALE))
5685 goto board;
5686 if (insn & (1 << 20))
5687 return disas_cp14_read(env, s, insn);
5688 else
5689 return disas_cp14_write(env, s, insn);
5690 case 15:
5691 return disas_cp15_insn (env, s, insn);
5692 default:
5693 board:
5694 /* Unknown coprocessor. See if the board has hooked it. */
5695 return disas_cp_insn (env, s, insn);
5696 }
5697 }
5698
5699
5700 /* Store a 64-bit value to a register pair. Clobbers val. */
5701 static void gen_storeq_reg(DisasContext *s, int rlow, int rhigh, TCGv_i64 val)
5702 {
5703 TCGv tmp;
5704 tmp = new_tmp();
5705 tcg_gen_trunc_i64_i32(tmp, val);
5706 store_reg(s, rlow, tmp);
5707 tmp = new_tmp();
5708 tcg_gen_shri_i64(val, val, 32);
5709 tcg_gen_trunc_i64_i32(tmp, val);
5710 store_reg(s, rhigh, tmp);
5711 }
5712
5713 /* load a 32-bit value from a register and perform a 64-bit accumulate. */
5714 static void gen_addq_lo(DisasContext *s, TCGv_i64 val, int rlow)
5715 {
5716 TCGv_i64 tmp;
5717 TCGv tmp2;
5718
5719 /* Load value and extend to 64 bits. */
5720 tmp = tcg_temp_new_i64();
5721 tmp2 = load_reg(s, rlow);
5722 tcg_gen_extu_i32_i64(tmp, tmp2);
5723 dead_tmp(tmp2);
5724 tcg_gen_add_i64(val, val, tmp);
5725 tcg_temp_free_i64(tmp);
5726 }
5727
5728 /* load and add a 64-bit value from a register pair. */
5729 static void gen_addq(DisasContext *s, TCGv_i64 val, int rlow, int rhigh)
5730 {
5731 TCGv_i64 tmp;
5732 TCGv tmpl;
5733 TCGv tmph;
5734
5735 /* Load 64-bit value rd:rn. */
5736 tmpl = load_reg(s, rlow);
5737 tmph = load_reg(s, rhigh);
5738 tmp = tcg_temp_new_i64();
5739 tcg_gen_concat_i32_i64(tmp, tmpl, tmph);
5740 dead_tmp(tmpl);
5741 dead_tmp(tmph);
5742 tcg_gen_add_i64(val, val, tmp);
5743 tcg_temp_free_i64(tmp);
5744 }
5745
5746 /* Set N and Z flags from a 64-bit value. */
5747 static void gen_logicq_cc(TCGv_i64 val)
5748 {
5749 TCGv tmp = new_tmp();
5750 gen_helper_logicq_cc(tmp, val);
5751 gen_logic_CC(tmp);
5752 dead_tmp(tmp);
5753 }
5754
5755 static void disas_arm_insn(CPUState * env, DisasContext *s)
5756 {
5757 unsigned int cond, insn, val, op1, i, shift, rm, rs, rn, rd, sh;
5758 TCGv tmp;
5759 TCGv tmp2;
5760 TCGv tmp3;
5761 TCGv addr;
5762 TCGv_i64 tmp64;
5763
5764 insn = ldl_code(s->pc);
5765 s->pc += 4;
5766
5767 /* M variants do not implement ARM mode. */
5768 if (IS_M(env))
5769 goto illegal_op;
5770 cond = insn >> 28;
5771 if (cond == 0xf){
5772 /* Unconditional instructions. */
5773 if (((insn >> 25) & 7) == 1) {
5774 /* NEON Data processing. */
5775 if (!arm_feature(env, ARM_FEATURE_NEON))
5776 goto illegal_op;
5777
5778 if (disas_neon_data_insn(env, s, insn))
5779 goto illegal_op;
5780 return;
5781 }
5782 if ((insn & 0x0f100000) == 0x04000000) {
5783 /* NEON load/store. */
5784 if (!arm_feature(env, ARM_FEATURE_NEON))
5785 goto illegal_op;
5786
5787 if (disas_neon_ls_insn(env, s, insn))
5788 goto illegal_op;
5789 return;
5790 }
5791 if ((insn & 0x0d70f000) == 0x0550f000)
5792 return; /* PLD */
5793 else if ((insn & 0x0ffffdff) == 0x01010000) {
5794 ARCH(6);
5795 /* setend */
5796 if (insn & (1 << 9)) {
5797 /* BE8 mode not implemented. */
5798 goto illegal_op;
5799 }
5800 return;
5801 } else if ((insn & 0x0fffff00) == 0x057ff000) {
5802 switch ((insn >> 4) & 0xf) {
5803 case 1: /* clrex */
5804 ARCH(6K);
5805 gen_helper_clrex(cpu_env);
5806 return;
5807 case 4: /* dsb */
5808 case 5: /* dmb */
5809 case 6: /* isb */
5810 ARCH(7);
5811 /* We don't emulate caches so these are a no-op. */
5812 return;
5813 default:
5814 goto illegal_op;
5815 }
5816 } else if ((insn & 0x0e5fffe0) == 0x084d0500) {
5817 /* srs */
5818 int32_t offset;
5819 if (IS_USER(s))
5820 goto illegal_op;
5821 ARCH(6);
5822 op1 = (insn & 0x1f);
5823 if (op1 == (env->uncached_cpsr & CPSR_M)) {
5824 addr = load_reg(s, 13);
5825 } else {
5826 addr = new_tmp();
5827 tmp = tcg_const_i32(op1);
5828 gen_helper_get_r13_banked(addr, cpu_env, tmp);
5829 tcg_temp_free_i32(tmp);
5830 }
5831 i = (insn >> 23) & 3;
5832 switch (i) {
5833 case 0: offset = -4; break; /* DA */
5834 case 1: offset = 0; break; /* IA */
5835 case 2: offset = -8; break; /* DB */
5836 case 3: offset = 4; break; /* IB */
5837 default: abort();
5838 }
5839 if (offset)
5840 tcg_gen_addi_i32(addr, addr, offset);
5841 tmp = load_reg(s, 14);
5842 gen_st32(tmp, addr, 0);
5843 tmp = load_cpu_field(spsr);
5844 tcg_gen_addi_i32(addr, addr, 4);
5845 gen_st32(tmp, addr, 0);
5846 if (insn & (1 << 21)) {
5847 /* Base writeback. */
5848 switch (i) {
5849 case 0: offset = -8; break;
5850 case 1: offset = 4; break;
5851 case 2: offset = -4; break;
5852 case 3: offset = 0; break;
5853 default: abort();
5854 }
5855 if (offset)
5856 tcg_gen_addi_i32(addr, addr, offset);
5857 if (op1 == (env->uncached_cpsr & CPSR_M)) {
5858 store_reg(s, 13, addr);
5859 } else {
5860 tmp = tcg_const_i32(op1);
5861 gen_helper_set_r13_banked(cpu_env, tmp, addr);
5862 tcg_temp_free_i32(tmp);
5863 dead_tmp(addr);
5864 }
5865 } else {
5866 dead_tmp(addr);
5867 }
5868 } else if ((insn & 0x0e5fffe0) == 0x081d0a00) {
5869 /* rfe */
5870 int32_t offset;
5871 if (IS_USER(s))
5872 goto illegal_op;
5873 ARCH(6);
5874 rn = (insn >> 16) & 0xf;
5875 addr = load_reg(s, rn);
5876 i = (insn >> 23) & 3;
5877 switch (i) {
5878 case 0: offset = -4; break; /* DA */
5879 case 1: offset = 0; break; /* IA */
5880 case 2: offset = -8; break; /* DB */
5881 case 3: offset = 4; break; /* IB */
5882 default: abort();
5883 }
5884 if (offset)
5885 tcg_gen_addi_i32(addr, addr, offset);
5886 /* Load PC into tmp and CPSR into tmp2. */
5887 tmp = gen_ld32(addr, 0);
5888 tcg_gen_addi_i32(addr, addr, 4);
5889 tmp2 = gen_ld32(addr, 0);
5890 if (insn & (1 << 21)) {
5891 /* Base writeback. */
5892 switch (i) {
5893 case 0: offset = -8; break;
5894 case 1: offset = 4; break;
5895 case 2: offset = -4; break;
5896 case 3: offset = 0; break;
5897 default: abort();
5898 }
5899 if (offset)
5900 tcg_gen_addi_i32(addr, addr, offset);
5901 store_reg(s, rn, addr);
5902 } else {
5903 dead_tmp(addr);
5904 }
5905 gen_rfe(s, tmp, tmp2);
5906 return;
5907 } else if ((insn & 0x0e000000) == 0x0a000000) {
5908 /* branch link and change to thumb (blx <offset>) */
5909 int32_t offset;
5910
5911 val = (uint32_t)s->pc;
5912 tmp = new_tmp();
5913 tcg_gen_movi_i32(tmp, val);
5914 store_reg(s, 14, tmp);
5915 /* Sign-extend the 24-bit offset */
5916 offset = (((int32_t)insn) << 8) >> 8;
5917 /* offset * 4 + bit24 * 2 + (thumb bit) */
5918 val += (offset << 2) | ((insn >> 23) & 2) | 1;
5919 /* pipeline offset */
5920 val += 4;
5921 gen_bx_im(s, val);
5922 return;
5923 } else if ((insn & 0x0e000f00) == 0x0c000100) {
5924 if (arm_feature(env, ARM_FEATURE_IWMMXT)) {
5925 /* iWMMXt register transfer. */
5926 if (env->cp15.c15_cpar & (1 << 1))
5927 if (!disas_iwmmxt_insn(env, s, insn))
5928 return;
5929 }
5930 } else if ((insn & 0x0fe00000) == 0x0c400000) {
5931 /* Coprocessor double register transfer. */
5932 } else if ((insn & 0x0f000010) == 0x0e000010) {
5933 /* Additional coprocessor register transfer. */
5934 } else if ((insn & 0x0ff10020) == 0x01000000) {
5935 uint32_t mask;
5936 uint32_t val;
5937 /* cps (privileged) */
5938 if (IS_USER(s))
5939 return;
5940 mask = val = 0;
5941 if (insn & (1 << 19)) {
5942 if (insn & (1 << 8))
5943 mask |= CPSR_A;
5944 if (insn & (1 << 7))
5945 mask |= CPSR_I;
5946 if (insn & (1 << 6))
5947 mask |= CPSR_F;
5948 if (insn & (1 << 18))
5949 val |= mask;
5950 }
5951 if (insn & (1 << 17)) {
5952 mask |= CPSR_M;
5953 val |= (insn & 0x1f);
5954 }
5955 if (mask) {
5956 gen_set_psr_im(s, mask, 0, val);
5957 }
5958 return;
5959 }
5960 goto illegal_op;
5961 }
5962 if (cond != 0xe) {
5963 /* if not always execute, we generate a conditional jump to
5964 next instruction */
5965 s->condlabel = gen_new_label();
5966 gen_test_cc(cond ^ 1, s->condlabel);
5967 s->condjmp = 1;
5968 }
5969 if ((insn & 0x0f900000) == 0x03000000) {
5970 if ((insn & (1 << 21)) == 0) {
5971 ARCH(6T2);
5972 rd = (insn >> 12) & 0xf;
5973 val = ((insn >> 4) & 0xf000) | (insn & 0xfff);
5974 if ((insn & (1 << 22)) == 0) {
5975 /* MOVW */
5976 tmp = new_tmp();
5977 tcg_gen_movi_i32(tmp, val);
5978 } else {
5979 /* MOVT */
5980 tmp = load_reg(s, rd);
5981 tcg_gen_ext16u_i32(tmp, tmp);
5982 tcg_gen_ori_i32(tmp, tmp, val << 16);
5983 }
5984 store_reg(s, rd, tmp);
5985 } else {
5986 if (((insn >> 12) & 0xf) != 0xf)
5987 goto illegal_op;
5988 if (((insn >> 16) & 0xf) == 0) {
5989 gen_nop_hint(s, insn & 0xff);
5990 } else {
5991 /* CPSR = immediate */
5992 val = insn & 0xff;
5993 shift = ((insn >> 8) & 0xf) * 2;
5994 if (shift)
5995 val = (val >> shift) | (val << (32 - shift));
5996 i = ((insn & (1 << 22)) != 0);
5997 if (gen_set_psr_im(s, msr_mask(env, s, (insn >> 16) & 0xf, i), i, val))
5998 goto illegal_op;
5999 }
6000 }
6001 } else if ((insn & 0x0f900000) == 0x01000000
6002 && (insn & 0x00000090) != 0x00000090) {
6003 /* miscellaneous instructions */
6004 op1 = (insn >> 21) & 3;
6005 sh = (insn >> 4) & 0xf;
6006 rm = insn & 0xf;
6007 switch (sh) {
6008 case 0x0: /* move program status register */
6009 if (op1 & 1) {
6010 /* PSR = reg */
6011 tmp = load_reg(s, rm);
6012 i = ((op1 & 2) != 0);
6013 if (gen_set_psr(s, msr_mask(env, s, (insn >> 16) & 0xf, i), i, tmp))
6014 goto illegal_op;
6015 } else {
6016 /* reg = PSR */
6017 rd = (insn >> 12) & 0xf;
6018 if (op1 & 2) {
6019 if (IS_USER(s))
6020 goto illegal_op;
6021 tmp = load_cpu_field(spsr);
6022 } else {
6023 tmp = new_tmp();
6024 gen_helper_cpsr_read(tmp);
6025 }
6026 store_reg(s, rd, tmp);
6027 }
6028 break;
6029 case 0x1:
6030 if (op1 == 1) {
6031 /* branch/exchange thumb (bx). */
6032 tmp = load_reg(s, rm);
6033 gen_bx(s, tmp);
6034 } else if (op1 == 3) {
6035 /* clz */
6036 rd = (insn >> 12) & 0xf;
6037 tmp = load_reg(s, rm);
6038 gen_helper_clz(tmp, tmp);
6039 store_reg(s, rd, tmp);
6040 } else {
6041 goto illegal_op;
6042 }
6043 break;
6044 case 0x2:
6045 if (op1 == 1) {
6046 ARCH(5J); /* bxj */
6047 /* Trivial implementation equivalent to bx. */
6048 tmp = load_reg(s, rm);
6049 gen_bx(s, tmp);
6050 } else {
6051 goto illegal_op;
6052 }
6053 break;
6054 case 0x3:
6055 if (op1 != 1)
6056 goto illegal_op;
6057
6058 /* branch link/exchange thumb (blx) */
6059 tmp = load_reg(s, rm);
6060 tmp2 = new_tmp();
6061 tcg_gen_movi_i32(tmp2, s->pc);
6062 store_reg(s, 14, tmp2);
6063 gen_bx(s, tmp);
6064 break;
6065 case 0x5: /* saturating add/subtract */
6066 rd = (insn >> 12) & 0xf;
6067 rn = (insn >> 16) & 0xf;
6068 tmp = load_reg(s, rm);
6069 tmp2 = load_reg(s, rn);
6070 if (op1 & 2)
6071 gen_helper_double_saturate(tmp2, tmp2);
6072 if (op1 & 1)
6073 gen_helper_sub_saturate(tmp, tmp, tmp2);
6074 else
6075 gen_helper_add_saturate(tmp, tmp, tmp2);
6076 dead_tmp(tmp2);
6077 store_reg(s, rd, tmp);
6078 break;
6079 case 7: /* bkpt */
6080 gen_set_condexec(s);
6081 gen_set_pc_im(s->pc - 4);
6082 gen_exception(EXCP_BKPT);
6083 s->is_jmp = DISAS_JUMP;
6084 break;
6085 case 0x8: /* signed multiply */
6086 case 0xa:
6087 case 0xc:
6088 case 0xe:
6089 rs = (insn >> 8) & 0xf;
6090 rn = (insn >> 12) & 0xf;
6091 rd = (insn >> 16) & 0xf;
6092 if (op1 == 1) {
6093 /* (32 * 16) >> 16 */
6094 tmp = load_reg(s, rm);
6095 tmp2 = load_reg(s, rs);
6096 if (sh & 4)
6097 tcg_gen_sari_i32(tmp2, tmp2, 16);
6098 else
6099 gen_sxth(tmp2);
6100 tmp64 = gen_muls_i64_i32(tmp, tmp2);
6101 tcg_gen_shri_i64(tmp64, tmp64, 16);
6102 tmp = new_tmp();
6103 tcg_gen_trunc_i64_i32(tmp, tmp64);
6104 tcg_temp_free_i64(tmp64);
6105 if ((sh & 2) == 0) {
6106 tmp2 = load_reg(s, rn);
6107 gen_helper_add_setq(tmp, tmp, tmp2);
6108 dead_tmp(tmp2);
6109 }
6110 store_reg(s, rd, tmp);
6111 } else {
6112 /* 16 * 16 */
6113 tmp = load_reg(s, rm);
6114 tmp2 = load_reg(s, rs);
6115 gen_mulxy(tmp, tmp2, sh & 2, sh & 4);
6116 dead_tmp(tmp2);
6117 if (op1 == 2) {
6118 tmp64 = tcg_temp_new_i64();
6119 tcg_gen_ext_i32_i64(tmp64, tmp);
6120 dead_tmp(tmp);
6121 gen_addq(s, tmp64, rn, rd);
6122 gen_storeq_reg(s, rn, rd, tmp64);
6123 tcg_temp_free_i64(tmp64);
6124 } else {
6125 if (op1 == 0) {
6126 tmp2 = load_reg(s, rn);
6127 gen_helper_add_setq(tmp, tmp, tmp2);
6128 dead_tmp(tmp2);
6129 }
6130 store_reg(s, rd, tmp);
6131 }
6132 }
6133 break;
6134 default:
6135 goto illegal_op;
6136 }
6137 } else if (((insn & 0x0e000000) == 0 &&
6138 (insn & 0x00000090) != 0x90) ||
6139 ((insn & 0x0e000000) == (1 << 25))) {
6140 int set_cc, logic_cc, shiftop;
6141
6142 op1 = (insn >> 21) & 0xf;
6143 set_cc = (insn >> 20) & 1;
6144 logic_cc = table_logic_cc[op1] & set_cc;
6145
6146 /* data processing instruction */
6147 if (insn & (1 << 25)) {
6148 /* immediate operand */
6149 val = insn & 0xff;
6150 shift = ((insn >> 8) & 0xf) * 2;
6151 if (shift) {
6152 val = (val >> shift) | (val << (32 - shift));
6153 }
6154 tmp2 = new_tmp();
6155 tcg_gen_movi_i32(tmp2, val);
6156 if (logic_cc && shift) {
6157 gen_set_CF_bit31(tmp2);
6158 }
6159 } else {
6160 /* register */
6161 rm = (insn) & 0xf;
6162 tmp2 = load_reg(s, rm);
6163 shiftop = (insn >> 5) & 3;
6164 if (!(insn & (1 << 4))) {
6165 shift = (insn >> 7) & 0x1f;
6166 gen_arm_shift_im(tmp2, shiftop, shift, logic_cc);
6167 } else {
6168 rs = (insn >> 8) & 0xf;
6169 tmp = load_reg(s, rs);
6170 gen_arm_shift_reg(tmp2, shiftop, tmp, logic_cc);
6171 }
6172 }
6173 if (op1 != 0x0f && op1 != 0x0d) {
6174 rn = (insn >> 16) & 0xf;
6175 tmp = load_reg(s, rn);
6176 } else {
6177 TCGV_UNUSED(tmp);
6178 }
6179 rd = (insn >> 12) & 0xf;
6180 switch(op1) {
6181 case 0x00:
6182 tcg_gen_and_i32(tmp, tmp, tmp2);
6183 if (logic_cc) {
6184 gen_logic_CC(tmp);
6185 }
6186 store_reg_bx(env, s, rd, tmp);
6187 break;
6188 case 0x01:
6189 tcg_gen_xor_i32(tmp, tmp, tmp2);
6190 if (logic_cc) {
6191 gen_logic_CC(tmp);
6192 }
6193 store_reg_bx(env, s, rd, tmp);
6194 break;
6195 case 0x02:
6196 if (set_cc && rd == 15) {
6197 /* SUBS r15, ... is used for exception return. */
6198 if (IS_USER(s)) {
6199 goto illegal_op;
6200 }
6201 gen_helper_sub_cc(tmp, tmp, tmp2);
6202 gen_exception_return(s, tmp);
6203 } else {
6204 if (set_cc) {
6205 gen_helper_sub_cc(tmp, tmp, tmp2);
6206 } else {
6207 tcg_gen_sub_i32(tmp, tmp, tmp2);
6208 }
6209 store_reg_bx(env, s, rd, tmp);
6210 }
6211 break;
6212 case 0x03:
6213 if (set_cc) {
6214 gen_helper_sub_cc(tmp, tmp2, tmp);
6215 } else {
6216 tcg_gen_sub_i32(tmp, tmp2, tmp);
6217 }
6218 store_reg_bx(env, s, rd, tmp);
6219 break;
6220 case 0x04:
6221 if (set_cc) {
6222 gen_helper_add_cc(tmp, tmp, tmp2);
6223 } else {
6224 tcg_gen_add_i32(tmp, tmp, tmp2);
6225 }
6226 store_reg_bx(env, s, rd, tmp);
6227 break;
6228 case 0x05:
6229 if (set_cc) {
6230 gen_helper_adc_cc(tmp, tmp, tmp2);
6231 } else {
6232 gen_add_carry(tmp, tmp, tmp2);
6233 }
6234 store_reg_bx(env, s, rd, tmp);
6235 break;
6236 case 0x06:
6237 if (set_cc) {
6238 gen_helper_sbc_cc(tmp, tmp, tmp2);
6239 } else {
6240 gen_sub_carry(tmp, tmp, tmp2);
6241 }
6242 store_reg_bx(env, s, rd, tmp);
6243 break;
6244 case 0x07:
6245 if (set_cc) {
6246 gen_helper_sbc_cc(tmp, tmp2, tmp);
6247 } else {
6248 gen_sub_carry(tmp, tmp2, tmp);
6249 }
6250 store_reg_bx(env, s, rd, tmp);
6251 break;
6252 case 0x08:
6253 if (set_cc) {
6254 tcg_gen_and_i32(tmp, tmp, tmp2);
6255 gen_logic_CC(tmp);
6256 }
6257 dead_tmp(tmp);
6258 break;
6259 case 0x09:
6260 if (set_cc) {
6261 tcg_gen_xor_i32(tmp, tmp, tmp2);
6262 gen_logic_CC(tmp);
6263 }
6264 dead_tmp(tmp);
6265 break;
6266 case 0x0a:
6267 if (set_cc) {
6268 gen_helper_sub_cc(tmp, tmp, tmp2);
6269 }
6270 dead_tmp(tmp);
6271 break;
6272 case 0x0b:
6273 if (set_cc) {
6274 gen_helper_add_cc(tmp, tmp, tmp2);
6275 }
6276 dead_tmp(tmp);
6277 break;
6278 case 0x0c:
6279 tcg_gen_or_i32(tmp, tmp, tmp2);
6280 if (logic_cc) {
6281 gen_logic_CC(tmp);
6282 }
6283 store_reg_bx(env, s, rd, tmp);
6284 break;
6285 case 0x0d:
6286 if (logic_cc && rd == 15) {
6287 /* MOVS r15, ... is used for exception return. */
6288 if (IS_USER(s)) {
6289 goto illegal_op;
6290 }
6291 gen_exception_return(s, tmp2);
6292 } else {
6293 if (logic_cc) {
6294 gen_logic_CC(tmp2);
6295 }
6296 store_reg_bx(env, s, rd, tmp2);
6297 }
6298 break;
6299 case 0x0e:
6300 tcg_gen_bic_i32(tmp, tmp, tmp2);
6301 if (logic_cc) {
6302 gen_logic_CC(tmp);
6303 }
6304 store_reg_bx(env, s, rd, tmp);
6305 break;
6306 default:
6307 case 0x0f:
6308 tcg_gen_not_i32(tmp2, tmp2);
6309 if (logic_cc) {
6310 gen_logic_CC(tmp2);
6311 }
6312 store_reg_bx(env, s, rd, tmp2);
6313 break;
6314 }
6315 if (op1 != 0x0f && op1 != 0x0d) {
6316 dead_tmp(tmp2);
6317 }
6318 } else {
6319 /* other instructions */
6320 op1 = (insn >> 24) & 0xf;
6321 switch(op1) {
6322 case 0x0:
6323 case 0x1:
6324 /* multiplies, extra load/stores */
6325 sh = (insn >> 5) & 3;
6326 if (sh == 0) {
6327 if (op1 == 0x0) {
6328 rd = (insn >> 16) & 0xf;
6329 rn = (insn >> 12) & 0xf;
6330 rs = (insn >> 8) & 0xf;
6331 rm = (insn) & 0xf;
6332 op1 = (insn >> 20) & 0xf;
6333 switch (op1) {
6334 case 0: case 1: case 2: case 3: case 6:
6335 /* 32 bit mul */
6336 tmp = load_reg(s, rs);
6337 tmp2 = load_reg(s, rm);
6338 tcg_gen_mul_i32(tmp, tmp, tmp2);
6339 dead_tmp(tmp2);
6340 if (insn & (1 << 22)) {
6341 /* Subtract (mls) */
6342 ARCH(6T2);
6343 tmp2 = load_reg(s, rn);
6344 tcg_gen_sub_i32(tmp, tmp2, tmp);
6345 dead_tmp(tmp2);
6346 } else if (insn & (1 << 21)) {
6347 /* Add */
6348 tmp2 = load_reg(s, rn);
6349 tcg_gen_add_i32(tmp, tmp, tmp2);
6350 dead_tmp(tmp2);
6351 }
6352 if (insn & (1 << 20))
6353 gen_logic_CC(tmp);
6354 store_reg(s, rd, tmp);
6355 break;
6356 default:
6357 /* 64 bit mul */
6358 tmp = load_reg(s, rs);
6359 tmp2 = load_reg(s, rm);
6360 if (insn & (1 << 22))
6361 tmp64 = gen_muls_i64_i32(tmp, tmp2);
6362 else
6363 tmp64 = gen_mulu_i64_i32(tmp, tmp2);
6364 if (insn & (1 << 21)) /* mult accumulate */
6365 gen_addq(s, tmp64, rn, rd);
6366 if (!(insn & (1 << 23))) { /* double accumulate */
6367 ARCH(6);
6368 gen_addq_lo(s, tmp64, rn);
6369 gen_addq_lo(s, tmp64, rd);
6370 }
6371 if (insn & (1 << 20))
6372 gen_logicq_cc(tmp64);
6373 gen_storeq_reg(s, rn, rd, tmp64);
6374 tcg_temp_free_i64(tmp64);
6375 break;
6376 }
6377 } else {
6378 rn = (insn >> 16) & 0xf;
6379 rd = (insn >> 12) & 0xf;
6380 if (insn & (1 << 23)) {
6381 /* load/store exclusive */
6382 op1 = (insn >> 21) & 0x3;
6383 if (op1)
6384 ARCH(6K);
6385 else
6386 ARCH(6);
6387 addr = tcg_temp_local_new_i32();
6388 load_reg_var(s, addr, rn);
6389 if (insn & (1 << 20)) {
6390 gen_helper_mark_exclusive(cpu_env, addr);
6391 switch (op1) {
6392 case 0: /* ldrex */
6393 tmp = gen_ld32(addr, IS_USER(s));
6394 break;
6395 case 1: /* ldrexd */
6396 tmp = gen_ld32(addr, IS_USER(s));
6397 store_reg(s, rd, tmp);
6398 tcg_gen_addi_i32(addr, addr, 4);
6399 tmp = gen_ld32(addr, IS_USER(s));
6400 rd++;
6401 break;
6402 case 2: /* ldrexb */
6403 tmp = gen_ld8u(addr, IS_USER(s));
6404 break;
6405 case 3: /* ldrexh */
6406 tmp = gen_ld16u(addr, IS_USER(s));
6407 break;
6408 default:
6409 abort();
6410 }
6411 store_reg(s, rd, tmp);
6412 } else {
6413 int label = gen_new_label();
6414 rm = insn & 0xf;
6415 tmp2 = tcg_temp_local_new_i32();
6416 gen_helper_test_exclusive(tmp2, cpu_env, addr);
6417 tcg_gen_brcondi_i32(TCG_COND_NE, tmp2, 0, label);
6418 tmp = load_reg(s,rm);
6419 switch (op1) {
6420 case 0: /* strex */
6421 gen_st32(tmp, addr, IS_USER(s));
6422 break;
6423 case 1: /* strexd */
6424 gen_st32(tmp, addr, IS_USER(s));
6425 tcg_gen_addi_i32(addr, addr, 4);
6426 tmp = load_reg(s, rm + 1);
6427 gen_st32(tmp, addr, IS_USER(s));
6428 break;
6429 case 2: /* strexb */
6430 gen_st8(tmp, addr, IS_USER(s));
6431 break;
6432 case 3: /* strexh */
6433 gen_st16(tmp, addr, IS_USER(s));
6434 break;
6435 default:
6436 abort();
6437 }
6438 gen_set_label(label);
6439 tcg_gen_mov_i32(cpu_R[rd], tmp2);
6440 tcg_temp_free(tmp2);
6441 }
6442 tcg_temp_free(addr);
6443 } else {
6444 /* SWP instruction */
6445 rm = (insn) & 0xf;
6446
6447 /* ??? This is not really atomic. However we know
6448 we never have multiple CPUs running in parallel,
6449 so it is good enough. */
6450 addr = load_reg(s, rn);
6451 tmp = load_reg(s, rm);
6452 if (insn & (1 << 22)) {
6453 tmp2 = gen_ld8u(addr, IS_USER(s));
6454 gen_st8(tmp, addr, IS_USER(s));
6455 } else {
6456 tmp2 = gen_ld32(addr, IS_USER(s));
6457 gen_st32(tmp, addr, IS_USER(s));
6458 }
6459 dead_tmp(addr);
6460 store_reg(s, rd, tmp2);
6461 }
6462 }
6463 } else {
6464 int address_offset;
6465 int load;
6466 /* Misc load/store */
6467 rn = (insn >> 16) & 0xf;
6468 rd = (insn >> 12) & 0xf;
6469 addr = load_reg(s, rn);
6470 if (insn & (1 << 24))
6471 gen_add_datah_offset(s, insn, 0, addr);
6472 address_offset = 0;
6473 if (insn & (1 << 20)) {
6474 /* load */
6475 switch(sh) {
6476 case 1:
6477 tmp = gen_ld16u(addr, IS_USER(s));
6478 break;
6479 case 2:
6480 tmp = gen_ld8s(addr, IS_USER(s));
6481 break;
6482 default:
6483 case 3:
6484 tmp = gen_ld16s(addr, IS_USER(s));
6485 break;
6486 }
6487 load = 1;
6488 } else if (sh & 2) {
6489 /* doubleword */
6490 if (sh & 1) {
6491 /* store */
6492 tmp = load_reg(s, rd);
6493 gen_st32(tmp, addr, IS_USER(s));
6494 tcg_gen_addi_i32(addr, addr, 4);
6495 tmp = load_reg(s, rd + 1);
6496 gen_st32(tmp, addr, IS_USER(s));
6497 load = 0;
6498 } else {
6499 /* load */
6500 tmp = gen_ld32(addr, IS_USER(s));
6501 store_reg(s, rd, tmp);
6502 tcg_gen_addi_i32(addr, addr, 4);
6503 tmp = gen_ld32(addr, IS_USER(s));
6504 rd++;
6505 load = 1;
6506 }
6507 address_offset = -4;
6508 } else {
6509 /* store */
6510 tmp = load_reg(s, rd);
6511 gen_st16(tmp, addr, IS_USER(s));
6512 load = 0;
6513 }
6514 /* Perform base writeback before the loaded value to
6515 ensure correct behavior with overlapping index registers.
6516 ldrd with base writeback is is undefined if the
6517 destination and index registers overlap. */
6518 if (!(insn & (1 << 24))) {
6519 gen_add_datah_offset(s, insn, address_offset, addr);
6520 store_reg(s, rn, addr);
6521 } else if (insn & (1 << 21)) {
6522 if (address_offset)
6523 tcg_gen_addi_i32(addr, addr, address_offset);
6524 store_reg(s, rn, addr);
6525 } else {
6526 dead_tmp(addr);
6527 }
6528 if (load) {
6529 /* Complete the load. */
6530 store_reg(s, rd, tmp);
6531 }
6532 }
6533 break;
6534 case 0x4:
6535 case 0x5:
6536 goto do_ldst;
6537 case 0x6:
6538 case 0x7:
6539 if (insn & (1 << 4)) {
6540 ARCH(6);
6541 /* Armv6 Media instructions. */
6542 rm = insn & 0xf;
6543 rn = (insn >> 16) & 0xf;
6544 rd = (insn >> 12) & 0xf;
6545 rs = (insn >> 8) & 0xf;
6546 switch ((insn >> 23) & 3) {
6547 case 0: /* Parallel add/subtract. */
6548 op1 = (insn >> 20) & 7;
6549 tmp = load_reg(s, rn);
6550 tmp2 = load_reg(s, rm);
6551 sh = (insn >> 5) & 7;
6552 if ((op1 & 3) == 0 || sh == 5 || sh == 6)
6553 goto illegal_op;
6554 gen_arm_parallel_addsub(op1, sh, tmp, tmp2);
6555 dead_tmp(tmp2);
6556 store_reg(s, rd, tmp);
6557 break;
6558 case 1:
6559 if ((insn & 0x00700020) == 0) {
6560 /* Halfword pack. */
6561 tmp = load_reg(s, rn);
6562 tmp2 = load_reg(s, rm);
6563 shift = (insn >> 7) & 0x1f;
6564 if (insn & (1 << 6)) {
6565 /* pkhtb */
6566 if (shift == 0)
6567 shift = 31;
6568 tcg_gen_sari_i32(tmp2, tmp2, shift);
6569 tcg_gen_andi_i32(tmp, tmp, 0xffff0000);
6570 tcg_gen_ext16u_i32(tmp2, tmp2);
6571 } else {
6572 /* pkhbt */
6573 if (shift)
6574 tcg_gen_shli_i32(tmp2, tmp2, shift);
6575 tcg_gen_ext16u_i32(tmp, tmp);
6576 tcg_gen_andi_i32(tmp2, tmp2, 0xffff0000);
6577 }
6578 tcg_gen_or_i32(tmp, tmp, tmp2);
6579 dead_tmp(tmp2);
6580 store_reg(s, rd, tmp);
6581 } else if ((insn & 0x00200020) == 0x00200000) {
6582 /* [us]sat */
6583 tmp = load_reg(s, rm);
6584 shift = (insn >> 7) & 0x1f;
6585 if (insn & (1 << 6)) {
6586 if (shift == 0)
6587 shift = 31;
6588 tcg_gen_sari_i32(tmp, tmp, shift);
6589 } else {
6590 tcg_gen_shli_i32(tmp, tmp, shift);
6591 }
6592 sh = (insn >> 16) & 0x1f;
6593 if (sh != 0) {
6594 tmp2 = tcg_const_i32(sh);
6595 if (insn & (1 << 22))
6596 gen_helper_usat(tmp, tmp, tmp2);
6597 else
6598 gen_helper_ssat(tmp, tmp, tmp2);
6599 tcg_temp_free_i32(tmp2);
6600 }
6601 store_reg(s, rd, tmp);
6602 } else if ((insn & 0x00300fe0) == 0x00200f20) {
6603 /* [us]sat16 */
6604 tmp = load_reg(s, rm);
6605 sh = (insn >> 16) & 0x1f;
6606 if (sh != 0) {
6607 tmp2 = tcg_const_i32(sh);
6608 if (insn & (1 << 22))
6609 gen_helper_usat16(tmp, tmp, tmp2);
6610 else
6611 gen_helper_ssat16(tmp, tmp, tmp2);
6612 tcg_temp_free_i32(tmp2);
6613 }
6614 store_reg(s, rd, tmp);
6615 } else if ((insn & 0x00700fe0) == 0x00000fa0) {
6616 /* Select bytes. */
6617 tmp = load_reg(s, rn);
6618 tmp2 = load_reg(s, rm);
6619 tmp3 = new_tmp();
6620 tcg_gen_ld_i32(tmp3, cpu_env, offsetof(CPUState, GE));
6621 gen_helper_sel_flags(tmp, tmp3, tmp, tmp2);
6622 dead_tmp(tmp3);
6623 dead_tmp(tmp2);
6624 store_reg(s, rd, tmp);
6625 } else if ((insn & 0x000003e0) == 0x00000060) {
6626 tmp = load_reg(s, rm);
6627 shift = (insn >> 10) & 3;
6628 /* ??? In many cases it's not neccessary to do a
6629 rotate, a shift is sufficient. */
6630 if (shift != 0)
6631 tcg_gen_rori_i32(tmp, tmp, shift * 8);
6632 op1 = (insn >> 20) & 7;
6633 switch (op1) {
6634 case 0: gen_sxtb16(tmp); break;
6635 case 2: gen_sxtb(tmp); break;
6636 case 3: gen_sxth(tmp); break;
6637 case 4: gen_uxtb16(tmp); break;
6638 case 6: gen_uxtb(tmp); break;
6639 case 7: gen_uxth(tmp); break;
6640 default: goto illegal_op;
6641 }
6642 if (rn != 15) {
6643 tmp2 = load_reg(s, rn);
6644 if ((op1 & 3) == 0) {
6645 gen_add16(tmp, tmp2);
6646 } else {
6647 tcg_gen_add_i32(tmp, tmp, tmp2);
6648 dead_tmp(tmp2);
6649 }
6650 }
6651 store_reg(s, rd, tmp);
6652 } else if ((insn & 0x003f0f60) == 0x003f0f20) {
6653 /* rev */
6654 tmp = load_reg(s, rm);
6655 if (insn & (1 << 22)) {
6656 if (insn & (1 << 7)) {
6657 gen_revsh(tmp);
6658 } else {
6659 ARCH(6T2);
6660 gen_helper_rbit(tmp, tmp);
6661 }
6662 } else {
6663 if (insn & (1 << 7))
6664 gen_rev16(tmp);
6665 else
6666 tcg_gen_bswap32_i32(tmp, tmp);
6667 }
6668 store_reg(s, rd, tmp);
6669 } else {
6670 goto illegal_op;
6671 }
6672 break;
6673 case 2: /* Multiplies (Type 3). */
6674 tmp = load_reg(s, rm);
6675 tmp2 = load_reg(s, rs);
6676 if (insn & (1 << 20)) {
6677 /* Signed multiply most significant [accumulate]. */
6678 tmp64 = gen_muls_i64_i32(tmp, tmp2);
6679 if (insn & (1 << 5))
6680 tcg_gen_addi_i64(tmp64, tmp64, 0x80000000u);
6681 tcg_gen_shri_i64(tmp64, tmp64, 32);
6682 tmp = new_tmp();
6683 tcg_gen_trunc_i64_i32(tmp, tmp64);
6684 tcg_temp_free_i64(tmp64);
6685 if (rd != 15) {
6686 tmp2 = load_reg(s, rd);
6687 if (insn & (1 << 6)) {
6688 tcg_gen_sub_i32(tmp, tmp, tmp2);
6689 } else {
6690 tcg_gen_add_i32(tmp, tmp, tmp2);
6691 }
6692 dead_tmp(tmp2);
6693 }
6694 store_reg(s, rn, tmp);
6695 } else {
6696 if (insn & (1 << 5))
6697 gen_swap_half(tmp2);
6698 gen_smul_dual(tmp, tmp2);
6699 /* This addition cannot overflow. */
6700 if (insn & (1 << 6)) {
6701 tcg_gen_sub_i32(tmp, tmp, tmp2);
6702 } else {
6703 tcg_gen_add_i32(tmp, tmp, tmp2);
6704 }
6705 dead_tmp(tmp2);
6706 if (insn & (1 << 22)) {
6707 /* smlald, smlsld */
6708 tmp64 = tcg_temp_new_i64();
6709 tcg_gen_ext_i32_i64(tmp64, tmp);
6710 dead_tmp(tmp);
6711 gen_addq(s, tmp64, rd, rn);
6712 gen_storeq_reg(s, rd, rn, tmp64);
6713 tcg_temp_free_i64(tmp64);
6714 } else {
6715 /* smuad, smusd, smlad, smlsd */
6716 if (rd != 15)
6717 {
6718 tmp2 = load_reg(s, rd);
6719 gen_helper_add_setq(tmp, tmp, tmp2);
6720 dead_tmp(tmp2);
6721 }
6722 store_reg(s, rn, tmp);
6723 }
6724 }
6725 break;
6726 case 3:
6727 op1 = ((insn >> 17) & 0x38) | ((insn >> 5) & 7);
6728 switch (op1) {
6729 case 0: /* Unsigned sum of absolute differences. */
6730 ARCH(6);
6731 tmp = load_reg(s, rm);
6732 tmp2 = load_reg(s, rs);
6733 gen_helper_usad8(tmp, tmp, tmp2);
6734 dead_tmp(tmp2);
6735 if (rd != 15) {
6736 tmp2 = load_reg(s, rd);
6737 tcg_gen_add_i32(tmp, tmp, tmp2);
6738 dead_tmp(tmp2);
6739 }
6740 store_reg(s, rn, tmp);
6741 break;
6742 case 0x20: case 0x24: case 0x28: case 0x2c:
6743 /* Bitfield insert/clear. */
6744 ARCH(6T2);
6745 shift = (insn >> 7) & 0x1f;
6746 i = (insn >> 16) & 0x1f;
6747 i = i + 1 - shift;
6748 if (rm == 15) {
6749 tmp = new_tmp();
6750 tcg_gen_movi_i32(tmp, 0);
6751 } else {
6752 tmp = load_reg(s, rm);
6753 }
6754 if (i != 32) {
6755 tmp2 = load_reg(s, rd);
6756 gen_bfi(tmp, tmp2, tmp, shift, (1u << i) - 1);
6757 dead_tmp(tmp2);
6758 }
6759 store_reg(s, rd, tmp);
6760 break;
6761 case 0x12: case 0x16: case 0x1a: case 0x1e: /* sbfx */
6762 case 0x32: case 0x36: case 0x3a: case 0x3e: /* ubfx */
6763 ARCH(6T2);
6764 tmp = load_reg(s, rm);
6765 shift = (insn >> 7) & 0x1f;
6766 i = ((insn >> 16) & 0x1f) + 1;
6767 if (shift + i > 32)
6768 goto illegal_op;
6769 if (i < 32) {
6770 if (op1 & 0x20) {
6771 gen_ubfx(tmp, shift, (1u << i) - 1);
6772 } else {
6773 gen_sbfx(tmp, shift, i);
6774 }
6775 }
6776 store_reg(s, rd, tmp);
6777 break;
6778 default:
6779 goto illegal_op;
6780 }
6781 break;
6782 }
6783 break;
6784 }
6785 do_ldst:
6786 /* Check for undefined extension instructions
6787 * per the ARM Bible IE:
6788 * xxxx 0111 1111 xxxx xxxx xxxx 1111 xxxx
6789 */
6790 sh = (0xf << 20) | (0xf << 4);
6791 if (op1 == 0x7 && ((insn & sh) == sh))
6792 {
6793 goto illegal_op;
6794 }
6795 /* load/store byte/word */
6796 rn = (insn >> 16) & 0xf;
6797 rd = (insn >> 12) & 0xf;
6798 tmp2 = load_reg(s, rn);
6799 i = (IS_USER(s) || (insn & 0x01200000) == 0x00200000);
6800 if (insn & (1 << 24))
6801 gen_add_data_offset(s, insn, tmp2);
6802 if (insn & (1 << 20)) {
6803 /* load */
6804 if (insn & (1 << 22)) {
6805 tmp = gen_ld8u(tmp2, i);
6806 } else {
6807 tmp = gen_ld32(tmp2, i);
6808 }
6809 } else {
6810 /* store */
6811 tmp = load_reg(s, rd);
6812 if (insn & (1 << 22))
6813 gen_st8(tmp, tmp2, i);
6814 else
6815 gen_st32(tmp, tmp2, i);
6816 }
6817 if (!(insn & (1 << 24))) {
6818 gen_add_data_offset(s, insn, tmp2);
6819 store_reg(s, rn, tmp2);
6820 } else if (insn & (1 << 21)) {
6821 store_reg(s, rn, tmp2);
6822 } else {
6823 dead_tmp(tmp2);
6824 }
6825 if (insn & (1 << 20)) {
6826 /* Complete the load. */
6827 if (rd == 15)
6828 gen_bx(s, tmp);
6829 else
6830 store_reg(s, rd, tmp);
6831 }
6832 break;
6833 case 0x08:
6834 case 0x09:
6835 {
6836 int j, n, user, loaded_base;
6837 TCGv loaded_var;
6838 /* load/store multiple words */
6839 /* XXX: store correct base if write back */
6840 user = 0;
6841 if (insn & (1 << 22)) {
6842 if (IS_USER(s))
6843 goto illegal_op; /* only usable in supervisor mode */
6844
6845 if ((insn & (1 << 15)) == 0)
6846 user = 1;
6847 }
6848 rn = (insn >> 16) & 0xf;
6849 addr = load_reg(s, rn);
6850
6851 /* compute total size */
6852 loaded_base = 0;
6853 TCGV_UNUSED(loaded_var);
6854 n = 0;
6855 for(i=0;i<16;i++) {
6856 if (insn & (1 << i))
6857 n++;
6858 }
6859 /* XXX: test invalid n == 0 case ? */
6860 if (insn & (1 << 23)) {
6861 if (insn & (1 << 24)) {
6862 /* pre increment */
6863 tcg_gen_addi_i32(addr, addr, 4);
6864 } else {
6865 /* post increment */
6866 }
6867 } else {
6868 if (insn & (1 << 24)) {
6869 /* pre decrement */
6870 tcg_gen_addi_i32(addr, addr, -(n * 4));
6871 } else {
6872 /* post decrement */
6873 if (n != 1)
6874 tcg_gen_addi_i32(addr, addr, -((n - 1) * 4));
6875 }
6876 }
6877 j = 0;
6878 for(i=0;i<16;i++) {
6879 if (insn & (1 << i)) {
6880 if (insn & (1 << 20)) {
6881 /* load */
6882 tmp = gen_ld32(addr, IS_USER(s));
6883 if (i == 15) {
6884 gen_bx(s, tmp);
6885 } else if (user) {
6886 tmp2 = tcg_const_i32(i);
6887 gen_helper_set_user_reg(tmp2, tmp);
6888 tcg_temp_free_i32(tmp2);
6889 dead_tmp(tmp);
6890 } else if (i == rn) {
6891 loaded_var = tmp;
6892 loaded_base = 1;
6893 } else {
6894 store_reg(s, i, tmp);
6895 }
6896 } else {
6897 /* store */
6898 if (i == 15) {
6899 /* special case: r15 = PC + 8 */
6900 val = (long)s->pc + 4;
6901 tmp = new_tmp();
6902 tcg_gen_movi_i32(tmp, val);
6903 } else if (user) {
6904 tmp = new_tmp();
6905 tmp2 = tcg_const_i32(i);
6906 gen_helper_get_user_reg(tmp, tmp2);
6907 tcg_temp_free_i32(tmp2);
6908 } else {
6909 tmp = load_reg(s, i);
6910 }
6911 gen_st32(tmp, addr, IS_USER(s));
6912 }
6913 j++;
6914 /* no need to add after the last transfer */
6915 if (j != n)
6916 tcg_gen_addi_i32(addr, addr, 4);
6917 }
6918 }
6919 if (insn & (1 << 21)) {
6920 /* write back */
6921 if (insn & (1 << 23)) {
6922 if (insn & (1 << 24)) {
6923 /* pre increment */
6924 } else {
6925 /* post increment */
6926 tcg_gen_addi_i32(addr, addr, 4);
6927 }
6928 } else {
6929 if (insn & (1 << 24)) {
6930 /* pre decrement */
6931 if (n != 1)
6932 tcg_gen_addi_i32(addr, addr, -((n - 1) * 4));
6933 } else {
6934 /* post decrement */
6935 tcg_gen_addi_i32(addr, addr, -(n * 4));
6936 }
6937 }
6938 store_reg(s, rn, addr);
6939 } else {
6940 dead_tmp(addr);
6941 }
6942 if (loaded_base) {
6943 store_reg(s, rn, loaded_var);
6944 }
6945 if ((insn & (1 << 22)) && !user) {
6946 /* Restore CPSR from SPSR. */
6947 tmp = load_cpu_field(spsr);
6948 gen_set_cpsr(tmp, 0xffffffff);
6949 dead_tmp(tmp);
6950 s->is_jmp = DISAS_UPDATE;
6951 }
6952 }
6953 break;
6954 case 0xa:
6955 case 0xb:
6956 {
6957 int32_t offset;
6958
6959 /* branch (and link) */
6960 val = (int32_t)s->pc;
6961 if (insn & (1 << 24)) {
6962 tmp = new_tmp();
6963 tcg_gen_movi_i32(tmp, val);
6964 store_reg(s, 14, tmp);
6965 }
6966 offset = (((int32_t)insn << 8) >> 8);
6967 val += (offset << 2) + 4;
6968 gen_jmp(s, val);
6969 }
6970 break;
6971 case 0xc:
6972 case 0xd:
6973 case 0xe:
6974 /* Coprocessor. */
6975 if (disas_coproc_insn(env, s, insn))
6976 goto illegal_op;
6977 break;
6978 case 0xf:
6979 /* swi */
6980 gen_set_pc_im(s->pc);
6981 s->is_jmp = DISAS_SWI;
6982 break;
6983 default:
6984 illegal_op:
6985 gen_set_condexec(s);
6986 gen_set_pc_im(s->pc - 4);
6987 gen_exception(EXCP_UDEF);
6988 s->is_jmp = DISAS_JUMP;
6989 break;
6990 }
6991 }
6992 }
6993
6994 /* Return true if this is a Thumb-2 logical op. */
6995 static int
6996 thumb2_logic_op(int op)
6997 {
6998 return (op < 8);
6999 }
7000
7001 /* Generate code for a Thumb-2 data processing operation. If CONDS is nonzero
7002 then set condition code flags based on the result of the operation.
7003 If SHIFTER_OUT is nonzero then set the carry flag for logical operations
7004 to the high bit of T1.
7005 Returns zero if the opcode is valid. */
7006
7007 static int
7008 gen_thumb2_data_op(DisasContext *s, int op, int conds, uint32_t shifter_out, TCGv t0, TCGv t1)
7009 {
7010 int logic_cc;
7011
7012 logic_cc = 0;
7013 switch (op) {
7014 case 0: /* and */
7015 tcg_gen_and_i32(t0, t0, t1);
7016 logic_cc = conds;
7017 break;
7018 case 1: /* bic */
7019 tcg_gen_bic_i32(t0, t0, t1);
7020 logic_cc = conds;
7021 break;
7022 case 2: /* orr */
7023 tcg_gen_or_i32(t0, t0, t1);
7024 logic_cc = conds;
7025 break;
7026 case 3: /* orn */
7027 tcg_gen_not_i32(t1, t1);
7028 tcg_gen_or_i32(t0, t0, t1);
7029 logic_cc = conds;
7030 break;
7031 case 4: /* eor */
7032 tcg_gen_xor_i32(t0, t0, t1);
7033 logic_cc = conds;
7034 break;
7035 case 8: /* add */
7036 if (conds)
7037 gen_helper_add_cc(t0, t0, t1);
7038 else
7039 tcg_gen_add_i32(t0, t0, t1);
7040 break;
7041 case 10: /* adc */
7042 if (conds)
7043 gen_helper_adc_cc(t0, t0, t1);
7044 else
7045 gen_adc(t0, t1);
7046 break;
7047 case 11: /* sbc */
7048 if (conds)
7049 gen_helper_sbc_cc(t0, t0, t1);
7050 else
7051 gen_sub_carry(t0, t0, t1);
7052 break;
7053 case 13: /* sub */
7054 if (conds)
7055 gen_helper_sub_cc(t0, t0, t1);
7056 else
7057 tcg_gen_sub_i32(t0, t0, t1);
7058 break;
7059 case 14: /* rsb */
7060 if (conds)
7061 gen_helper_sub_cc(t0, t1, t0);
7062 else
7063 tcg_gen_sub_i32(t0, t1, t0);
7064 break;
7065 default: /* 5, 6, 7, 9, 12, 15. */
7066 return 1;
7067 }
7068 if (logic_cc) {
7069 gen_logic_CC(t0);
7070 if (shifter_out)
7071 gen_set_CF_bit31(t1);
7072 }
7073 return 0;
7074 }
7075
7076 /* Translate a 32-bit thumb instruction. Returns nonzero if the instruction
7077 is not legal. */
7078 static int disas_thumb2_insn(CPUState *env, DisasContext *s, uint16_t insn_hw1)
7079 {
7080 uint32_t insn, imm, shift, offset;
7081 uint32_t rd, rn, rm, rs;
7082 TCGv tmp;
7083 TCGv tmp2;
7084 TCGv tmp3;
7085 TCGv addr;
7086 TCGv_i64 tmp64;
7087 int op;
7088 int shiftop;
7089 int conds;
7090 int logic_cc;
7091
7092 if (!(arm_feature(env, ARM_FEATURE_THUMB2)
7093 || arm_feature (env, ARM_FEATURE_M))) {
7094 /* Thumb-1 cores may need to treat bl and blx as a pair of
7095 16-bit instructions to get correct prefetch abort behavior. */
7096 insn = insn_hw1;
7097 if ((insn & (1 << 12)) == 0) {
7098 /* Second half of blx. */
7099 offset = ((insn & 0x7ff) << 1);
7100 tmp = load_reg(s, 14);
7101 tcg_gen_addi_i32(tmp, tmp, offset);
7102 tcg_gen_andi_i32(tmp, tmp, 0xfffffffc);
7103
7104 tmp2 = new_tmp();
7105 tcg_gen_movi_i32(tmp2, s->pc | 1);
7106 store_reg(s, 14, tmp2);
7107 gen_bx(s, tmp);
7108 return 0;
7109 }
7110 if (insn & (1 << 11)) {
7111 /* Second half of bl. */
7112 offset = ((insn & 0x7ff) << 1) | 1;
7113 tmp = load_reg(s, 14);
7114 tcg_gen_addi_i32(tmp, tmp, offset);
7115
7116 tmp2 = new_tmp();
7117 tcg_gen_movi_i32(tmp2, s->pc | 1);
7118 store_reg(s, 14, tmp2);
7119 gen_bx(s, tmp);
7120 return 0;
7121 }
7122 if ((s->pc & ~TARGET_PAGE_MASK) == 0) {
7123 /* Instruction spans a page boundary. Implement it as two
7124 16-bit instructions in case the second half causes an
7125 prefetch abort. */
7126 offset = ((int32_t)insn << 21) >> 9;
7127 tcg_gen_movi_i32(cpu_R[14], s->pc + 2 + offset);
7128 return 0;
7129 }
7130 /* Fall through to 32-bit decode. */
7131 }
7132
7133 insn = lduw_code(s->pc);
7134 s->pc += 2;
7135 insn |= (uint32_t)insn_hw1 << 16;
7136
7137 if ((insn & 0xf800e800) != 0xf000e800) {
7138 ARCH(6T2);
7139 }
7140
7141 rn = (insn >> 16) & 0xf;
7142 rs = (insn >> 12) & 0xf;
7143 rd = (insn >> 8) & 0xf;
7144 rm = insn & 0xf;
7145 switch ((insn >> 25) & 0xf) {
7146 case 0: case 1: case 2: case 3:
7147 /* 16-bit instructions. Should never happen. */
7148 abort();
7149 case 4:
7150 if (insn & (1 << 22)) {
7151 /* Other load/store, table branch. */
7152 if (insn & 0x01200000) {
7153 /* Load/store doubleword. */
7154 if (rn == 15) {
7155 addr = new_tmp();
7156 tcg_gen_movi_i32(addr, s->pc & ~3);
7157 } else {
7158 addr = load_reg(s, rn);
7159 }
7160 offset = (insn & 0xff) * 4;
7161 if ((insn & (1 << 23)) == 0)
7162 offset = -offset;
7163 if (insn & (1 << 24)) {
7164 tcg_gen_addi_i32(addr, addr, offset);
7165 offset = 0;
7166 }
7167 if (insn & (1 << 20)) {
7168 /* ldrd */
7169 tmp = gen_ld32(addr, IS_USER(s));
7170 store_reg(s, rs, tmp);
7171 tcg_gen_addi_i32(addr, addr, 4);
7172 tmp = gen_ld32(addr, IS_USER(s));
7173 store_reg(s, rd, tmp);
7174 } else {
7175 /* strd */
7176 tmp = load_reg(s, rs);
7177 gen_st32(tmp, addr, IS_USER(s));
7178 tcg_gen_addi_i32(addr, addr, 4);
7179 tmp = load_reg(s, rd);
7180 gen_st32(tmp, addr, IS_USER(s));
7181 }
7182 if (insn & (1 << 21)) {
7183 /* Base writeback. */
7184 if (rn == 15)
7185 goto illegal_op;
7186 tcg_gen_addi_i32(addr, addr, offset - 4);
7187 store_reg(s, rn, addr);
7188 } else {
7189 dead_tmp(addr);
7190 }
7191 } else if ((insn & (1 << 23)) == 0) {
7192 /* Load/store exclusive word. */
7193 addr = tcg_temp_local_new();
7194 load_reg_var(s, addr, rn);
7195 if (insn & (1 << 20)) {
7196 gen_helper_mark_exclusive(cpu_env, addr);
7197 tmp = gen_ld32(addr, IS_USER(s));
7198 store_reg(s, rd, tmp);
7199 } else {
7200 int label = gen_new_label();
7201 tmp2 = tcg_temp_local_new();
7202 gen_helper_test_exclusive(tmp2, cpu_env, addr);
7203 tcg_gen_brcondi_i32(TCG_COND_NE, tmp2, 0, label);
7204 tmp = load_reg(s, rs);
7205 gen_st32(tmp, addr, IS_USER(s));
7206 gen_set_label(label);
7207 tcg_gen_mov_i32(cpu_R[rd], tmp2);
7208 tcg_temp_free(tmp2);
7209 }
7210 tcg_temp_free(addr);
7211 } else if ((insn & (1 << 6)) == 0) {
7212 /* Table Branch. */
7213 if (rn == 15) {
7214 addr = new_tmp();
7215 tcg_gen_movi_i32(addr, s->pc);
7216 } else {
7217 addr = load_reg(s, rn);
7218 }
7219 tmp = load_reg(s, rm);
7220 tcg_gen_add_i32(addr, addr, tmp);
7221 if (insn & (1 << 4)) {
7222 /* tbh */
7223 tcg_gen_add_i32(addr, addr, tmp);
7224 dead_tmp(tmp);
7225 tmp = gen_ld16u(addr, IS_USER(s));
7226 } else { /* tbb */
7227 dead_tmp(tmp);
7228 tmp = gen_ld8u(addr, IS_USER(s));
7229 }
7230 dead_tmp(addr);
7231 tcg_gen_shli_i32(tmp, tmp, 1);
7232 tcg_gen_addi_i32(tmp, tmp, s->pc);
7233 store_reg(s, 15, tmp);
7234 } else {
7235 /* Load/store exclusive byte/halfword/doubleword. */
7236 /* ??? These are not really atomic. However we know
7237 we never have multiple CPUs running in parallel,
7238 so it is good enough. */
7239 op = (insn >> 4) & 0x3;
7240 addr = tcg_temp_local_new();
7241 load_reg_var(s, addr, rn);
7242 if (insn & (1 << 20)) {
7243 gen_helper_mark_exclusive(cpu_env, addr);
7244 switch (op) {
7245 case 0:
7246 tmp = gen_ld8u(addr, IS_USER(s));
7247 break;
7248 case 1:
7249 tmp = gen_ld16u(addr, IS_USER(s));
7250 break;
7251 case 3:
7252 tmp = gen_ld32(addr, IS_USER(s));
7253 tcg_gen_addi_i32(addr, addr, 4);
7254 tmp2 = gen_ld32(addr, IS_USER(s));
7255 store_reg(s, rd, tmp2);
7256 break;
7257 default:
7258 goto illegal_op;
7259 }
7260 store_reg(s, rs, tmp);
7261 } else {
7262 int label = gen_new_label();
7263 tmp2 = tcg_temp_local_new();
7264 gen_helper_test_exclusive(tmp2, cpu_env, addr);
7265 tcg_gen_brcondi_i32(TCG_COND_NE, tmp2, 0, label);
7266 tmp = load_reg(s, rs);
7267 switch (op) {
7268 case 0:
7269 gen_st8(tmp, addr, IS_USER(s));
7270 break;
7271 case 1:
7272 gen_st16(tmp, addr, IS_USER(s));
7273 break;
7274 case 3:
7275 gen_st32(tmp, addr, IS_USER(s));
7276 tcg_gen_addi_i32(addr, addr, 4);
7277 tmp = load_reg(s, rd);
7278 gen_st32(tmp, addr, IS_USER(s));
7279 break;
7280 default:
7281 goto illegal_op;
7282 }
7283 gen_set_label(label);
7284 tcg_gen_mov_i32(cpu_R[rm], tmp2);
7285 tcg_temp_free(tmp2);
7286 }
7287 tcg_temp_free(addr);
7288 }
7289 } else {
7290 /* Load/store multiple, RFE, SRS. */
7291 if (((insn >> 23) & 1) == ((insn >> 24) & 1)) {
7292 /* Not available in user mode. */
7293 if (IS_USER(s))
7294 goto illegal_op;
7295 if (insn & (1 << 20)) {
7296 /* rfe */
7297 addr = load_reg(s, rn);
7298 if ((insn & (1 << 24)) == 0)
7299 tcg_gen_addi_i32(addr, addr, -8);
7300 /* Load PC into tmp and CPSR into tmp2. */
7301 tmp = gen_ld32(addr, 0);
7302 tcg_gen_addi_i32(addr, addr, 4);
7303 tmp2 = gen_ld32(addr, 0);
7304 if (insn & (1 << 21)) {
7305 /* Base writeback. */
7306 if (insn & (1 << 24)) {
7307 tcg_gen_addi_i32(addr, addr, 4);
7308 } else {
7309 tcg_gen_addi_i32(addr, addr, -4);
7310 }
7311 store_reg(s, rn, addr);
7312 } else {
7313 dead_tmp(addr);
7314 }
7315 gen_rfe(s, tmp, tmp2);
7316 } else {
7317 /* srs */
7318 op = (insn & 0x1f);
7319 if (op == (env->uncached_cpsr & CPSR_M)) {
7320 addr = load_reg(s, 13);
7321 } else {
7322 addr = new_tmp();
7323 tmp = tcg_const_i32(op);
7324 gen_helper_get_r13_banked(addr, cpu_env, tmp);
7325 tcg_temp_free_i32(tmp);
7326 }
7327 if ((insn & (1 << 24)) == 0) {
7328 tcg_gen_addi_i32(addr, addr, -8);
7329 }
7330 tmp = load_reg(s, 14);
7331 gen_st32(tmp, addr, 0);
7332 tcg_gen_addi_i32(addr, addr, 4);
7333 tmp = new_tmp();
7334 gen_helper_cpsr_read(tmp);
7335 gen_st32(tmp, addr, 0);
7336 if (insn & (1 << 21)) {
7337 if ((insn & (1 << 24)) == 0) {
7338 tcg_gen_addi_i32(addr, addr, -4);
7339 } else {
7340 tcg_gen_addi_i32(addr, addr, 4);
7341 }
7342 if (op == (env->uncached_cpsr & CPSR_M)) {
7343 store_reg(s, 13, addr);
7344 } else {
7345 tmp = tcg_const_i32(op);
7346 gen_helper_set_r13_banked(cpu_env, tmp, addr);
7347 tcg_temp_free_i32(tmp);
7348 }
7349 } else {
7350 dead_tmp(addr);
7351 }
7352 }
7353 } else {
7354 int i;
7355 /* Load/store multiple. */
7356 addr = load_reg(s, rn);
7357 offset = 0;
7358 for (i = 0; i < 16; i++) {
7359 if (insn & (1 << i))
7360 offset += 4;
7361 }
7362 if (insn & (1 << 24)) {
7363 tcg_gen_addi_i32(addr, addr, -offset);
7364 }
7365
7366 for (i = 0; i < 16; i++) {
7367 if ((insn & (1 << i)) == 0)
7368 continue;
7369 if (insn & (1 << 20)) {
7370 /* Load. */
7371 tmp = gen_ld32(addr, IS_USER(s));
7372 if (i == 15) {
7373 gen_bx(s, tmp);
7374 } else {
7375 store_reg(s, i, tmp);
7376 }
7377 } else {
7378 /* Store. */
7379 tmp = load_reg(s, i);
7380 gen_st32(tmp, addr, IS_USER(s));
7381 }
7382 tcg_gen_addi_i32(addr, addr, 4);
7383 }
7384 if (insn & (1 << 21)) {
7385 /* Base register writeback. */
7386 if (insn & (1 << 24)) {
7387 tcg_gen_addi_i32(addr, addr, -offset);
7388 }
7389 /* Fault if writeback register is in register list. */
7390 if (insn & (1 << rn))
7391 goto illegal_op;
7392 store_reg(s, rn, addr);
7393 } else {
7394 dead_tmp(addr);
7395 }
7396 }
7397 }
7398 break;
7399 case 5: /* Data processing register constant shift. */
7400 if (rn == 15) {
7401 tmp = new_tmp();
7402 tcg_gen_movi_i32(tmp, 0);
7403 } else {
7404 tmp = load_reg(s, rn);
7405 }
7406 tmp2 = load_reg(s, rm);
7407 op = (insn >> 21) & 0xf;
7408 shiftop = (insn >> 4) & 3;
7409 shift = ((insn >> 6) & 3) | ((insn >> 10) & 0x1c);
7410 conds = (insn & (1 << 20)) != 0;
7411 logic_cc = (conds && thumb2_logic_op(op));
7412 gen_arm_shift_im(tmp2, shiftop, shift, logic_cc);
7413 if (gen_thumb2_data_op(s, op, conds, 0, tmp, tmp2))
7414 goto illegal_op;
7415 dead_tmp(tmp2);
7416 if (rd != 15) {
7417 store_reg(s, rd, tmp);
7418 } else {
7419 dead_tmp(tmp);
7420 }
7421 break;
7422 case 13: /* Misc data processing. */
7423 op = ((insn >> 22) & 6) | ((insn >> 7) & 1);
7424 if (op < 4 && (insn & 0xf000) != 0xf000)
7425 goto illegal_op;
7426 switch (op) {
7427 case 0: /* Register controlled shift. */
7428 tmp = load_reg(s, rn);
7429 tmp2 = load_reg(s, rm);
7430 if ((insn & 0x70) != 0)
7431 goto illegal_op;
7432 op = (insn >> 21) & 3;
7433 logic_cc = (insn & (1 << 20)) != 0;
7434 gen_arm_shift_reg(tmp, op, tmp2, logic_cc);
7435 if (logic_cc)
7436 gen_logic_CC(tmp);
7437 store_reg_bx(env, s, rd, tmp);
7438 break;
7439 case 1: /* Sign/zero extend. */
7440 tmp = load_reg(s, rm);
7441 shift = (insn >> 4) & 3;
7442 /* ??? In many cases it's not neccessary to do a
7443 rotate, a shift is sufficient. */
7444 if (shift != 0)
7445 tcg_gen_rori_i32(tmp, tmp, shift * 8);
7446 op = (insn >> 20) & 7;
7447 switch (op) {
7448 case 0: gen_sxth(tmp); break;
7449 case 1: gen_uxth(tmp); break;
7450 case 2: gen_sxtb16(tmp); break;
7451 case 3: gen_uxtb16(tmp); break;
7452 case 4: gen_sxtb(tmp); break;
7453 case 5: gen_uxtb(tmp); break;
7454 default: goto illegal_op;
7455 }
7456 if (rn != 15) {
7457 tmp2 = load_reg(s, rn);
7458 if ((op >> 1) == 1) {
7459 gen_add16(tmp, tmp2);
7460 } else {
7461 tcg_gen_add_i32(tmp, tmp, tmp2);
7462 dead_tmp(tmp2);
7463 }
7464 }
7465 store_reg(s, rd, tmp);
7466 break;
7467 case 2: /* SIMD add/subtract. */
7468 op = (insn >> 20) & 7;
7469 shift = (insn >> 4) & 7;
7470 if ((op & 3) == 3 || (shift & 3) == 3)
7471 goto illegal_op;
7472 tmp = load_reg(s, rn);
7473 tmp2 = load_reg(s, rm);
7474 gen_thumb2_parallel_addsub(op, shift, tmp, tmp2);
7475 dead_tmp(tmp2);
7476 store_reg(s, rd, tmp);
7477 break;
7478 case 3: /* Other data processing. */
7479 op = ((insn >> 17) & 0x38) | ((insn >> 4) & 7);
7480 if (op < 4) {
7481 /* Saturating add/subtract. */
7482 tmp = load_reg(s, rn);
7483 tmp2 = load_reg(s, rm);
7484 if (op & 2)
7485 gen_helper_double_saturate(tmp, tmp);
7486 if (op & 1)
7487 gen_helper_sub_saturate(tmp, tmp2, tmp);
7488 else
7489 gen_helper_add_saturate(tmp, tmp, tmp2);
7490 dead_tmp(tmp2);
7491 } else {
7492 tmp = load_reg(s, rn);
7493 switch (op) {
7494 case 0x0a: /* rbit */
7495 gen_helper_rbit(tmp, tmp);
7496 break;
7497 case 0x08: /* rev */
7498 tcg_gen_bswap32_i32(tmp, tmp);
7499 break;
7500 case 0x09: /* rev16 */
7501 gen_rev16(tmp);
7502 break;
7503 case 0x0b: /* revsh */
7504 gen_revsh(tmp);
7505 break;
7506 case 0x10: /* sel */
7507 tmp2 = load_reg(s, rm);
7508 tmp3 = new_tmp();
7509 tcg_gen_ld_i32(tmp3, cpu_env, offsetof(CPUState, GE));
7510 gen_helper_sel_flags(tmp, tmp3, tmp, tmp2);
7511 dead_tmp(tmp3);
7512 dead_tmp(tmp2);
7513 break;
7514 case 0x18: /* clz */
7515 gen_helper_clz(tmp, tmp);
7516 break;
7517 default:
7518 goto illegal_op;
7519 }
7520 }
7521 store_reg(s, rd, tmp);
7522 break;
7523 case 4: case 5: /* 32-bit multiply. Sum of absolute differences. */
7524 op = (insn >> 4) & 0xf;
7525 tmp = load_reg(s, rn);
7526 tmp2 = load_reg(s, rm);
7527 switch ((insn >> 20) & 7) {
7528 case 0: /* 32 x 32 -> 32 */
7529 tcg_gen_mul_i32(tmp, tmp, tmp2);
7530 dead_tmp(tmp2);
7531 if (rs != 15) {
7532 tmp2 = load_reg(s, rs);
7533 if (op)
7534 tcg_gen_sub_i32(tmp, tmp2, tmp);
7535 else
7536 tcg_gen_add_i32(tmp, tmp, tmp2);
7537 dead_tmp(tmp2);
7538 }
7539 break;
7540 case 1: /* 16 x 16 -> 32 */
7541 gen_mulxy(tmp, tmp2, op & 2, op & 1);
7542 dead_tmp(tmp2);
7543 if (rs != 15) {
7544 tmp2 = load_reg(s, rs);
7545 gen_helper_add_setq(tmp, tmp, tmp2);
7546 dead_tmp(tmp2);
7547 }
7548 break;
7549 case 2: /* Dual multiply add. */
7550 case 4: /* Dual multiply subtract. */
7551 if (op)
7552 gen_swap_half(tmp2);
7553 gen_smul_dual(tmp, tmp2);
7554 /* This addition cannot overflow. */
7555 if (insn & (1 << 22)) {
7556 tcg_gen_sub_i32(tmp, tmp, tmp2);
7557 } else {
7558 tcg_gen_add_i32(tmp, tmp, tmp2);
7559 }
7560 dead_tmp(tmp2);
7561 if (rs != 15)
7562 {
7563 tmp2 = load_reg(s, rs);
7564 gen_helper_add_setq(tmp, tmp, tmp2);
7565 dead_tmp(tmp2);
7566 }
7567 break;
7568 case 3: /* 32 * 16 -> 32msb */
7569 if (op)
7570 tcg_gen_sari_i32(tmp2, tmp2, 16);
7571 else
7572 gen_sxth(tmp2);
7573 tmp64 = gen_muls_i64_i32(tmp, tmp2);
7574 tcg_gen_shri_i64(tmp64, tmp64, 16);
7575 tmp = new_tmp();
7576 tcg_gen_trunc_i64_i32(tmp, tmp64);
7577 tcg_temp_free_i64(tmp64);
7578 if (rs != 15)
7579 {
7580 tmp2 = load_reg(s, rs);
7581 gen_helper_add_setq(tmp, tmp, tmp2);
7582 dead_tmp(tmp2);
7583 }
7584 break;
7585 case 5: case 6: /* 32 * 32 -> 32msb */
7586 gen_imull(tmp, tmp2);
7587 if (insn & (1 << 5)) {
7588 gen_roundqd(tmp, tmp2);
7589 dead_tmp(tmp2);
7590 } else {
7591 dead_tmp(tmp);
7592 tmp = tmp2;
7593 }
7594 if (rs != 15) {
7595 tmp2 = load_reg(s, rs);
7596 if (insn & (1 << 21)) {
7597 tcg_gen_add_i32(tmp, tmp, tmp2);
7598 } else {
7599 tcg_gen_sub_i32(tmp, tmp2, tmp);
7600 }
7601 dead_tmp(tmp2);
7602 }
7603 break;
7604 case 7: /* Unsigned sum of absolute differences. */
7605 gen_helper_usad8(tmp, tmp, tmp2);
7606 dead_tmp(tmp2);
7607 if (rs != 15) {
7608 tmp2 = load_reg(s, rs);
7609 tcg_gen_add_i32(tmp, tmp, tmp2);
7610 dead_tmp(tmp2);
7611 }
7612 break;
7613 }
7614 store_reg(s, rd, tmp);
7615 break;
7616 case 6: case 7: /* 64-bit multiply, Divide. */
7617 op = ((insn >> 4) & 0xf) | ((insn >> 16) & 0x70);
7618 tmp = load_reg(s, rn);
7619 tmp2 = load_reg(s, rm);
7620 if ((op & 0x50) == 0x10) {
7621 /* sdiv, udiv */
7622 if (!arm_feature(env, ARM_FEATURE_DIV))
7623 goto illegal_op;
7624 if (op & 0x20)
7625 gen_helper_udiv(tmp, tmp, tmp2);
7626 else
7627 gen_helper_sdiv(tmp, tmp, tmp2);
7628 dead_tmp(tmp2);
7629 store_reg(s, rd, tmp);
7630 } else if ((op & 0xe) == 0xc) {
7631 /* Dual multiply accumulate long. */
7632 if (op & 1)
7633 gen_swap_half(tmp2);
7634 gen_smul_dual(tmp, tmp2);
7635 if (op & 0x10) {
7636 tcg_gen_sub_i32(tmp, tmp, tmp2);
7637 } else {
7638 tcg_gen_add_i32(tmp, tmp, tmp2);
7639 }
7640 dead_tmp(tmp2);
7641 /* BUGFIX */
7642 tmp64 = tcg_temp_new_i64();
7643 tcg_gen_ext_i32_i64(tmp64, tmp);
7644 dead_tmp(tmp);
7645 gen_addq(s, tmp64, rs, rd);
7646 gen_storeq_reg(s, rs, rd, tmp64);
7647 tcg_temp_free_i64(tmp64);
7648 } else {
7649 if (op & 0x20) {
7650 /* Unsigned 64-bit multiply */
7651 tmp64 = gen_mulu_i64_i32(tmp, tmp2);
7652 } else {
7653 if (op & 8) {
7654 /* smlalxy */
7655 gen_mulxy(tmp, tmp2, op & 2, op & 1);
7656 dead_tmp(tmp2);
7657 tmp64 = tcg_temp_new_i64();
7658 tcg_gen_ext_i32_i64(tmp64, tmp);
7659 dead_tmp(tmp);
7660 } else {
7661 /* Signed 64-bit multiply */
7662 tmp64 = gen_muls_i64_i32(tmp, tmp2);
7663 }
7664 }
7665 if (op & 4) {
7666 /* umaal */
7667 gen_addq_lo(s, tmp64, rs);
7668 gen_addq_lo(s, tmp64, rd);
7669 } else if (op & 0x40) {
7670 /* 64-bit accumulate. */
7671 gen_addq(s, tmp64, rs, rd);
7672 }
7673 gen_storeq_reg(s, rs, rd, tmp64);
7674 tcg_temp_free_i64(tmp64);
7675 }
7676 break;
7677 }
7678 break;
7679 case 6: case 7: case 14: case 15:
7680 /* Coprocessor. */
7681 if (((insn >> 24) & 3) == 3) {
7682 /* Translate into the equivalent ARM encoding. */
7683 insn = (insn & 0xe2ffffff) | ((insn & (1 << 28)) >> 4);
7684 if (disas_neon_data_insn(env, s, insn))
7685 goto illegal_op;
7686 } else {
7687 if (insn & (1 << 28))
7688 goto illegal_op;
7689 if (disas_coproc_insn (env, s, insn))
7690 goto illegal_op;
7691 }
7692 break;
7693 case 8: case 9: case 10: case 11:
7694 if (insn & (1 << 15)) {
7695 /* Branches, misc control. */
7696 if (insn & 0x5000) {
7697 /* Unconditional branch. */
7698 /* signextend(hw1[10:0]) -> offset[:12]. */
7699 offset = ((int32_t)insn << 5) >> 9 & ~(int32_t)0xfff;
7700 /* hw1[10:0] -> offset[11:1]. */
7701 offset |= (insn & 0x7ff) << 1;
7702 /* (~hw2[13, 11] ^ offset[24]) -> offset[23,22]
7703 offset[24:22] already have the same value because of the
7704 sign extension above. */
7705 offset ^= ((~insn) & (1 << 13)) << 10;
7706 offset ^= ((~insn) & (1 << 11)) << 11;
7707
7708 if (insn & (1 << 14)) {
7709 /* Branch and link. */
7710 tcg_gen_movi_i32(cpu_R[14], s->pc | 1);
7711 }
7712
7713 offset += s->pc;
7714 if (insn & (1 << 12)) {
7715 /* b/bl */
7716 gen_jmp(s, offset);
7717 } else {
7718 /* blx */
7719 offset &= ~(uint32_t)2;
7720 gen_bx_im(s, offset);
7721 }
7722 } else if (((insn >> 23) & 7) == 7) {
7723 /* Misc control */
7724 if (insn & (1 << 13))
7725 goto illegal_op;
7726
7727 if (insn & (1 << 26)) {
7728 /* Secure monitor call (v6Z) */
7729 goto illegal_op; /* not implemented. */
7730 } else {
7731 op = (insn >> 20) & 7;
7732 switch (op) {
7733 case 0: /* msr cpsr. */
7734 if (IS_M(env)) {
7735 tmp = load_reg(s, rn);
7736 addr = tcg_const_i32(insn & 0xff);
7737 gen_helper_v7m_msr(cpu_env, addr, tmp);
7738 tcg_temp_free_i32(addr);
7739 dead_tmp(tmp);
7740 gen_lookup_tb(s);
7741 break;
7742 }
7743 /* fall through */
7744 case 1: /* msr spsr. */
7745 if (IS_M(env))
7746 goto illegal_op;
7747 tmp = load_reg(s, rn);
7748 if (gen_set_psr(s,
7749 msr_mask(env, s, (insn >> 8) & 0xf, op == 1),
7750 op == 1, tmp))
7751 goto illegal_op;
7752 break;
7753 case 2: /* cps, nop-hint. */
7754 if (((insn >> 8) & 7) == 0) {
7755 gen_nop_hint(s, insn & 0xff);
7756 }
7757 /* Implemented as NOP in user mode. */
7758 if (IS_USER(s))
7759 break;
7760 offset = 0;
7761 imm = 0;
7762 if (insn & (1 << 10)) {
7763 if (insn & (1 << 7))
7764 offset |= CPSR_A;
7765 if (insn & (1 << 6))
7766 offset |= CPSR_I;
7767 if (insn & (1 << 5))
7768 offset |= CPSR_F;
7769 if (insn & (1 << 9))
7770 imm = CPSR_A | CPSR_I | CPSR_F;
7771 }
7772 if (insn & (1 << 8)) {
7773 offset |= 0x1f;
7774 imm |= (insn & 0x1f);
7775 }
7776 if (offset) {
7777 gen_set_psr_im(s, offset, 0, imm);
7778 }
7779 break;
7780 case 3: /* Special control operations. */
7781 op = (insn >> 4) & 0xf;
7782 switch (op) {
7783 case 2: /* clrex */
7784 gen_helper_clrex(cpu_env);
7785 break;
7786 case 4: /* dsb */
7787 case 5: /* dmb */
7788 case 6: /* isb */
7789 /* These execute as NOPs. */
7790 ARCH(7);
7791 break;
7792 default:
7793 goto illegal_op;
7794 }
7795 break;
7796 case 4: /* bxj */
7797 /* Trivial implementation equivalent to bx. */
7798 tmp = load_reg(s, rn);
7799 gen_bx(s, tmp);
7800 break;
7801 case 5: /* Exception return. */
7802 /* Unpredictable in user mode. */
7803 goto illegal_op;
7804 case 6: /* mrs cpsr. */
7805 tmp = new_tmp();
7806 if (IS_M(env)) {
7807 addr = tcg_const_i32(insn & 0xff);
7808 gen_helper_v7m_mrs(tmp, cpu_env, addr);
7809 tcg_temp_free_i32(addr);
7810 } else {
7811 gen_helper_cpsr_read(tmp);
7812 }
7813 store_reg(s, rd, tmp);
7814 break;
7815 case 7: /* mrs spsr. */
7816 /* Not accessible in user mode. */
7817 if (IS_USER(s) || IS_M(env))
7818 goto illegal_op;
7819 tmp = load_cpu_field(spsr);
7820 store_reg(s, rd, tmp);
7821 break;
7822 }
7823 }
7824 } else {
7825 /* Conditional branch. */
7826 op = (insn >> 22) & 0xf;
7827 /* Generate a conditional jump to next instruction. */
7828 s->condlabel = gen_new_label();
7829 gen_test_cc(op ^ 1, s->condlabel);
7830 s->condjmp = 1;
7831
7832 /* offset[11:1] = insn[10:0] */
7833 offset = (insn & 0x7ff) << 1;
7834 /* offset[17:12] = insn[21:16]. */
7835 offset |= (insn & 0x003f0000) >> 4;
7836 /* offset[31:20] = insn[26]. */
7837 offset |= ((int32_t)((insn << 5) & 0x80000000)) >> 11;
7838 /* offset[18] = insn[13]. */
7839 offset |= (insn & (1 << 13)) << 5;
7840 /* offset[19] = insn[11]. */
7841 offset |= (insn & (1 << 11)) << 8;
7842
7843 /* jump to the offset */
7844 gen_jmp(s, s->pc + offset);
7845 }
7846 } else {
7847 /* Data processing immediate. */
7848 if (insn & (1 << 25)) {
7849 if (insn & (1 << 24)) {
7850 if (insn & (1 << 20))
7851 goto illegal_op;
7852 /* Bitfield/Saturate. */
7853 op = (insn >> 21) & 7;
7854 imm = insn & 0x1f;
7855 shift = ((insn >> 6) & 3) | ((insn >> 10) & 0x1c);
7856 if (rn == 15) {
7857 tmp = new_tmp();
7858 tcg_gen_movi_i32(tmp, 0);
7859 } else {
7860 tmp = load_reg(s, rn);
7861 }
7862 switch (op) {
7863 case 2: /* Signed bitfield extract. */
7864 imm++;
7865 if (shift + imm > 32)
7866 goto illegal_op;
7867 if (imm < 32)
7868 gen_sbfx(tmp, shift, imm);
7869 break;
7870 case 6: /* Unsigned bitfield extract. */
7871 imm++;
7872 if (shift + imm > 32)
7873 goto illegal_op;
7874 if (imm < 32)
7875 gen_ubfx(tmp, shift, (1u << imm) - 1);
7876 break;
7877 case 3: /* Bitfield insert/clear. */
7878 if (imm < shift)
7879 goto illegal_op;
7880 imm = imm + 1 - shift;
7881 if (imm != 32) {
7882 tmp2 = load_reg(s, rd);
7883 gen_bfi(tmp, tmp2, tmp, shift, (1u << imm) - 1);
7884 dead_tmp(tmp2);
7885 }
7886 break;
7887 case 7:
7888 goto illegal_op;
7889 default: /* Saturate. */
7890 if (shift) {
7891 if (op & 1)
7892 tcg_gen_sari_i32(tmp, tmp, shift);
7893 else
7894 tcg_gen_shli_i32(tmp, tmp, shift);
7895 }
7896 tmp2 = tcg_const_i32(imm);
7897 if (op & 4) {
7898 /* Unsigned. */
7899 if ((op & 1) && shift == 0)
7900 gen_helper_usat16(tmp, tmp, tmp2);
7901 else
7902 gen_helper_usat(tmp, tmp, tmp2);
7903 } else {
7904 /* Signed. */
7905 if ((op & 1) && shift == 0)
7906 gen_helper_ssat16(tmp, tmp, tmp2);
7907 else
7908 gen_helper_ssat(tmp, tmp, tmp2);
7909 }
7910 tcg_temp_free_i32(tmp2);
7911 break;
7912 }
7913 store_reg(s, rd, tmp);
7914 } else {
7915 imm = ((insn & 0x04000000) >> 15)
7916 | ((insn & 0x7000) >> 4) | (insn & 0xff);
7917 if (insn & (1 << 22)) {
7918 /* 16-bit immediate. */
7919 imm |= (insn >> 4) & 0xf000;
7920 if (insn & (1 << 23)) {
7921 /* movt */
7922 tmp = load_reg(s, rd);
7923 tcg_gen_ext16u_i32(tmp, tmp);
7924 tcg_gen_ori_i32(tmp, tmp, imm << 16);
7925 } else {
7926 /* movw */
7927 tmp = new_tmp();
7928 tcg_gen_movi_i32(tmp, imm);
7929 }
7930 } else {
7931 /* Add/sub 12-bit immediate. */
7932 if (rn == 15) {
7933 offset = s->pc & ~(uint32_t)3;
7934 if (insn & (1 << 23))
7935 offset -= imm;
7936 else
7937 offset += imm;
7938 tmp = new_tmp();
7939 tcg_gen_movi_i32(tmp, offset);
7940 } else {
7941 tmp = load_reg(s, rn);
7942 if (insn & (1 << 23))
7943 tcg_gen_subi_i32(tmp, tmp, imm);
7944 else
7945 tcg_gen_addi_i32(tmp, tmp, imm);
7946 }
7947 }
7948 store_reg(s, rd, tmp);
7949 }
7950 } else {
7951 int shifter_out = 0;
7952 /* modified 12-bit immediate. */
7953 shift = ((insn & 0x04000000) >> 23) | ((insn & 0x7000) >> 12);
7954 imm = (insn & 0xff);
7955 switch (shift) {
7956 case 0: /* XY */
7957 /* Nothing to do. */
7958 break;
7959 case 1: /* 00XY00XY */
7960 imm |= imm << 16;
7961 break;
7962 case 2: /* XY00XY00 */
7963 imm |= imm << 16;
7964 imm <<= 8;
7965 break;
7966 case 3: /* XYXYXYXY */
7967 imm |= imm << 16;
7968 imm |= imm << 8;
7969 break;
7970 default: /* Rotated constant. */
7971 shift = (shift << 1) | (imm >> 7);
7972 imm |= 0x80;
7973 imm = imm << (32 - shift);
7974 shifter_out = 1;
7975 break;
7976 }
7977 tmp2 = new_tmp();
7978 tcg_gen_movi_i32(tmp2, imm);
7979 rn = (insn >> 16) & 0xf;
7980 if (rn == 15) {
7981 tmp = new_tmp();
7982 tcg_gen_movi_i32(tmp, 0);
7983 } else {
7984 tmp = load_reg(s, rn);
7985 }
7986 op = (insn >> 21) & 0xf;
7987 if (gen_thumb2_data_op(s, op, (insn & (1 << 20)) != 0,
7988 shifter_out, tmp, tmp2))
7989 goto illegal_op;
7990 dead_tmp(tmp2);
7991 rd = (insn >> 8) & 0xf;
7992 if (rd != 15) {
7993 store_reg(s, rd, tmp);
7994 } else {
7995 dead_tmp(tmp);
7996 }
7997 }
7998 }
7999 break;
8000 case 12: /* Load/store single data item. */
8001 {
8002 int postinc = 0;
8003 int writeback = 0;
8004 int user;
8005 if ((insn & 0x01100000) == 0x01000000) {
8006 if (disas_neon_ls_insn(env, s, insn))
8007 goto illegal_op;
8008 break;
8009 }
8010 user = IS_USER(s);
8011 if (rn == 15) {
8012 addr = new_tmp();
8013 /* PC relative. */
8014 /* s->pc has already been incremented by 4. */
8015 imm = s->pc & 0xfffffffc;
8016 if (insn & (1 << 23))
8017 imm += insn & 0xfff;
8018 else
8019 imm -= insn & 0xfff;
8020 tcg_gen_movi_i32(addr, imm);
8021 } else {
8022 addr = load_reg(s, rn);
8023 if (insn & (1 << 23)) {
8024 /* Positive offset. */
8025 imm = insn & 0xfff;
8026 tcg_gen_addi_i32(addr, addr, imm);
8027 } else {
8028 op = (insn >> 8) & 7;
8029 imm = insn & 0xff;
8030 switch (op) {
8031 case 0: case 8: /* Shifted Register. */
8032 shift = (insn >> 4) & 0xf;
8033 if (shift > 3)
8034 goto illegal_op;
8035 tmp = load_reg(s, rm);
8036 if (shift)
8037 tcg_gen_shli_i32(tmp, tmp, shift);
8038 tcg_gen_add_i32(addr, addr, tmp);
8039 dead_tmp(tmp);
8040 break;
8041 case 4: /* Negative offset. */
8042 tcg_gen_addi_i32(addr, addr, -imm);
8043 break;
8044 case 6: /* User privilege. */
8045 tcg_gen_addi_i32(addr, addr, imm);
8046 user = 1;
8047 break;
8048 case 1: /* Post-decrement. */
8049 imm = -imm;
8050 /* Fall through. */
8051 case 3: /* Post-increment. */
8052 postinc = 1;
8053 writeback = 1;
8054 break;
8055 case 5: /* Pre-decrement. */
8056 imm = -imm;
8057 /* Fall through. */
8058 case 7: /* Pre-increment. */
8059 tcg_gen_addi_i32(addr, addr, imm);
8060 writeback = 1;
8061 break;
8062 default:
8063 goto illegal_op;
8064 }
8065 }
8066 }
8067 op = ((insn >> 21) & 3) | ((insn >> 22) & 4);
8068 if (insn & (1 << 20)) {
8069 /* Load. */
8070 if (rs == 15 && op != 2) {
8071 if (op & 2)
8072 goto illegal_op;
8073 /* Memory hint. Implemented as NOP. */
8074 } else {
8075 switch (op) {
8076 case 0: tmp = gen_ld8u(addr, user); break;
8077 case 4: tmp = gen_ld8s(addr, user); break;
8078 case 1: tmp = gen_ld16u(addr, user); break;
8079 case 5: tmp = gen_ld16s(addr, user); break;
8080 case 2: tmp = gen_ld32(addr, user); break;
8081 default: goto illegal_op;
8082 }
8083 if (rs == 15) {
8084 gen_bx(s, tmp);
8085 } else {
8086 store_reg(s, rs, tmp);
8087 }
8088 }
8089 } else {
8090 /* Store. */
8091 if (rs == 15)
8092 goto illegal_op;
8093 tmp = load_reg(s, rs);
8094 switch (op) {
8095 case 0: gen_st8(tmp, addr, user); break;
8096 case 1: gen_st16(tmp, addr, user); break;
8097 case 2: gen_st32(tmp, addr, user); break;
8098 default: goto illegal_op;
8099 }
8100 }
8101 if (postinc)
8102 tcg_gen_addi_i32(addr, addr, imm);
8103 if (writeback) {
8104 store_reg(s, rn, addr);
8105 } else {
8106 dead_tmp(addr);
8107 }
8108 }
8109 break;
8110 default:
8111 goto illegal_op;
8112 }
8113 return 0;
8114 illegal_op:
8115 return 1;
8116 }
8117
8118 static void disas_thumb_insn(CPUState *env, DisasContext *s)
8119 {
8120 uint32_t val, insn, op, rm, rn, rd, shift, cond;
8121 int32_t offset;
8122 int i;
8123 TCGv tmp;
8124 TCGv tmp2;
8125 TCGv addr;
8126
8127 if (s->condexec_mask) {
8128 cond = s->condexec_cond;
8129 s->condlabel = gen_new_label();
8130 gen_test_cc(cond ^ 1, s->condlabel);
8131 s->condjmp = 1;
8132 }
8133
8134 insn = lduw_code(s->pc);
8135 s->pc += 2;
8136
8137 switch (insn >> 12) {
8138 case 0: case 1:
8139
8140 rd = insn & 7;
8141 op = (insn >> 11) & 3;
8142 if (op == 3) {
8143 /* add/subtract */
8144 rn = (insn >> 3) & 7;
8145 tmp = load_reg(s, rn);
8146 if (insn & (1 << 10)) {
8147 /* immediate */
8148 tmp2 = new_tmp();
8149 tcg_gen_movi_i32(tmp2, (insn >> 6) & 7);
8150 } else {
8151 /* reg */
8152 rm = (insn >> 6) & 7;
8153 tmp2 = load_reg(s, rm);
8154 }
8155 if (insn & (1 << 9)) {
8156 if (s->condexec_mask)
8157 tcg_gen_sub_i32(tmp, tmp, tmp2);
8158 else
8159 gen_helper_sub_cc(tmp, tmp, tmp2);
8160 } else {
8161 if (s->condexec_mask)
8162 tcg_gen_add_i32(tmp, tmp, tmp2);
8163 else
8164 gen_helper_add_cc(tmp, tmp, tmp2);
8165 }
8166 dead_tmp(tmp2);
8167 store_reg(s, rd, tmp);
8168 } else {
8169 /* shift immediate */
8170 rm = (insn >> 3) & 7;
8171 shift = (insn >> 6) & 0x1f;
8172 tmp = load_reg(s, rm);
8173 gen_arm_shift_im(tmp, op, shift, s->condexec_mask == 0);
8174 if (!s->condexec_mask)
8175 gen_logic_CC(tmp);
8176 store_reg(s, rd, tmp);
8177 }
8178 break;
8179 case 2: case 3:
8180 /* arithmetic large immediate */
8181 op = (insn >> 11) & 3;
8182 rd = (insn >> 8) & 0x7;
8183 if (op == 0) { /* mov */
8184 tmp = new_tmp();
8185 tcg_gen_movi_i32(tmp, insn & 0xff);
8186 if (!s->condexec_mask)
8187 gen_logic_CC(tmp);
8188 store_reg(s, rd, tmp);
8189 } else {
8190 tmp = load_reg(s, rd);
8191 tmp2 = new_tmp();
8192 tcg_gen_movi_i32(tmp2, insn & 0xff);
8193 switch (op) {
8194 case 1: /* cmp */
8195 gen_helper_sub_cc(tmp, tmp, tmp2);
8196 dead_tmp(tmp);
8197 dead_tmp(tmp2);
8198 break;
8199 case 2: /* add */
8200 if (s->condexec_mask)
8201 tcg_gen_add_i32(tmp, tmp, tmp2);
8202 else
8203 gen_helper_add_cc(tmp, tmp, tmp2);
8204 dead_tmp(tmp2);
8205 store_reg(s, rd, tmp);
8206 break;
8207 case 3: /* sub */
8208 if (s->condexec_mask)
8209 tcg_gen_sub_i32(tmp, tmp, tmp2);
8210 else
8211 gen_helper_sub_cc(tmp, tmp, tmp2);
8212 dead_tmp(tmp2);
8213 store_reg(s, rd, tmp);
8214 break;
8215 }
8216 }
8217 break;
8218 case 4:
8219 if (insn & (1 << 11)) {
8220 rd = (insn >> 8) & 7;
8221 /* load pc-relative. Bit 1 of PC is ignored. */
8222 val = s->pc + 2 + ((insn & 0xff) * 4);
8223 val &= ~(uint32_t)2;
8224 addr = new_tmp();
8225 tcg_gen_movi_i32(addr, val);
8226 tmp = gen_ld32(addr, IS_USER(s));
8227 dead_tmp(addr);
8228 store_reg(s, rd, tmp);
8229 break;
8230 }
8231 if (insn & (1 << 10)) {
8232 /* data processing extended or blx */
8233 rd = (insn & 7) | ((insn >> 4) & 8);
8234 rm = (insn >> 3) & 0xf;
8235 op = (insn >> 8) & 3;
8236 switch (op) {
8237 case 0: /* add */
8238 tmp = load_reg(s, rd);
8239 tmp2 = load_reg(s, rm);
8240 tcg_gen_add_i32(tmp, tmp, tmp2);
8241 dead_tmp(tmp2);
8242 store_reg(s, rd, tmp);
8243 break;
8244 case 1: /* cmp */
8245 tmp = load_reg(s, rd);
8246 tmp2 = load_reg(s, rm);
8247 gen_helper_sub_cc(tmp, tmp, tmp2);
8248 dead_tmp(tmp2);
8249 dead_tmp(tmp);
8250 break;
8251 case 2: /* mov/cpy */
8252 tmp = load_reg(s, rm);
8253 store_reg(s, rd, tmp);
8254 break;
8255 case 3:/* branch [and link] exchange thumb register */
8256 tmp = load_reg(s, rm);
8257 if (insn & (1 << 7)) {
8258 val = (uint32_t)s->pc | 1;
8259 tmp2 = new_tmp();
8260 tcg_gen_movi_i32(tmp2, val);
8261 store_reg(s, 14, tmp2);
8262 }
8263 gen_bx(s, tmp);
8264 break;
8265 }
8266 break;
8267 }
8268
8269 /* data processing register */
8270 rd = insn & 7;
8271 rm = (insn >> 3) & 7;
8272 op = (insn >> 6) & 0xf;
8273 if (op == 2 || op == 3 || op == 4 || op == 7) {
8274 /* the shift/rotate ops want the operands backwards */
8275 val = rm;
8276 rm = rd;
8277 rd = val;
8278 val = 1;
8279 } else {
8280 val = 0;
8281 }
8282
8283 if (op == 9) { /* neg */
8284 tmp = new_tmp();
8285 tcg_gen_movi_i32(tmp, 0);
8286 } else if (op != 0xf) { /* mvn doesn't read its first operand */
8287 tmp = load_reg(s, rd);
8288 } else {
8289 TCGV_UNUSED(tmp);
8290 }
8291
8292 tmp2 = load_reg(s, rm);
8293 switch (op) {
8294 case 0x0: /* and */
8295 tcg_gen_and_i32(tmp, tmp, tmp2);
8296 if (!s->condexec_mask)
8297 gen_logic_CC(tmp);
8298 break;
8299 case 0x1: /* eor */
8300 tcg_gen_xor_i32(tmp, tmp, tmp2);
8301 if (!s->condexec_mask)
8302 gen_logic_CC(tmp);
8303 break;
8304 case 0x2: /* lsl */
8305 if (s->condexec_mask) {
8306 gen_helper_shl(tmp2, tmp2, tmp);
8307 } else {
8308 gen_helper_shl_cc(tmp2, tmp2, tmp);
8309 gen_logic_CC(tmp2);
8310 }
8311 break;
8312 case 0x3: /* lsr */
8313 if (s->condexec_mask) {
8314 gen_helper_shr(tmp2, tmp2, tmp);
8315 } else {
8316 gen_helper_shr_cc(tmp2, tmp2, tmp);
8317 gen_logic_CC(tmp2);
8318 }
8319 break;
8320 case 0x4: /* asr */
8321 if (s->condexec_mask) {
8322 gen_helper_sar(tmp2, tmp2, tmp);
8323 } else {
8324 gen_helper_sar_cc(tmp2, tmp2, tmp);
8325 gen_logic_CC(tmp2);
8326 }
8327 break;
8328 case 0x5: /* adc */
8329 if (s->condexec_mask)
8330 gen_adc(tmp, tmp2);
8331 else
8332 gen_helper_adc_cc(tmp, tmp, tmp2);
8333 break;
8334 case 0x6: /* sbc */
8335 if (s->condexec_mask)
8336 gen_sub_carry(tmp, tmp, tmp2);
8337 else
8338 gen_helper_sbc_cc(tmp, tmp, tmp2);
8339 break;
8340 case 0x7: /* ror */
8341 if (s->condexec_mask) {
8342 gen_helper_ror(tmp2, tmp2, tmp);
8343 } else {
8344 gen_helper_ror_cc(tmp2, tmp2, tmp);
8345 gen_logic_CC(tmp2);
8346 }
8347 break;
8348 case 0x8: /* tst */
8349 tcg_gen_and_i32(tmp, tmp, tmp2);
8350 gen_logic_CC(tmp);
8351 rd = 16;
8352 break;
8353 case 0x9: /* neg */
8354 if (s->condexec_mask)
8355 tcg_gen_neg_i32(tmp, tmp2);
8356 else
8357 gen_helper_sub_cc(tmp, tmp, tmp2);
8358 break;
8359 case 0xa: /* cmp */
8360 gen_helper_sub_cc(tmp, tmp, tmp2);
8361 rd = 16;
8362 break;
8363 case 0xb: /* cmn */
8364 gen_helper_add_cc(tmp, tmp, tmp2);
8365 rd = 16;
8366 break;
8367 case 0xc: /* orr */
8368 tcg_gen_or_i32(tmp, tmp, tmp2);
8369 if (!s->condexec_mask)
8370 gen_logic_CC(tmp);
8371 break;
8372 case 0xd: /* mul */
8373 tcg_gen_mul_i32(tmp, tmp, tmp2);
8374 if (!s->condexec_mask)
8375 gen_logic_CC(tmp);
8376 break;
8377 case 0xe: /* bic */
8378 tcg_gen_bic_i32(tmp, tmp, tmp2);
8379 if (!s->condexec_mask)
8380 gen_logic_CC(tmp);
8381 break;
8382 case 0xf: /* mvn */
8383 tcg_gen_not_i32(tmp2, tmp2);
8384 if (!s->condexec_mask)
8385 gen_logic_CC(tmp2);
8386 val = 1;
8387 rm = rd;
8388 break;
8389 }
8390 if (rd != 16) {
8391 if (val) {
8392 store_reg(s, rm, tmp2);
8393 if (op != 0xf)
8394 dead_tmp(tmp);
8395 } else {
8396 store_reg(s, rd, tmp);
8397 dead_tmp(tmp2);
8398 }
8399 } else {
8400 dead_tmp(tmp);
8401 dead_tmp(tmp2);
8402 }
8403 break;
8404
8405 case 5:
8406 /* load/store register offset. */
8407 rd = insn & 7;
8408 rn = (insn >> 3) & 7;
8409 rm = (insn >> 6) & 7;
8410 op = (insn >> 9) & 7;
8411 addr = load_reg(s, rn);
8412 tmp = load_reg(s, rm);
8413 tcg_gen_add_i32(addr, addr, tmp);
8414 dead_tmp(tmp);
8415
8416 if (op < 3) /* store */
8417 tmp = load_reg(s, rd);
8418
8419 switch (op) {
8420 case 0: /* str */
8421 gen_st32(tmp, addr, IS_USER(s));
8422 break;
8423 case 1: /* strh */
8424 gen_st16(tmp, addr, IS_USER(s));
8425 break;
8426 case 2: /* strb */
8427 gen_st8(tmp, addr, IS_USER(s));
8428 break;
8429 case 3: /* ldrsb */
8430 tmp = gen_ld8s(addr, IS_USER(s));
8431 break;
8432 case 4: /* ldr */
8433 tmp = gen_ld32(addr, IS_USER(s));
8434 break;
8435 case 5: /* ldrh */
8436 tmp = gen_ld16u(addr, IS_USER(s));
8437 break;
8438 case 6: /* ldrb */
8439 tmp = gen_ld8u(addr, IS_USER(s));
8440 break;
8441 case 7: /* ldrsh */
8442 tmp = gen_ld16s(addr, IS_USER(s));
8443 break;
8444 }
8445 if (op >= 3) /* load */
8446 store_reg(s, rd, tmp);
8447 dead_tmp(addr);
8448 break;
8449
8450 case 6:
8451 /* load/store word immediate offset */
8452 rd = insn & 7;
8453 rn = (insn >> 3) & 7;
8454 addr = load_reg(s, rn);
8455 val = (insn >> 4) & 0x7c;
8456 tcg_gen_addi_i32(addr, addr, val);
8457
8458 if (insn & (1 << 11)) {
8459 /* load */
8460 tmp = gen_ld32(addr, IS_USER(s));
8461 store_reg(s, rd, tmp);
8462 } else {
8463 /* store */
8464 tmp = load_reg(s, rd);
8465 gen_st32(tmp, addr, IS_USER(s));
8466 }
8467 dead_tmp(addr);
8468 break;
8469
8470 case 7:
8471 /* load/store byte immediate offset */
8472 rd = insn & 7;
8473 rn = (insn >> 3) & 7;
8474 addr = load_reg(s, rn);
8475 val = (insn >> 6) & 0x1f;
8476 tcg_gen_addi_i32(addr, addr, val);
8477
8478 if (insn & (1 << 11)) {
8479 /* load */
8480 tmp = gen_ld8u(addr, IS_USER(s));
8481 store_reg(s, rd, tmp);
8482 } else {
8483 /* store */
8484 tmp = load_reg(s, rd);
8485 gen_st8(tmp, addr, IS_USER(s));
8486 }
8487 dead_tmp(addr);
8488 break;
8489
8490 case 8:
8491 /* load/store halfword immediate offset */
8492 rd = insn & 7;
8493 rn = (insn >> 3) & 7;
8494 addr = load_reg(s, rn);
8495 val = (insn >> 5) & 0x3e;
8496 tcg_gen_addi_i32(addr, addr, val);
8497
8498 if (insn & (1 << 11)) {
8499 /* load */
8500 tmp = gen_ld16u(addr, IS_USER(s));
8501 store_reg(s, rd, tmp);
8502 } else {
8503 /* store */
8504 tmp = load_reg(s, rd);
8505 gen_st16(tmp, addr, IS_USER(s));
8506 }
8507 dead_tmp(addr);
8508 break;
8509
8510 case 9:
8511 /* load/store from stack */
8512 rd = (insn >> 8) & 7;
8513 addr = load_reg(s, 13);
8514 val = (insn & 0xff) * 4;
8515 tcg_gen_addi_i32(addr, addr, val);
8516
8517 if (insn & (1 << 11)) {
8518 /* load */
8519 tmp = gen_ld32(addr, IS_USER(s));
8520 store_reg(s, rd, tmp);
8521 } else {
8522 /* store */
8523 tmp = load_reg(s, rd);
8524 gen_st32(tmp, addr, IS_USER(s));
8525 }
8526 dead_tmp(addr);
8527 break;
8528
8529 case 10:
8530 /* add to high reg */
8531 rd = (insn >> 8) & 7;
8532 if (insn & (1 << 11)) {
8533 /* SP */
8534 tmp = load_reg(s, 13);
8535 } else {
8536 /* PC. bit 1 is ignored. */
8537 tmp = new_tmp();
8538 tcg_gen_movi_i32(tmp, (s->pc + 2) & ~(uint32_t)2);
8539 }
8540 val = (insn & 0xff) * 4;
8541 tcg_gen_addi_i32(tmp, tmp, val);
8542 store_reg(s, rd, tmp);
8543 break;
8544
8545 case 11:
8546 /* misc */
8547 op = (insn >> 8) & 0xf;
8548 switch (op) {
8549 case 0:
8550 /* adjust stack pointer */
8551 tmp = load_reg(s, 13);
8552 val = (insn & 0x7f) * 4;
8553 if (insn & (1 << 7))
8554 val = -(int32_t)val;
8555 tcg_gen_addi_i32(tmp, tmp, val);
8556 store_reg(s, 13, tmp);
8557 break;
8558
8559 case 2: /* sign/zero extend. */
8560 ARCH(6);
8561 rd = insn & 7;
8562 rm = (insn >> 3) & 7;
8563 tmp = load_reg(s, rm);
8564 switch ((insn >> 6) & 3) {
8565 case 0: gen_sxth(tmp); break;
8566 case 1: gen_sxtb(tmp); break;
8567 case 2: gen_uxth(tmp); break;
8568 case 3: gen_uxtb(tmp); break;
8569 }
8570 store_reg(s, rd, tmp);
8571 break;
8572 case 4: case 5: case 0xc: case 0xd:
8573 /* push/pop */
8574 addr = load_reg(s, 13);
8575 if (insn & (1 << 8))
8576 offset = 4;
8577 else
8578 offset = 0;
8579 for (i = 0; i < 8; i++) {
8580 if (insn & (1 << i))
8581 offset += 4;
8582 }
8583 if ((insn & (1 << 11)) == 0) {
8584 tcg_gen_addi_i32(addr, addr, -offset);
8585 }
8586 for (i = 0; i < 8; i++) {
8587 if (insn & (1 << i)) {
8588 if (insn & (1 << 11)) {
8589 /* pop */
8590 tmp = gen_ld32(addr, IS_USER(s));
8591 store_reg(s, i, tmp);
8592 } else {
8593 /* push */
8594 tmp = load_reg(s, i);
8595 gen_st32(tmp, addr, IS_USER(s));
8596 }
8597 /* advance to the next address. */
8598 tcg_gen_addi_i32(addr, addr, 4);
8599 }
8600 }
8601 TCGV_UNUSED(tmp);
8602 if (insn & (1 << 8)) {
8603 if (insn & (1 << 11)) {
8604 /* pop pc */
8605 tmp = gen_ld32(addr, IS_USER(s));
8606 /* don't set the pc until the rest of the instruction
8607 has completed */
8608 } else {
8609 /* push lr */
8610 tmp = load_reg(s, 14);
8611 gen_st32(tmp, addr, IS_USER(s));
8612 }
8613 tcg_gen_addi_i32(addr, addr, 4);
8614 }
8615 if ((insn & (1 << 11)) == 0) {
8616 tcg_gen_addi_i32(addr, addr, -offset);
8617 }
8618 /* write back the new stack pointer */
8619 store_reg(s, 13, addr);
8620 /* set the new PC value */
8621 if ((insn & 0x0900) == 0x0900)
8622 gen_bx(s, tmp);
8623 break;
8624
8625 case 1: case 3: case 9: case 11: /* czb */
8626 rm = insn & 7;
8627 tmp = load_reg(s, rm);
8628 s->condlabel = gen_new_label();
8629 s->condjmp = 1;
8630 if (insn & (1 << 11))
8631 tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 0, s->condlabel);
8632 else
8633 tcg_gen_brcondi_i32(TCG_COND_NE, tmp, 0, s->condlabel);
8634 dead_tmp(tmp);
8635 offset = ((insn & 0xf8) >> 2) | (insn & 0x200) >> 3;
8636 val = (uint32_t)s->pc + 2;
8637 val += offset;
8638 gen_jmp(s, val);
8639 break;
8640
8641 case 15: /* IT, nop-hint. */
8642 if ((insn & 0xf) == 0) {
8643 gen_nop_hint(s, (insn >> 4) & 0xf);
8644 break;
8645 }
8646 /* If Then. */
8647 s->condexec_cond = (insn >> 4) & 0xe;
8648 s->condexec_mask = insn & 0x1f;
8649 /* No actual code generated for this insn, just setup state. */
8650 break;
8651
8652 case 0xe: /* bkpt */
8653 gen_set_condexec(s);
8654 gen_set_pc_im(s->pc - 2);
8655 gen_exception(EXCP_BKPT);
8656 s->is_jmp = DISAS_JUMP;
8657 break;
8658
8659 case 0xa: /* rev */
8660 ARCH(6);
8661 rn = (insn >> 3) & 0x7;
8662 rd = insn & 0x7;
8663 tmp = load_reg(s, rn);
8664 switch ((insn >> 6) & 3) {
8665 case 0: tcg_gen_bswap32_i32(tmp, tmp); break;
8666 case 1: gen_rev16(tmp); break;
8667 case 3: gen_revsh(tmp); break;
8668 default: goto illegal_op;
8669 }
8670 store_reg(s, rd, tmp);
8671 break;
8672
8673 case 6: /* cps */
8674 ARCH(6);
8675 if (IS_USER(s))
8676 break;
8677 if (IS_M(env)) {
8678 tmp = tcg_const_i32((insn & (1 << 4)) != 0);
8679 /* PRIMASK */
8680 if (insn & 1) {
8681 addr = tcg_const_i32(16);
8682 gen_helper_v7m_msr(cpu_env, addr, tmp);
8683 tcg_temp_free_i32(addr);
8684 }
8685 /* FAULTMASK */
8686 if (insn & 2) {
8687 addr = tcg_const_i32(17);
8688 gen_helper_v7m_msr(cpu_env, addr, tmp);
8689 tcg_temp_free_i32(addr);
8690 }
8691 tcg_temp_free_i32(tmp);
8692 gen_lookup_tb(s);
8693 } else {
8694 if (insn & (1 << 4))
8695 shift = CPSR_A | CPSR_I | CPSR_F;
8696 else
8697 shift = 0;
8698 gen_set_psr_im(s, shift, 0, ((insn & 7) << 6) & shift);
8699 }
8700 break;
8701
8702 default:
8703 goto undef;
8704 }
8705 break;
8706
8707 case 12:
8708 /* load/store multiple */
8709 rn = (insn >> 8) & 0x7;
8710 addr = load_reg(s, rn);
8711 for (i = 0; i < 8; i++) {
8712 if (insn & (1 << i)) {
8713 if (insn & (1 << 11)) {
8714 /* load */
8715 tmp = gen_ld32(addr, IS_USER(s));
8716 store_reg(s, i, tmp);
8717 } else {
8718 /* store */
8719 tmp = load_reg(s, i);
8720 gen_st32(tmp, addr, IS_USER(s));
8721 }
8722 /* advance to the next address */
8723 tcg_gen_addi_i32(addr, addr, 4);
8724 }
8725 }
8726 /* Base register writeback. */
8727 if ((insn & (1 << rn)) == 0) {
8728 store_reg(s, rn, addr);
8729 } else {
8730 dead_tmp(addr);
8731 }
8732 break;
8733
8734 case 13:
8735 /* conditional branch or swi */
8736 cond = (insn >> 8) & 0xf;
8737 if (cond == 0xe)
8738 goto undef;
8739
8740 if (cond == 0xf) {
8741 /* swi */
8742 gen_set_condexec(s);
8743 gen_set_pc_im(s->pc);
8744 s->is_jmp = DISAS_SWI;
8745 break;
8746 }
8747 /* generate a conditional jump to next instruction */
8748 s->condlabel = gen_new_label();
8749 gen_test_cc(cond ^ 1, s->condlabel);
8750 s->condjmp = 1;
8751
8752 /* jump to the offset */
8753 val = (uint32_t)s->pc + 2;
8754 offset = ((int32_t)insn << 24) >> 24;
8755 val += offset << 1;
8756 gen_jmp(s, val);
8757 break;
8758
8759 case 14:
8760 if (insn & (1 << 11)) {
8761 if (disas_thumb2_insn(env, s, insn))
8762 goto undef32;
8763 break;
8764 }
8765 /* unconditional branch */
8766 val = (uint32_t)s->pc;
8767 offset = ((int32_t)insn << 21) >> 21;
8768 val += (offset << 1) + 2;
8769 gen_jmp(s, val);
8770 break;
8771
8772 case 15:
8773 if (disas_thumb2_insn(env, s, insn))
8774 goto undef32;
8775 break;
8776 }
8777 return;
8778 undef32:
8779 gen_set_condexec(s);
8780 gen_set_pc_im(s->pc - 4);
8781 gen_exception(EXCP_UDEF);
8782 s->is_jmp = DISAS_JUMP;
8783 return;
8784 illegal_op:
8785 undef:
8786 gen_set_condexec(s);
8787 gen_set_pc_im(s->pc - 2);
8788 gen_exception(EXCP_UDEF);
8789 s->is_jmp = DISAS_JUMP;
8790 }
8791
8792 /* generate intermediate code in gen_opc_buf and gen_opparam_buf for
8793 basic block 'tb'. If search_pc is TRUE, also generate PC
8794 information for each intermediate instruction. */
8795 static inline void gen_intermediate_code_internal(CPUState *env,
8796 TranslationBlock *tb,
8797 int search_pc)
8798 {
8799 DisasContext dc1, *dc = &dc1;
8800 CPUBreakpoint *bp;
8801 uint16_t *gen_opc_end;
8802 int j, lj;
8803 target_ulong pc_start;
8804 uint32_t next_page_start;
8805 int num_insns;
8806 int max_insns;
8807
8808 /* generate intermediate code */
8809 num_temps = 0;
8810
8811 pc_start = tb->pc;
8812
8813 dc->tb = tb;
8814
8815 gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
8816
8817 dc->is_jmp = DISAS_NEXT;
8818 dc->pc = pc_start;
8819 dc->singlestep_enabled = env->singlestep_enabled;
8820 dc->condjmp = 0;
8821 dc->thumb = env->thumb;
8822 dc->condexec_mask = (env->condexec_bits & 0xf) << 1;
8823 dc->condexec_cond = env->condexec_bits >> 4;
8824 #if !defined(CONFIG_USER_ONLY)
8825 if (IS_M(env)) {
8826 dc->user = ((env->v7m.exception == 0) && (env->v7m.control & 1));
8827 } else {
8828 dc->user = (env->uncached_cpsr & 0x1f) == ARM_CPU_MODE_USR;
8829 }
8830 #endif
8831 cpu_F0s = tcg_temp_new_i32();
8832 cpu_F1s = tcg_temp_new_i32();
8833 cpu_F0d = tcg_temp_new_i64();
8834 cpu_F1d = tcg_temp_new_i64();
8835 cpu_V0 = cpu_F0d;
8836 cpu_V1 = cpu_F1d;
8837 /* FIXME: cpu_M0 can probably be the same as cpu_V0. */
8838 cpu_M0 = tcg_temp_new_i64();
8839 next_page_start = (pc_start & TARGET_PAGE_MASK) + TARGET_PAGE_SIZE;
8840 lj = -1;
8841 num_insns = 0;
8842 max_insns = tb->cflags & CF_COUNT_MASK;
8843 if (max_insns == 0)
8844 max_insns = CF_COUNT_MASK;
8845
8846 gen_icount_start();
8847 /* Reset the conditional execution bits immediately. This avoids
8848 complications trying to do it at the end of the block. */
8849 if (env->condexec_bits)
8850 {
8851 TCGv tmp = new_tmp();
8852 tcg_gen_movi_i32(tmp, 0);
8853 store_cpu_field(tmp, condexec_bits);
8854 }
8855 do {
8856 #ifdef CONFIG_USER_ONLY
8857 /* Intercept jump to the magic kernel page. */
8858 if (dc->pc >= 0xffff0000) {
8859 /* We always get here via a jump, so know we are not in a
8860 conditional execution block. */
8861 gen_exception(EXCP_KERNEL_TRAP);
8862 dc->is_jmp = DISAS_UPDATE;
8863 break;
8864 }
8865 #else
8866 if (dc->pc >= 0xfffffff0 && IS_M(env)) {
8867 /* We always get here via a jump, so know we are not in a
8868 conditional execution block. */
8869 gen_exception(EXCP_EXCEPTION_EXIT);
8870 dc->is_jmp = DISAS_UPDATE;
8871 break;
8872 }
8873 #endif
8874
8875 if (unlikely(!QTAILQ_EMPTY(&env->breakpoints))) {
8876 QTAILQ_FOREACH(bp, &env->breakpoints, entry) {
8877 if (bp->pc == dc->pc) {
8878 gen_set_condexec(dc);
8879 gen_set_pc_im(dc->pc);
8880 gen_exception(EXCP_DEBUG);
8881 dc->is_jmp = DISAS_JUMP;
8882 /* Advance PC so that clearing the breakpoint will
8883 invalidate this TB. */
8884 dc->pc += 2;
8885 goto done_generating;
8886 break;
8887 }
8888 }
8889 }
8890 if (search_pc) {
8891 j = gen_opc_ptr - gen_opc_buf;
8892 if (lj < j) {
8893 lj++;
8894 while (lj < j)
8895 gen_opc_instr_start[lj++] = 0;
8896 }
8897 gen_opc_pc[lj] = dc->pc;
8898 gen_opc_instr_start[lj] = 1;
8899 gen_opc_icount[lj] = num_insns;
8900 }
8901
8902 if (num_insns + 1 == max_insns && (tb->cflags & CF_LAST_IO))
8903 gen_io_start();
8904
8905 if (env->thumb) {
8906 disas_thumb_insn(env, dc);
8907 if (dc->condexec_mask) {
8908 dc->condexec_cond = (dc->condexec_cond & 0xe)
8909 | ((dc->condexec_mask >> 4) & 1);
8910 dc->condexec_mask = (dc->condexec_mask << 1) & 0x1f;
8911 if (dc->condexec_mask == 0) {
8912 dc->condexec_cond = 0;
8913 }
8914 }
8915 } else {
8916 disas_arm_insn(env, dc);
8917 }
8918 if (num_temps) {
8919 fprintf(stderr, "Internal resource leak before %08x\n", dc->pc);
8920 num_temps = 0;
8921 }
8922
8923 if (dc->condjmp && !dc->is_jmp) {
8924 gen_set_label(dc->condlabel);
8925 dc->condjmp = 0;
8926 }
8927 /* Translation stops when a conditional branch is encountered.
8928 * Otherwise the subsequent code could get translated several times.
8929 * Also stop translation when a page boundary is reached. This
8930 * ensures prefetch aborts occur at the right place. */
8931 num_insns ++;
8932 } while (!dc->is_jmp && gen_opc_ptr < gen_opc_end &&
8933 !env->singlestep_enabled &&
8934 !singlestep &&
8935 dc->pc < next_page_start &&
8936 num_insns < max_insns);
8937
8938 if (tb->cflags & CF_LAST_IO) {
8939 if (dc->condjmp) {
8940 /* FIXME: This can theoretically happen with self-modifying
8941 code. */
8942 cpu_abort(env, "IO on conditional branch instruction");
8943 }
8944 gen_io_end();
8945 }
8946
8947 /* At this stage dc->condjmp will only be set when the skipped
8948 instruction was a conditional branch or trap, and the PC has
8949 already been written. */
8950 if (unlikely(env->singlestep_enabled)) {
8951 /* Make sure the pc is updated, and raise a debug exception. */
8952 if (dc->condjmp) {
8953 gen_set_condexec(dc);
8954 if (dc->is_jmp == DISAS_SWI) {
8955 gen_exception(EXCP_SWI);
8956 } else {
8957 gen_exception(EXCP_DEBUG);
8958 }
8959 gen_set_label(dc->condlabel);
8960 }
8961 if (dc->condjmp || !dc->is_jmp) {
8962 gen_set_pc_im(dc->pc);
8963 dc->condjmp = 0;
8964 }
8965 gen_set_condexec(dc);
8966 if (dc->is_jmp == DISAS_SWI && !dc->condjmp) {
8967 gen_exception(EXCP_SWI);
8968 } else {
8969 /* FIXME: Single stepping a WFI insn will not halt
8970 the CPU. */
8971 gen_exception(EXCP_DEBUG);
8972 }
8973 } else {
8974 /* While branches must always occur at the end of an IT block,
8975 there are a few other things that can cause us to terminate
8976 the TB in the middel of an IT block:
8977 - Exception generating instructions (bkpt, swi, undefined).
8978 - Page boundaries.
8979 - Hardware watchpoints.
8980 Hardware breakpoints have already been handled and skip this code.
8981 */
8982 gen_set_condexec(dc);
8983 switch(dc->is_jmp) {
8984 case DISAS_NEXT:
8985 gen_goto_tb(dc, 1, dc->pc);
8986 break;
8987 default:
8988 case DISAS_JUMP:
8989 case DISAS_UPDATE:
8990 /* indicate that the hash table must be used to find the next TB */
8991 tcg_gen_exit_tb(0);
8992 break;
8993 case DISAS_TB_JUMP:
8994 /* nothing more to generate */
8995 break;
8996 case DISAS_WFI:
8997 gen_helper_wfi();
8998 break;
8999 case DISAS_SWI:
9000 gen_exception(EXCP_SWI);
9001 break;
9002 }
9003 if (dc->condjmp) {
9004 gen_set_label(dc->condlabel);
9005 gen_set_condexec(dc);
9006 gen_goto_tb(dc, 1, dc->pc);
9007 dc->condjmp = 0;
9008 }
9009 }
9010
9011 done_generating:
9012 gen_icount_end(tb, num_insns);
9013 *gen_opc_ptr = INDEX_op_end;
9014
9015 #ifdef DEBUG_DISAS
9016 if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
9017 qemu_log("----------------\n");
9018 qemu_log("IN: %s\n", lookup_symbol(pc_start));
9019 log_target_disas(pc_start, dc->pc - pc_start, env->thumb);
9020 qemu_log("\n");
9021 }
9022 #endif
9023 if (search_pc) {
9024 j = gen_opc_ptr - gen_opc_buf;
9025 lj++;
9026 while (lj <= j)
9027 gen_opc_instr_start[lj++] = 0;
9028 } else {
9029 tb->size = dc->pc - pc_start;
9030 tb->icount = num_insns;
9031 }
9032 }
9033
9034 void gen_intermediate_code(CPUState *env, TranslationBlock *tb)
9035 {
9036 gen_intermediate_code_internal(env, tb, 0);
9037 }
9038
9039 void gen_intermediate_code_pc(CPUState *env, TranslationBlock *tb)
9040 {
9041 gen_intermediate_code_internal(env, tb, 1);
9042 }
9043
9044 static const char *cpu_mode_names[16] = {
9045 "usr", "fiq", "irq", "svc", "???", "???", "???", "abt",
9046 "???", "???", "???", "und", "???", "???", "???", "sys"
9047 };
9048
9049 void cpu_dump_state(CPUState *env, FILE *f,
9050 int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
9051 int flags)
9052 {
9053 int i;
9054 #if 0
9055 union {
9056 uint32_t i;
9057 float s;
9058 } s0, s1;
9059 CPU_DoubleU d;
9060 /* ??? This assumes float64 and double have the same layout.
9061 Oh well, it's only debug dumps. */
9062 union {
9063 float64 f64;
9064 double d;
9065 } d0;
9066 #endif
9067 uint32_t psr;
9068
9069 for(i=0;i<16;i++) {
9070 cpu_fprintf(f, "R%02d=%08x", i, env->regs[i]);
9071 if ((i % 4) == 3)
9072 cpu_fprintf(f, "\n");
9073 else
9074 cpu_fprintf(f, " ");
9075 }
9076 psr = cpsr_read(env);
9077 cpu_fprintf(f, "PSR=%08x %c%c%c%c %c %s%d\n",
9078 psr,
9079 psr & (1 << 31) ? 'N' : '-',
9080 psr & (1 << 30) ? 'Z' : '-',
9081 psr & (1 << 29) ? 'C' : '-',
9082 psr & (1 << 28) ? 'V' : '-',
9083 psr & CPSR_T ? 'T' : 'A',
9084 cpu_mode_names[psr & 0xf], (psr & 0x10) ? 32 : 26);
9085
9086 #if 0
9087 for (i = 0; i < 16; i++) {
9088 d.d = env->vfp.regs[i];
9089 s0.i = d.l.lower;
9090 s1.i = d.l.upper;
9091 d0.f64 = d.d;
9092 cpu_fprintf(f, "s%02d=%08x(%8g) s%02d=%08x(%8g) d%02d=%08x%08x(%8g)\n",
9093 i * 2, (int)s0.i, s0.s,
9094 i * 2 + 1, (int)s1.i, s1.s,
9095 i, (int)(uint32_t)d.l.upper, (int)(uint32_t)d.l.lower,
9096 d0.d);
9097 }
9098 cpu_fprintf(f, "FPSCR: %08x\n", (int)env->vfp.xregs[ARM_VFP_FPSCR]);
9099 #endif
9100 }
9101
9102 void gen_pc_load(CPUState *env, TranslationBlock *tb,
9103 unsigned long searched_pc, int pc_pos, void *puc)
9104 {
9105 env->regs[15] = gen_opc_pc[pc_pos];
9106 }