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