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