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