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