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