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