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