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