4 * Copyright (c) 2003 Fabrice Bellard
5 * Copyright (c) 2005-2007 CodeSourcery
6 * Copyright (c) 2007 OpenedHand, Ltd.
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.
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.
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA
38 #define ENABLE_ARCH_5J 0
39 #define ENABLE_ARCH_6 arm_feature(env, ARM_FEATURE_V6)
40 #define ENABLE_ARCH_6K arm_feature(env, ARM_FEATURE_V6K)
41 #define ENABLE_ARCH_6T2 arm_feature(env, ARM_FEATURE_THUMB2)
42 #define ENABLE_ARCH_7 arm_feature(env, ARM_FEATURE_V7)
44 #define ARCH(x) do { if (!ENABLE_ARCH_##x) goto illegal_op; } while(0)
46 /* internal defines */
47 typedef struct DisasContext {
50 /* Nonzero if this instruction has been conditionally skipped. */
52 /* The label that will be jumped to when the instruction is skipped. */
54 /* Thumb-2 condtional execution bits. */
57 struct TranslationBlock *tb;
58 int singlestep_enabled;
60 #if !defined(CONFIG_USER_ONLY)
65 #if defined(CONFIG_USER_ONLY)
68 #define IS_USER(s) (s->user)
71 /* These instructions trap after executing, so defer them until after the
72 conditional executions state has been updated. */
76 static TCGv_ptr cpu_env;
77 /* We reuse the same 64-bit temporaries for efficiency. */
78 static TCGv_i64 cpu_V0, cpu_V1, cpu_M0;
80 /* FIXME: These should be removed. */
82 static TCGv cpu_F0s, cpu_F1s;
83 static TCGv_i64 cpu_F0d, cpu_F1d;
85 #define ICOUNT_TEMP cpu_T[0]
86 #include "gen-icount.h"
88 /* initialize TCG globals. */
89 void arm_translate_init(void)
91 cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");
93 cpu_T[0] = tcg_global_reg_new_i32(TCG_AREG1, "T0");
94 cpu_T[1] = tcg_global_reg_new_i32(TCG_AREG2, "T1");
100 /* The code generator doesn't like lots of temporaries, so maintain our own
101 cache for reuse within a function. */
103 static int num_temps;
104 static TCGv temps[MAX_TEMPS];
106 /* Allocate a temporary variable. */
107 static TCGv_i32 new_tmp(void)
110 if (num_temps == MAX_TEMPS)
113 if (GET_TCGV_I32(temps[num_temps]))
114 return temps[num_temps++];
116 tmp = tcg_temp_new_i32();
117 temps[num_temps++] = tmp;
121 /* Release a temporary variable. */
122 static void dead_tmp(TCGv tmp)
127 if (TCGV_EQUAL(temps[i], tmp))
130 /* Shuffle this temp to the last slot. */
131 while (!TCGV_EQUAL(temps[i], tmp))
133 while (i < num_temps) {
134 temps[i] = temps[i + 1];
140 static inline TCGv load_cpu_offset(int offset)
142 TCGv tmp = new_tmp();
143 tcg_gen_ld_i32(tmp, cpu_env, offset);
147 #define load_cpu_field(name) load_cpu_offset(offsetof(CPUState, name))
149 static inline void store_cpu_offset(TCGv var, int offset)
151 tcg_gen_st_i32(var, cpu_env, offset);
155 #define store_cpu_field(var, name) \
156 store_cpu_offset(var, offsetof(CPUState, name))
158 /* Set a variable to the value of a CPU register. */
159 static void load_reg_var(DisasContext *s, TCGv var, int reg)
163 /* normaly, since we updated PC, we need only to add one insn */
165 addr = (long)s->pc + 2;
167 addr = (long)s->pc + 4;
168 tcg_gen_movi_i32(var, addr);
170 tcg_gen_ld_i32(var, cpu_env, offsetof(CPUState, regs[reg]));
174 /* Create a new temporary and set it to the value of a CPU register. */
175 static inline TCGv load_reg(DisasContext *s, int reg)
177 TCGv tmp = new_tmp();
178 load_reg_var(s, tmp, reg);
182 /* Set a CPU register. The source must be a temporary and will be
184 static void store_reg(DisasContext *s, int reg, TCGv var)
187 tcg_gen_andi_i32(var, var, ~1);
188 s->is_jmp = DISAS_JUMP;
190 tcg_gen_st_i32(var, cpu_env, offsetof(CPUState, regs[reg]));
195 /* Basic operations. */
196 #define gen_op_movl_T0_T1() tcg_gen_mov_i32(cpu_T[0], cpu_T[1])
197 #define gen_op_movl_T0_im(im) tcg_gen_movi_i32(cpu_T[0], im)
198 #define gen_op_movl_T1_im(im) tcg_gen_movi_i32(cpu_T[1], im)
200 #define gen_op_addl_T1_im(im) tcg_gen_addi_i32(cpu_T[1], cpu_T[1], im)
201 #define gen_op_addl_T0_T1() tcg_gen_add_i32(cpu_T[0], cpu_T[0], cpu_T[1])
202 #define gen_op_subl_T0_T1() tcg_gen_sub_i32(cpu_T[0], cpu_T[0], cpu_T[1])
203 #define gen_op_rsbl_T0_T1() tcg_gen_sub_i32(cpu_T[0], cpu_T[1], cpu_T[0])
205 #define gen_op_addl_T0_T1_cc() gen_helper_add_cc(cpu_T[0], cpu_T[0], cpu_T[1])
206 #define gen_op_adcl_T0_T1_cc() gen_helper_adc_cc(cpu_T[0], cpu_T[0], cpu_T[1])
207 #define gen_op_subl_T0_T1_cc() gen_helper_sub_cc(cpu_T[0], cpu_T[0], cpu_T[1])
208 #define gen_op_sbcl_T0_T1_cc() gen_helper_sbc_cc(cpu_T[0], cpu_T[0], cpu_T[1])
209 #define gen_op_rsbl_T0_T1_cc() gen_helper_sub_cc(cpu_T[0], cpu_T[1], cpu_T[0])
211 #define gen_op_andl_T0_T1() tcg_gen_and_i32(cpu_T[0], cpu_T[0], cpu_T[1])
212 #define gen_op_xorl_T0_T1() tcg_gen_xor_i32(cpu_T[0], cpu_T[0], cpu_T[1])
213 #define gen_op_orl_T0_T1() tcg_gen_or_i32(cpu_T[0], cpu_T[0], cpu_T[1])
214 #define gen_op_notl_T0() tcg_gen_not_i32(cpu_T[0], cpu_T[0])
215 #define gen_op_notl_T1() tcg_gen_not_i32(cpu_T[1], cpu_T[1])
216 #define gen_op_logic_T0_cc() gen_logic_CC(cpu_T[0]);
217 #define gen_op_logic_T1_cc() gen_logic_CC(cpu_T[1]);
219 #define gen_op_shll_T1_im(im) tcg_gen_shli_i32(cpu_T[1], cpu_T[1], im)
220 #define gen_op_shrl_T1_im(im) tcg_gen_shri_i32(cpu_T[1], cpu_T[1], im)
222 /* Value extensions. */
223 #define gen_uxtb(var) tcg_gen_ext8u_i32(var, var)
224 #define gen_uxth(var) tcg_gen_ext16u_i32(var, var)
225 #define gen_sxtb(var) tcg_gen_ext8s_i32(var, var)
226 #define gen_sxth(var) tcg_gen_ext16s_i32(var, var)
228 #define gen_sxtb16(var) gen_helper_sxtb16(var, var)
229 #define gen_uxtb16(var) gen_helper_uxtb16(var, var)
231 #define gen_op_mul_T0_T1() tcg_gen_mul_i32(cpu_T[0], cpu_T[0], cpu_T[1])
233 #define gen_set_cpsr(var, mask) gen_helper_cpsr_write(var, tcg_const_i32(mask))
234 /* Set NZCV flags from the high 4 bits of var. */
235 #define gen_set_nzcv(var) gen_set_cpsr(var, CPSR_NZCV)
237 static void gen_exception(int excp)
239 TCGv tmp = new_tmp();
240 tcg_gen_movi_i32(tmp, excp);
241 gen_helper_exception(tmp);
245 static void gen_smul_dual(TCGv a, TCGv b)
247 TCGv tmp1 = new_tmp();
248 TCGv tmp2 = new_tmp();
249 tcg_gen_ext16s_i32(tmp1, a);
250 tcg_gen_ext16s_i32(tmp2, b);
251 tcg_gen_mul_i32(tmp1, tmp1, tmp2);
253 tcg_gen_sari_i32(a, a, 16);
254 tcg_gen_sari_i32(b, b, 16);
255 tcg_gen_mul_i32(b, b, a);
256 tcg_gen_mov_i32(a, tmp1);
260 /* Byteswap each halfword. */
261 static void gen_rev16(TCGv var)
263 TCGv tmp = new_tmp();
264 tcg_gen_shri_i32(tmp, var, 8);
265 tcg_gen_andi_i32(tmp, tmp, 0x00ff00ff);
266 tcg_gen_shli_i32(var, var, 8);
267 tcg_gen_andi_i32(var, var, 0xff00ff00);
268 tcg_gen_or_i32(var, var, tmp);
272 /* Byteswap low halfword and sign extend. */
273 static void gen_revsh(TCGv var)
275 TCGv tmp = new_tmp();
276 tcg_gen_shri_i32(tmp, var, 8);
277 tcg_gen_andi_i32(tmp, tmp, 0x00ff);
278 tcg_gen_shli_i32(var, var, 8);
279 tcg_gen_ext8s_i32(var, var);
280 tcg_gen_or_i32(var, var, tmp);
284 /* Unsigned bitfield extract. */
285 static void gen_ubfx(TCGv var, int shift, uint32_t mask)
288 tcg_gen_shri_i32(var, var, shift);
289 tcg_gen_andi_i32(var, var, mask);
292 /* Signed bitfield extract. */
293 static void gen_sbfx(TCGv var, int shift, int width)
298 tcg_gen_sari_i32(var, var, shift);
299 if (shift + width < 32) {
300 signbit = 1u << (width - 1);
301 tcg_gen_andi_i32(var, var, (1u << width) - 1);
302 tcg_gen_xori_i32(var, var, signbit);
303 tcg_gen_subi_i32(var, var, signbit);
307 /* Bitfield insertion. Insert val into base. Clobbers base and val. */
308 static void gen_bfi(TCGv dest, TCGv base, TCGv val, int shift, uint32_t mask)
310 tcg_gen_andi_i32(val, val, mask);
311 tcg_gen_shli_i32(val, val, shift);
312 tcg_gen_andi_i32(base, base, ~(mask << shift));
313 tcg_gen_or_i32(dest, base, val);
316 /* Round the top 32 bits of a 64-bit value. */
317 static void gen_roundqd(TCGv a, TCGv b)
319 tcg_gen_shri_i32(a, a, 31);
320 tcg_gen_add_i32(a, a, b);
323 /* FIXME: Most targets have native widening multiplication.
324 It would be good to use that instead of a full wide multiply. */
325 /* 32x32->64 multiply. Marks inputs as dead. */
326 static TCGv_i64 gen_mulu_i64_i32(TCGv a, TCGv b)
328 TCGv_i64 tmp1 = tcg_temp_new_i64();
329 TCGv_i64 tmp2 = tcg_temp_new_i64();
331 tcg_gen_extu_i32_i64(tmp1, a);
333 tcg_gen_extu_i32_i64(tmp2, b);
335 tcg_gen_mul_i64(tmp1, tmp1, tmp2);
339 static TCGv_i64 gen_muls_i64_i32(TCGv a, TCGv b)
341 TCGv_i64 tmp1 = tcg_temp_new_i64();
342 TCGv_i64 tmp2 = tcg_temp_new_i64();
344 tcg_gen_ext_i32_i64(tmp1, a);
346 tcg_gen_ext_i32_i64(tmp2, b);
348 tcg_gen_mul_i64(tmp1, tmp1, tmp2);
352 /* Unsigned 32x32->64 multiply. */
353 static void gen_op_mull_T0_T1(void)
355 TCGv_i64 tmp1 = tcg_temp_new_i64();
356 TCGv_i64 tmp2 = tcg_temp_new_i64();
358 tcg_gen_extu_i32_i64(tmp1, cpu_T[0]);
359 tcg_gen_extu_i32_i64(tmp2, cpu_T[1]);
360 tcg_gen_mul_i64(tmp1, tmp1, tmp2);
361 tcg_gen_trunc_i64_i32(cpu_T[0], tmp1);
362 tcg_gen_shri_i64(tmp1, tmp1, 32);
363 tcg_gen_trunc_i64_i32(cpu_T[1], tmp1);
366 /* Signed 32x32->64 multiply. */
367 static void gen_imull(TCGv a, TCGv b)
369 TCGv_i64 tmp1 = tcg_temp_new_i64();
370 TCGv_i64 tmp2 = tcg_temp_new_i64();
372 tcg_gen_ext_i32_i64(tmp1, a);
373 tcg_gen_ext_i32_i64(tmp2, b);
374 tcg_gen_mul_i64(tmp1, tmp1, tmp2);
375 tcg_gen_trunc_i64_i32(a, tmp1);
376 tcg_gen_shri_i64(tmp1, tmp1, 32);
377 tcg_gen_trunc_i64_i32(b, tmp1);
380 /* Swap low and high halfwords. */
381 static void gen_swap_half(TCGv var)
383 TCGv tmp = new_tmp();
384 tcg_gen_shri_i32(tmp, var, 16);
385 tcg_gen_shli_i32(var, var, 16);
386 tcg_gen_or_i32(var, var, tmp);
390 /* Dual 16-bit add. Result placed in t0 and t1 is marked as dead.
391 tmp = (t0 ^ t1) & 0x8000;
394 t0 = (t0 + t1) ^ tmp;
397 static void gen_add16(TCGv t0, TCGv t1)
399 TCGv tmp = new_tmp();
400 tcg_gen_xor_i32(tmp, t0, t1);
401 tcg_gen_andi_i32(tmp, tmp, 0x8000);
402 tcg_gen_andi_i32(t0, t0, ~0x8000);
403 tcg_gen_andi_i32(t1, t1, ~0x8000);
404 tcg_gen_add_i32(t0, t0, t1);
405 tcg_gen_xor_i32(t0, t0, tmp);
410 #define gen_set_CF(var) tcg_gen_st_i32(var, cpu_env, offsetof(CPUState, CF))
412 /* Set CF to the top bit of var. */
413 static void gen_set_CF_bit31(TCGv var)
415 TCGv tmp = new_tmp();
416 tcg_gen_shri_i32(tmp, var, 31);
421 /* Set N and Z flags from var. */
422 static inline void gen_logic_CC(TCGv var)
424 tcg_gen_st_i32(var, cpu_env, offsetof(CPUState, NF));
425 tcg_gen_st_i32(var, cpu_env, offsetof(CPUState, ZF));
429 static void gen_adc_T0_T1(void)
433 tmp = load_cpu_field(CF);
434 tcg_gen_add_i32(cpu_T[0], cpu_T[0], tmp);
438 /* dest = T0 + T1 + CF. */
439 static void gen_add_carry(TCGv dest, TCGv t0, TCGv t1)
442 tcg_gen_add_i32(dest, t0, t1);
443 tmp = load_cpu_field(CF);
444 tcg_gen_add_i32(dest, dest, tmp);
448 /* dest = T0 - T1 + CF - 1. */
449 static void gen_sub_carry(TCGv dest, TCGv t0, TCGv t1)
452 tcg_gen_sub_i32(dest, t0, t1);
453 tmp = load_cpu_field(CF);
454 tcg_gen_add_i32(dest, dest, tmp);
455 tcg_gen_subi_i32(dest, dest, 1);
459 #define gen_sbc_T0_T1() gen_sub_carry(cpu_T[0], cpu_T[0], cpu_T[1])
460 #define gen_rsc_T0_T1() gen_sub_carry(cpu_T[0], cpu_T[1], cpu_T[0])
462 /* T0 &= ~T1. Clobbers T1. */
463 /* FIXME: Implement bic natively. */
464 static inline void tcg_gen_bic_i32(TCGv dest, TCGv t0, TCGv t1)
466 TCGv tmp = new_tmp();
467 tcg_gen_not_i32(tmp, t1);
468 tcg_gen_and_i32(dest, t0, tmp);
471 static inline void gen_op_bicl_T0_T1(void)
477 /* FIXME: Implement this natively. */
478 #define tcg_gen_abs_i32(t0, t1) gen_helper_abs(t0, t1)
480 /* FIXME: Implement this natively. */
481 static void tcg_gen_rori_i32(TCGv t0, TCGv t1, int i)
489 tcg_gen_shri_i32(tmp, t1, i);
490 tcg_gen_shli_i32(t1, t1, 32 - i);
491 tcg_gen_or_i32(t0, t1, tmp);
495 static void shifter_out_im(TCGv var, int shift)
497 TCGv tmp = new_tmp();
499 tcg_gen_andi_i32(tmp, var, 1);
501 tcg_gen_shri_i32(tmp, var, shift);
503 tcg_gen_andi_i32(tmp, tmp, 1);
509 /* Shift by immediate. Includes special handling for shift == 0. */
510 static inline void gen_arm_shift_im(TCGv var, int shiftop, int shift, int flags)
516 shifter_out_im(var, 32 - shift);
517 tcg_gen_shli_i32(var, var, shift);
523 tcg_gen_shri_i32(var, var, 31);
526 tcg_gen_movi_i32(var, 0);
529 shifter_out_im(var, shift - 1);
530 tcg_gen_shri_i32(var, var, shift);
537 shifter_out_im(var, shift - 1);
540 tcg_gen_sari_i32(var, var, shift);
542 case 3: /* ROR/RRX */
545 shifter_out_im(var, shift - 1);
546 tcg_gen_rori_i32(var, var, shift); break;
548 TCGv tmp = load_cpu_field(CF);
550 shifter_out_im(var, 0);
551 tcg_gen_shri_i32(var, var, 1);
552 tcg_gen_shli_i32(tmp, tmp, 31);
553 tcg_gen_or_i32(var, var, tmp);
559 static inline void gen_arm_shift_reg(TCGv var, int shiftop,
560 TCGv shift, int flags)
564 case 0: gen_helper_shl_cc(var, var, shift); break;
565 case 1: gen_helper_shr_cc(var, var, shift); break;
566 case 2: gen_helper_sar_cc(var, var, shift); break;
567 case 3: gen_helper_ror_cc(var, var, shift); break;
571 case 0: gen_helper_shl(var, var, shift); break;
572 case 1: gen_helper_shr(var, var, shift); break;
573 case 2: gen_helper_sar(var, var, shift); break;
574 case 3: gen_helper_ror(var, var, shift); break;
580 #define PAS_OP(pfx) \
582 case 0: gen_pas_helper(glue(pfx,add16)); break; \
583 case 1: gen_pas_helper(glue(pfx,addsubx)); break; \
584 case 2: gen_pas_helper(glue(pfx,subaddx)); break; \
585 case 3: gen_pas_helper(glue(pfx,sub16)); break; \
586 case 4: gen_pas_helper(glue(pfx,add8)); break; \
587 case 7: gen_pas_helper(glue(pfx,sub8)); break; \
589 static void gen_arm_parallel_addsub(int op1, int op2, TCGv a, TCGv b)
594 #define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b, tmp)
596 tmp = tcg_temp_new_ptr();
597 tcg_gen_addi_ptr(tmp, cpu_env, offsetof(CPUState, GE));
601 tmp = tcg_temp_new_ptr();
602 tcg_gen_addi_ptr(tmp, cpu_env, offsetof(CPUState, GE));
605 #undef gen_pas_helper
606 #define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b)
619 #undef gen_pas_helper
624 /* For unknown reasons Arm and Thumb-2 use arbitrarily different encodings. */
625 #define PAS_OP(pfx) \
627 case 0: gen_pas_helper(glue(pfx,add8)); break; \
628 case 1: gen_pas_helper(glue(pfx,add16)); break; \
629 case 2: gen_pas_helper(glue(pfx,addsubx)); break; \
630 case 4: gen_pas_helper(glue(pfx,sub8)); break; \
631 case 5: gen_pas_helper(glue(pfx,sub16)); break; \
632 case 6: gen_pas_helper(glue(pfx,subaddx)); break; \
634 static void gen_thumb2_parallel_addsub(int op1, int op2, TCGv a, TCGv b)
639 #define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b, tmp)
641 tmp = tcg_temp_new_ptr();
642 tcg_gen_addi_ptr(tmp, cpu_env, offsetof(CPUState, GE));
646 tmp = tcg_temp_new_ptr();
647 tcg_gen_addi_ptr(tmp, cpu_env, offsetof(CPUState, GE));
650 #undef gen_pas_helper
651 #define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b)
664 #undef gen_pas_helper
669 static void gen_test_cc(int cc, int label)
677 tmp = load_cpu_field(ZF);
678 tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 0, label);
681 tmp = load_cpu_field(ZF);
682 tcg_gen_brcondi_i32(TCG_COND_NE, tmp, 0, label);
685 tmp = load_cpu_field(CF);
686 tcg_gen_brcondi_i32(TCG_COND_NE, tmp, 0, label);
689 tmp = load_cpu_field(CF);
690 tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 0, label);
693 tmp = load_cpu_field(NF);
694 tcg_gen_brcondi_i32(TCG_COND_LT, tmp, 0, label);
697 tmp = load_cpu_field(NF);
698 tcg_gen_brcondi_i32(TCG_COND_GE, tmp, 0, label);
701 tmp = load_cpu_field(VF);
702 tcg_gen_brcondi_i32(TCG_COND_LT, tmp, 0, label);
705 tmp = load_cpu_field(VF);
706 tcg_gen_brcondi_i32(TCG_COND_GE, tmp, 0, label);
708 case 8: /* hi: C && !Z */
709 inv = gen_new_label();
710 tmp = load_cpu_field(CF);
711 tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 0, inv);
713 tmp = load_cpu_field(ZF);
714 tcg_gen_brcondi_i32(TCG_COND_NE, tmp, 0, label);
717 case 9: /* ls: !C || Z */
718 tmp = load_cpu_field(CF);
719 tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 0, label);
721 tmp = load_cpu_field(ZF);
722 tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 0, label);
724 case 10: /* ge: N == V -> N ^ V == 0 */
725 tmp = load_cpu_field(VF);
726 tmp2 = load_cpu_field(NF);
727 tcg_gen_xor_i32(tmp, tmp, tmp2);
729 tcg_gen_brcondi_i32(TCG_COND_GE, tmp, 0, label);
731 case 11: /* lt: N != V -> N ^ V != 0 */
732 tmp = load_cpu_field(VF);
733 tmp2 = load_cpu_field(NF);
734 tcg_gen_xor_i32(tmp, tmp, tmp2);
736 tcg_gen_brcondi_i32(TCG_COND_LT, tmp, 0, label);
738 case 12: /* gt: !Z && N == V */
739 inv = gen_new_label();
740 tmp = load_cpu_field(ZF);
741 tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 0, inv);
743 tmp = load_cpu_field(VF);
744 tmp2 = load_cpu_field(NF);
745 tcg_gen_xor_i32(tmp, tmp, tmp2);
747 tcg_gen_brcondi_i32(TCG_COND_GE, tmp, 0, label);
750 case 13: /* le: Z || N != V */
751 tmp = load_cpu_field(ZF);
752 tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 0, label);
754 tmp = load_cpu_field(VF);
755 tmp2 = load_cpu_field(NF);
756 tcg_gen_xor_i32(tmp, tmp, tmp2);
758 tcg_gen_brcondi_i32(TCG_COND_LT, tmp, 0, label);
761 fprintf(stderr, "Bad condition code 0x%x\n", cc);
767 static const uint8_t table_logic_cc[16] = {
786 /* Set PC and Thumb state from an immediate address. */
787 static inline void gen_bx_im(DisasContext *s, uint32_t addr)
791 s->is_jmp = DISAS_UPDATE;
793 if (s->thumb != (addr & 1)) {
794 tcg_gen_movi_i32(tmp, addr & 1);
795 tcg_gen_st_i32(tmp, cpu_env, offsetof(CPUState, thumb));
797 tcg_gen_movi_i32(tmp, addr & ~1);
798 tcg_gen_st_i32(tmp, cpu_env, offsetof(CPUState, regs[15]));
802 /* Set PC and Thumb state from var. var is marked as dead. */
803 static inline void gen_bx(DisasContext *s, TCGv var)
807 s->is_jmp = DISAS_UPDATE;
809 tcg_gen_andi_i32(tmp, var, 1);
810 store_cpu_field(tmp, thumb);
811 tcg_gen_andi_i32(var, var, ~1);
812 store_cpu_field(var, regs[15]);
815 /* TODO: This should be removed. Use gen_bx instead. */
816 static inline void gen_bx_T0(DisasContext *s)
818 TCGv tmp = new_tmp();
819 tcg_gen_mov_i32(tmp, cpu_T[0]);
823 /* Variant of store_reg which uses branch&exchange logic when storing
824 to r15 in ARM architecture v7 and above. The source must be a temporary
825 and will be marked as dead. */
826 static inline void store_reg_bx(CPUState *env, DisasContext *s,
829 if (reg == 15 && ENABLE_ARCH_7) {
832 store_reg(s, reg, var);
836 static inline TCGv gen_ld8s(TCGv addr, int index)
838 TCGv tmp = new_tmp();
839 tcg_gen_qemu_ld8s(tmp, addr, index);
842 static inline TCGv gen_ld8u(TCGv addr, int index)
844 TCGv tmp = new_tmp();
845 tcg_gen_qemu_ld8u(tmp, addr, index);
848 static inline TCGv gen_ld16s(TCGv addr, int index)
850 TCGv tmp = new_tmp();
851 tcg_gen_qemu_ld16s(tmp, addr, index);
854 static inline TCGv gen_ld16u(TCGv addr, int index)
856 TCGv tmp = new_tmp();
857 tcg_gen_qemu_ld16u(tmp, addr, index);
860 static inline TCGv gen_ld32(TCGv addr, int index)
862 TCGv tmp = new_tmp();
863 tcg_gen_qemu_ld32u(tmp, addr, index);
866 static inline void gen_st8(TCGv val, TCGv addr, int index)
868 tcg_gen_qemu_st8(val, addr, index);
871 static inline void gen_st16(TCGv val, TCGv addr, int index)
873 tcg_gen_qemu_st16(val, addr, index);
876 static inline void gen_st32(TCGv val, TCGv addr, int index)
878 tcg_gen_qemu_st32(val, addr, index);
882 static inline void gen_movl_T0_reg(DisasContext *s, int reg)
884 load_reg_var(s, cpu_T[0], reg);
887 static inline void gen_movl_T1_reg(DisasContext *s, int reg)
889 load_reg_var(s, cpu_T[1], reg);
892 static inline void gen_movl_T2_reg(DisasContext *s, int reg)
894 load_reg_var(s, cpu_T[2], reg);
897 static inline void gen_set_pc_im(uint32_t val)
899 TCGv tmp = new_tmp();
900 tcg_gen_movi_i32(tmp, val);
901 store_cpu_field(tmp, regs[15]);
904 static inline void gen_movl_reg_TN(DisasContext *s, int reg, int t)
909 tcg_gen_andi_i32(tmp, cpu_T[t], ~1);
913 tcg_gen_st_i32(tmp, cpu_env, offsetof(CPUState, regs[reg]));
916 s->is_jmp = DISAS_JUMP;
920 static inline void gen_movl_reg_T0(DisasContext *s, int reg)
922 gen_movl_reg_TN(s, reg, 0);
925 static inline void gen_movl_reg_T1(DisasContext *s, int reg)
927 gen_movl_reg_TN(s, reg, 1);
930 /* Force a TB lookup after an instruction that changes the CPU state. */
931 static inline void gen_lookup_tb(DisasContext *s)
933 gen_op_movl_T0_im(s->pc);
934 gen_movl_reg_T0(s, 15);
935 s->is_jmp = DISAS_UPDATE;
938 static inline void gen_add_data_offset(DisasContext *s, unsigned int insn,
941 int val, rm, shift, shiftop;
944 if (!(insn & (1 << 25))) {
947 if (!(insn & (1 << 23)))
950 tcg_gen_addi_i32(var, var, val);
954 shift = (insn >> 7) & 0x1f;
955 shiftop = (insn >> 5) & 3;
956 offset = load_reg(s, rm);
957 gen_arm_shift_im(offset, shiftop, shift, 0);
958 if (!(insn & (1 << 23)))
959 tcg_gen_sub_i32(var, var, offset);
961 tcg_gen_add_i32(var, var, offset);
966 static inline void gen_add_datah_offset(DisasContext *s, unsigned int insn,
972 if (insn & (1 << 22)) {
974 val = (insn & 0xf) | ((insn >> 4) & 0xf0);
975 if (!(insn & (1 << 23)))
979 tcg_gen_addi_i32(var, var, val);
983 tcg_gen_addi_i32(var, var, extra);
985 offset = load_reg(s, rm);
986 if (!(insn & (1 << 23)))
987 tcg_gen_sub_i32(var, var, offset);
989 tcg_gen_add_i32(var, var, offset);
994 #define VFP_OP2(name) \
995 static inline void gen_vfp_##name(int dp) \
998 gen_helper_vfp_##name##d(cpu_F0d, cpu_F0d, cpu_F1d, cpu_env); \
1000 gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, cpu_F1s, cpu_env); \
1010 static inline void gen_vfp_abs(int dp)
1013 gen_helper_vfp_absd(cpu_F0d, cpu_F0d);
1015 gen_helper_vfp_abss(cpu_F0s, cpu_F0s);
1018 static inline void gen_vfp_neg(int dp)
1021 gen_helper_vfp_negd(cpu_F0d, cpu_F0d);
1023 gen_helper_vfp_negs(cpu_F0s, cpu_F0s);
1026 static inline void gen_vfp_sqrt(int dp)
1029 gen_helper_vfp_sqrtd(cpu_F0d, cpu_F0d, cpu_env);
1031 gen_helper_vfp_sqrts(cpu_F0s, cpu_F0s, cpu_env);
1034 static inline void gen_vfp_cmp(int dp)
1037 gen_helper_vfp_cmpd(cpu_F0d, cpu_F1d, cpu_env);
1039 gen_helper_vfp_cmps(cpu_F0s, cpu_F1s, cpu_env);
1042 static inline void gen_vfp_cmpe(int dp)
1045 gen_helper_vfp_cmped(cpu_F0d, cpu_F1d, cpu_env);
1047 gen_helper_vfp_cmpes(cpu_F0s, cpu_F1s, cpu_env);
1050 static inline void gen_vfp_F1_ld0(int dp)
1053 tcg_gen_movi_i64(cpu_F1d, 0);
1055 tcg_gen_movi_i32(cpu_F1s, 0);
1058 static inline void gen_vfp_uito(int dp)
1061 gen_helper_vfp_uitod(cpu_F0d, cpu_F0s, cpu_env);
1063 gen_helper_vfp_uitos(cpu_F0s, cpu_F0s, cpu_env);
1066 static inline void gen_vfp_sito(int dp)
1069 gen_helper_vfp_sitod(cpu_F0d, cpu_F0s, cpu_env);
1071 gen_helper_vfp_sitos(cpu_F0s, cpu_F0s, cpu_env);
1074 static inline void gen_vfp_toui(int dp)
1077 gen_helper_vfp_touid(cpu_F0s, cpu_F0d, cpu_env);
1079 gen_helper_vfp_touis(cpu_F0s, cpu_F0s, cpu_env);
1082 static inline void gen_vfp_touiz(int dp)
1085 gen_helper_vfp_touizd(cpu_F0s, cpu_F0d, cpu_env);
1087 gen_helper_vfp_touizs(cpu_F0s, cpu_F0s, cpu_env);
1090 static inline void gen_vfp_tosi(int dp)
1093 gen_helper_vfp_tosid(cpu_F0s, cpu_F0d, cpu_env);
1095 gen_helper_vfp_tosis(cpu_F0s, cpu_F0s, cpu_env);
1098 static inline void gen_vfp_tosiz(int dp)
1101 gen_helper_vfp_tosizd(cpu_F0s, cpu_F0d, cpu_env);
1103 gen_helper_vfp_tosizs(cpu_F0s, cpu_F0s, cpu_env);
1106 #define VFP_GEN_FIX(name) \
1107 static inline void gen_vfp_##name(int dp, int shift) \
1110 gen_helper_vfp_##name##d(cpu_F0d, cpu_F0d, tcg_const_i32(shift), cpu_env);\
1112 gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, tcg_const_i32(shift), cpu_env);\
1124 static inline void gen_vfp_ld(DisasContext *s, int dp)
1127 tcg_gen_qemu_ld64(cpu_F0d, cpu_T[1], IS_USER(s));
1129 tcg_gen_qemu_ld32u(cpu_F0s, cpu_T[1], IS_USER(s));
1132 static inline void gen_vfp_st(DisasContext *s, int dp)
1135 tcg_gen_qemu_st64(cpu_F0d, cpu_T[1], IS_USER(s));
1137 tcg_gen_qemu_st32(cpu_F0s, cpu_T[1], IS_USER(s));
1141 vfp_reg_offset (int dp, int reg)
1144 return offsetof(CPUARMState, vfp.regs[reg]);
1146 return offsetof(CPUARMState, vfp.regs[reg >> 1])
1147 + offsetof(CPU_DoubleU, l.upper);
1149 return offsetof(CPUARMState, vfp.regs[reg >> 1])
1150 + offsetof(CPU_DoubleU, l.lower);
1154 /* Return the offset of a 32-bit piece of a NEON register.
1155 zero is the least significant end of the register. */
1157 neon_reg_offset (int reg, int n)
1161 return vfp_reg_offset(0, sreg);
1164 /* FIXME: Remove these. */
1165 #define neon_T0 cpu_T[0]
1166 #define neon_T1 cpu_T[1]
1167 #define NEON_GET_REG(T, reg, n) \
1168 tcg_gen_ld_i32(neon_##T, cpu_env, neon_reg_offset(reg, n))
1169 #define NEON_SET_REG(T, reg, n) \
1170 tcg_gen_st_i32(neon_##T, cpu_env, neon_reg_offset(reg, n))
1172 static TCGv neon_load_reg(int reg, int pass)
1174 TCGv tmp = new_tmp();
1175 tcg_gen_ld_i32(tmp, cpu_env, neon_reg_offset(reg, pass));
1179 static void neon_store_reg(int reg, int pass, TCGv var)
1181 tcg_gen_st_i32(var, cpu_env, neon_reg_offset(reg, pass));
1185 static inline void neon_load_reg64(TCGv_i64 var, int reg)
1187 tcg_gen_ld_i64(var, cpu_env, vfp_reg_offset(1, reg));
1190 static inline void neon_store_reg64(TCGv_i64 var, int reg)
1192 tcg_gen_st_i64(var, cpu_env, vfp_reg_offset(1, reg));
1195 #define tcg_gen_ld_f32 tcg_gen_ld_i32
1196 #define tcg_gen_ld_f64 tcg_gen_ld_i64
1197 #define tcg_gen_st_f32 tcg_gen_st_i32
1198 #define tcg_gen_st_f64 tcg_gen_st_i64
1200 static inline void gen_mov_F0_vreg(int dp, int reg)
1203 tcg_gen_ld_f64(cpu_F0d, cpu_env, vfp_reg_offset(dp, reg));
1205 tcg_gen_ld_f32(cpu_F0s, cpu_env, vfp_reg_offset(dp, reg));
1208 static inline void gen_mov_F1_vreg(int dp, int reg)
1211 tcg_gen_ld_f64(cpu_F1d, cpu_env, vfp_reg_offset(dp, reg));
1213 tcg_gen_ld_f32(cpu_F1s, cpu_env, vfp_reg_offset(dp, reg));
1216 static inline void gen_mov_vreg_F0(int dp, int reg)
1219 tcg_gen_st_f64(cpu_F0d, cpu_env, vfp_reg_offset(dp, reg));
1221 tcg_gen_st_f32(cpu_F0s, cpu_env, vfp_reg_offset(dp, reg));
1224 #define ARM_CP_RW_BIT (1 << 20)
1226 static inline void iwmmxt_load_reg(TCGv_i64 var, int reg)
1228 tcg_gen_ld_i64(var, cpu_env, offsetof(CPUState, iwmmxt.regs[reg]));
1231 static inline void iwmmxt_store_reg(TCGv_i64 var, int reg)
1233 tcg_gen_st_i64(var, cpu_env, offsetof(CPUState, iwmmxt.regs[reg]));
1236 static inline void gen_op_iwmmxt_movl_wCx_T0(int reg)
1238 tcg_gen_st_i32(cpu_T[0], cpu_env, offsetof(CPUState, iwmmxt.cregs[reg]));
1241 static inline void gen_op_iwmmxt_movl_T0_wCx(int reg)
1243 tcg_gen_ld_i32(cpu_T[0], cpu_env, offsetof(CPUState, iwmmxt.cregs[reg]));
1246 static inline void gen_op_iwmmxt_movl_T1_wCx(int reg)
1248 tcg_gen_ld_i32(cpu_T[1], cpu_env, offsetof(CPUState, iwmmxt.cregs[reg]));
1251 static inline void gen_op_iwmmxt_movq_wRn_M0(int rn)
1253 iwmmxt_store_reg(cpu_M0, rn);
1256 static inline void gen_op_iwmmxt_movq_M0_wRn(int rn)
1258 iwmmxt_load_reg(cpu_M0, rn);
1261 static inline void gen_op_iwmmxt_orq_M0_wRn(int rn)
1263 iwmmxt_load_reg(cpu_V1, rn);
1264 tcg_gen_or_i64(cpu_M0, cpu_M0, cpu_V1);
1267 static inline void gen_op_iwmmxt_andq_M0_wRn(int rn)
1269 iwmmxt_load_reg(cpu_V1, rn);
1270 tcg_gen_and_i64(cpu_M0, cpu_M0, cpu_V1);
1273 static inline void gen_op_iwmmxt_xorq_M0_wRn(int rn)
1275 iwmmxt_load_reg(cpu_V1, rn);
1276 tcg_gen_xor_i64(cpu_M0, cpu_M0, cpu_V1);
1279 #define IWMMXT_OP(name) \
1280 static inline void gen_op_iwmmxt_##name##_M0_wRn(int rn) \
1282 iwmmxt_load_reg(cpu_V1, rn); \
1283 gen_helper_iwmmxt_##name(cpu_M0, cpu_M0, cpu_V1); \
1286 #define IWMMXT_OP_ENV(name) \
1287 static inline void gen_op_iwmmxt_##name##_M0_wRn(int rn) \
1289 iwmmxt_load_reg(cpu_V1, rn); \
1290 gen_helper_iwmmxt_##name(cpu_M0, cpu_env, cpu_M0, cpu_V1); \
1293 #define IWMMXT_OP_ENV_SIZE(name) \
1294 IWMMXT_OP_ENV(name##b) \
1295 IWMMXT_OP_ENV(name##w) \
1296 IWMMXT_OP_ENV(name##l)
1298 #define IWMMXT_OP_ENV1(name) \
1299 static inline void gen_op_iwmmxt_##name##_M0(void) \
1301 gen_helper_iwmmxt_##name(cpu_M0, cpu_env, cpu_M0); \
1315 IWMMXT_OP_ENV_SIZE(unpackl)
1316 IWMMXT_OP_ENV_SIZE(unpackh)
1318 IWMMXT_OP_ENV1(unpacklub)
1319 IWMMXT_OP_ENV1(unpackluw)
1320 IWMMXT_OP_ENV1(unpacklul)
1321 IWMMXT_OP_ENV1(unpackhub)
1322 IWMMXT_OP_ENV1(unpackhuw)
1323 IWMMXT_OP_ENV1(unpackhul)
1324 IWMMXT_OP_ENV1(unpacklsb)
1325 IWMMXT_OP_ENV1(unpacklsw)
1326 IWMMXT_OP_ENV1(unpacklsl)
1327 IWMMXT_OP_ENV1(unpackhsb)
1328 IWMMXT_OP_ENV1(unpackhsw)
1329 IWMMXT_OP_ENV1(unpackhsl)
1331 IWMMXT_OP_ENV_SIZE(cmpeq)
1332 IWMMXT_OP_ENV_SIZE(cmpgtu)
1333 IWMMXT_OP_ENV_SIZE(cmpgts)
1335 IWMMXT_OP_ENV_SIZE(mins)
1336 IWMMXT_OP_ENV_SIZE(minu)
1337 IWMMXT_OP_ENV_SIZE(maxs)
1338 IWMMXT_OP_ENV_SIZE(maxu)
1340 IWMMXT_OP_ENV_SIZE(subn)
1341 IWMMXT_OP_ENV_SIZE(addn)
1342 IWMMXT_OP_ENV_SIZE(subu)
1343 IWMMXT_OP_ENV_SIZE(addu)
1344 IWMMXT_OP_ENV_SIZE(subs)
1345 IWMMXT_OP_ENV_SIZE(adds)
1347 IWMMXT_OP_ENV(avgb0)
1348 IWMMXT_OP_ENV(avgb1)
1349 IWMMXT_OP_ENV(avgw0)
1350 IWMMXT_OP_ENV(avgw1)
1354 IWMMXT_OP_ENV(packuw)
1355 IWMMXT_OP_ENV(packul)
1356 IWMMXT_OP_ENV(packuq)
1357 IWMMXT_OP_ENV(packsw)
1358 IWMMXT_OP_ENV(packsl)
1359 IWMMXT_OP_ENV(packsq)
1361 static inline void gen_op_iwmmxt_muladdsl_M0_T0_T1(void)
1363 gen_helper_iwmmxt_muladdsl(cpu_M0, cpu_M0, cpu_T[0], cpu_T[1]);
1366 static inline void gen_op_iwmmxt_muladdsw_M0_T0_T1(void)
1368 gen_helper_iwmmxt_muladdsw(cpu_M0, cpu_M0, cpu_T[0], cpu_T[1]);
1371 static inline void gen_op_iwmmxt_muladdswl_M0_T0_T1(void)
1373 gen_helper_iwmmxt_muladdswl(cpu_M0, cpu_M0, cpu_T[0], cpu_T[1]);
1376 static inline void gen_op_iwmmxt_align_M0_T0_wRn(int rn)
1378 iwmmxt_load_reg(cpu_V1, rn);
1379 gen_helper_iwmmxt_align(cpu_M0, cpu_M0, cpu_V1, cpu_T[0]);
1382 static inline void gen_op_iwmmxt_insr_M0_T0_T1(int shift)
1384 TCGv tmp = tcg_const_i32(shift);
1385 gen_helper_iwmmxt_insr(cpu_M0, cpu_M0, cpu_T[0], cpu_T[1], tmp);
1388 static inline void gen_op_iwmmxt_extrsb_T0_M0(int shift)
1390 tcg_gen_shri_i64(cpu_M0, cpu_M0, shift);
1391 tcg_gen_trunc_i64_i32(cpu_T[0], cpu_M0);
1392 tcg_gen_ext8s_i32(cpu_T[0], cpu_T[0]);
1395 static inline void gen_op_iwmmxt_extrsw_T0_M0(int shift)
1397 tcg_gen_shri_i64(cpu_M0, cpu_M0, shift);
1398 tcg_gen_trunc_i64_i32(cpu_T[0], cpu_M0);
1399 tcg_gen_ext16s_i32(cpu_T[0], cpu_T[0]);
1402 static inline void gen_op_iwmmxt_extru_T0_M0(int shift, uint32_t mask)
1404 tcg_gen_shri_i64(cpu_M0, cpu_M0, shift);
1405 tcg_gen_trunc_i64_i32(cpu_T[0], cpu_M0);
1407 tcg_gen_andi_i32(cpu_T[0], cpu_T[0], mask);
1410 static void gen_op_iwmmxt_set_mup(void)
1413 tmp = load_cpu_field(iwmmxt.cregs[ARM_IWMMXT_wCon]);
1414 tcg_gen_ori_i32(tmp, tmp, 2);
1415 store_cpu_field(tmp, iwmmxt.cregs[ARM_IWMMXT_wCon]);
1418 static void gen_op_iwmmxt_set_cup(void)
1421 tmp = load_cpu_field(iwmmxt.cregs[ARM_IWMMXT_wCon]);
1422 tcg_gen_ori_i32(tmp, tmp, 1);
1423 store_cpu_field(tmp, iwmmxt.cregs[ARM_IWMMXT_wCon]);
1426 static void gen_op_iwmmxt_setpsr_nz(void)
1428 TCGv tmp = new_tmp();
1429 gen_helper_iwmmxt_setpsr_nz(tmp, cpu_M0);
1430 store_cpu_field(tmp, iwmmxt.cregs[ARM_IWMMXT_wCASF]);
1433 static inline void gen_op_iwmmxt_addl_M0_wRn(int rn)
1435 iwmmxt_load_reg(cpu_V1, rn);
1436 tcg_gen_ext32u_i64(cpu_V1, cpu_V1);
1437 tcg_gen_add_i64(cpu_M0, cpu_M0, cpu_V1);
1441 static void gen_iwmmxt_movl_T0_T1_wRn(int rn)
1443 iwmmxt_load_reg(cpu_V0, rn);
1444 tcg_gen_trunc_i64_i32(cpu_T[0], cpu_V0);
1445 tcg_gen_shri_i64(cpu_V0, cpu_V0, 32);
1446 tcg_gen_trunc_i64_i32(cpu_T[1], cpu_V0);
1449 static void gen_iwmmxt_movl_wRn_T0_T1(int rn)
1451 tcg_gen_concat_i32_i64(cpu_V0, cpu_T[0], cpu_T[1]);
1452 iwmmxt_store_reg(cpu_V0, rn);
1455 static inline int gen_iwmmxt_address(DisasContext *s, uint32_t insn)
1460 rd = (insn >> 16) & 0xf;
1461 gen_movl_T1_reg(s, rd);
1463 offset = (insn & 0xff) << ((insn >> 7) & 2);
1464 if (insn & (1 << 24)) {
1466 if (insn & (1 << 23))
1467 gen_op_addl_T1_im(offset);
1469 gen_op_addl_T1_im(-offset);
1471 if (insn & (1 << 21))
1472 gen_movl_reg_T1(s, rd);
1473 } else if (insn & (1 << 21)) {
1475 if (insn & (1 << 23))
1476 gen_op_movl_T0_im(offset);
1478 gen_op_movl_T0_im(- offset);
1479 gen_op_addl_T0_T1();
1480 gen_movl_reg_T0(s, rd);
1481 } else if (!(insn & (1 << 23)))
1486 static inline int gen_iwmmxt_shift(uint32_t insn, uint32_t mask)
1488 int rd = (insn >> 0) & 0xf;
1490 if (insn & (1 << 8))
1491 if (rd < ARM_IWMMXT_wCGR0 || rd > ARM_IWMMXT_wCGR3)
1494 gen_op_iwmmxt_movl_T0_wCx(rd);
1496 gen_iwmmxt_movl_T0_T1_wRn(rd);
1498 gen_op_movl_T1_im(mask);
1499 gen_op_andl_T0_T1();
1503 /* Disassemble an iwMMXt instruction. Returns nonzero if an error occured
1504 (ie. an undefined instruction). */
1505 static int disas_iwmmxt_insn(CPUState *env, DisasContext *s, uint32_t insn)
1508 int rdhi, rdlo, rd0, rd1, i;
1511 if ((insn & 0x0e000e00) == 0x0c000000) {
1512 if ((insn & 0x0fe00ff0) == 0x0c400000) {
1514 rdlo = (insn >> 12) & 0xf;
1515 rdhi = (insn >> 16) & 0xf;
1516 if (insn & ARM_CP_RW_BIT) { /* TMRRC */
1517 gen_iwmmxt_movl_T0_T1_wRn(wrd);
1518 gen_movl_reg_T0(s, rdlo);
1519 gen_movl_reg_T1(s, rdhi);
1520 } else { /* TMCRR */
1521 gen_movl_T0_reg(s, rdlo);
1522 gen_movl_T1_reg(s, rdhi);
1523 gen_iwmmxt_movl_wRn_T0_T1(wrd);
1524 gen_op_iwmmxt_set_mup();
1529 wrd = (insn >> 12) & 0xf;
1530 if (gen_iwmmxt_address(s, insn))
1532 if (insn & ARM_CP_RW_BIT) {
1533 if ((insn >> 28) == 0xf) { /* WLDRW wCx */
1534 tmp = gen_ld32(cpu_T[1], IS_USER(s));
1535 tcg_gen_mov_i32(cpu_T[0], tmp);
1537 gen_op_iwmmxt_movl_wCx_T0(wrd);
1540 if (insn & (1 << 8)) {
1541 if (insn & (1 << 22)) { /* WLDRD */
1542 tcg_gen_qemu_ld64(cpu_M0, cpu_T[1], IS_USER(s));
1544 } else { /* WLDRW wRd */
1545 tmp = gen_ld32(cpu_T[1], IS_USER(s));
1548 if (insn & (1 << 22)) { /* WLDRH */
1549 tmp = gen_ld16u(cpu_T[1], IS_USER(s));
1550 } else { /* WLDRB */
1551 tmp = gen_ld8u(cpu_T[1], IS_USER(s));
1555 tcg_gen_extu_i32_i64(cpu_M0, tmp);
1558 gen_op_iwmmxt_movq_wRn_M0(wrd);
1561 if ((insn >> 28) == 0xf) { /* WSTRW wCx */
1562 gen_op_iwmmxt_movl_T0_wCx(wrd);
1564 tcg_gen_mov_i32(tmp, cpu_T[0]);
1565 gen_st32(tmp, cpu_T[1], IS_USER(s));
1567 gen_op_iwmmxt_movq_M0_wRn(wrd);
1569 if (insn & (1 << 8)) {
1570 if (insn & (1 << 22)) { /* WSTRD */
1572 tcg_gen_qemu_st64(cpu_M0, cpu_T[1], IS_USER(s));
1573 } else { /* WSTRW wRd */
1574 tcg_gen_trunc_i64_i32(tmp, cpu_M0);
1575 gen_st32(tmp, cpu_T[1], IS_USER(s));
1578 if (insn & (1 << 22)) { /* WSTRH */
1579 tcg_gen_trunc_i64_i32(tmp, cpu_M0);
1580 gen_st16(tmp, cpu_T[1], IS_USER(s));
1581 } else { /* WSTRB */
1582 tcg_gen_trunc_i64_i32(tmp, cpu_M0);
1583 gen_st8(tmp, cpu_T[1], IS_USER(s));
1591 if ((insn & 0x0f000000) != 0x0e000000)
1594 switch (((insn >> 12) & 0xf00) | ((insn >> 4) & 0xff)) {
1595 case 0x000: /* WOR */
1596 wrd = (insn >> 12) & 0xf;
1597 rd0 = (insn >> 0) & 0xf;
1598 rd1 = (insn >> 16) & 0xf;
1599 gen_op_iwmmxt_movq_M0_wRn(rd0);
1600 gen_op_iwmmxt_orq_M0_wRn(rd1);
1601 gen_op_iwmmxt_setpsr_nz();
1602 gen_op_iwmmxt_movq_wRn_M0(wrd);
1603 gen_op_iwmmxt_set_mup();
1604 gen_op_iwmmxt_set_cup();
1606 case 0x011: /* TMCR */
1609 rd = (insn >> 12) & 0xf;
1610 wrd = (insn >> 16) & 0xf;
1612 case ARM_IWMMXT_wCID:
1613 case ARM_IWMMXT_wCASF:
1615 case ARM_IWMMXT_wCon:
1616 gen_op_iwmmxt_set_cup();
1618 case ARM_IWMMXT_wCSSF:
1619 gen_op_iwmmxt_movl_T0_wCx(wrd);
1620 gen_movl_T1_reg(s, rd);
1621 gen_op_bicl_T0_T1();
1622 gen_op_iwmmxt_movl_wCx_T0(wrd);
1624 case ARM_IWMMXT_wCGR0:
1625 case ARM_IWMMXT_wCGR1:
1626 case ARM_IWMMXT_wCGR2:
1627 case ARM_IWMMXT_wCGR3:
1628 gen_op_iwmmxt_set_cup();
1629 gen_movl_reg_T0(s, rd);
1630 gen_op_iwmmxt_movl_wCx_T0(wrd);
1636 case 0x100: /* WXOR */
1637 wrd = (insn >> 12) & 0xf;
1638 rd0 = (insn >> 0) & 0xf;
1639 rd1 = (insn >> 16) & 0xf;
1640 gen_op_iwmmxt_movq_M0_wRn(rd0);
1641 gen_op_iwmmxt_xorq_M0_wRn(rd1);
1642 gen_op_iwmmxt_setpsr_nz();
1643 gen_op_iwmmxt_movq_wRn_M0(wrd);
1644 gen_op_iwmmxt_set_mup();
1645 gen_op_iwmmxt_set_cup();
1647 case 0x111: /* TMRC */
1650 rd = (insn >> 12) & 0xf;
1651 wrd = (insn >> 16) & 0xf;
1652 gen_op_iwmmxt_movl_T0_wCx(wrd);
1653 gen_movl_reg_T0(s, rd);
1655 case 0x300: /* WANDN */
1656 wrd = (insn >> 12) & 0xf;
1657 rd0 = (insn >> 0) & 0xf;
1658 rd1 = (insn >> 16) & 0xf;
1659 gen_op_iwmmxt_movq_M0_wRn(rd0);
1660 tcg_gen_neg_i64(cpu_M0, cpu_M0);
1661 gen_op_iwmmxt_andq_M0_wRn(rd1);
1662 gen_op_iwmmxt_setpsr_nz();
1663 gen_op_iwmmxt_movq_wRn_M0(wrd);
1664 gen_op_iwmmxt_set_mup();
1665 gen_op_iwmmxt_set_cup();
1667 case 0x200: /* WAND */
1668 wrd = (insn >> 12) & 0xf;
1669 rd0 = (insn >> 0) & 0xf;
1670 rd1 = (insn >> 16) & 0xf;
1671 gen_op_iwmmxt_movq_M0_wRn(rd0);
1672 gen_op_iwmmxt_andq_M0_wRn(rd1);
1673 gen_op_iwmmxt_setpsr_nz();
1674 gen_op_iwmmxt_movq_wRn_M0(wrd);
1675 gen_op_iwmmxt_set_mup();
1676 gen_op_iwmmxt_set_cup();
1678 case 0x810: case 0xa10: /* WMADD */
1679 wrd = (insn >> 12) & 0xf;
1680 rd0 = (insn >> 0) & 0xf;
1681 rd1 = (insn >> 16) & 0xf;
1682 gen_op_iwmmxt_movq_M0_wRn(rd0);
1683 if (insn & (1 << 21))
1684 gen_op_iwmmxt_maddsq_M0_wRn(rd1);
1686 gen_op_iwmmxt_madduq_M0_wRn(rd1);
1687 gen_op_iwmmxt_movq_wRn_M0(wrd);
1688 gen_op_iwmmxt_set_mup();
1690 case 0x10e: case 0x50e: case 0x90e: case 0xd0e: /* WUNPCKIL */
1691 wrd = (insn >> 12) & 0xf;
1692 rd0 = (insn >> 16) & 0xf;
1693 rd1 = (insn >> 0) & 0xf;
1694 gen_op_iwmmxt_movq_M0_wRn(rd0);
1695 switch ((insn >> 22) & 3) {
1697 gen_op_iwmmxt_unpacklb_M0_wRn(rd1);
1700 gen_op_iwmmxt_unpacklw_M0_wRn(rd1);
1703 gen_op_iwmmxt_unpackll_M0_wRn(rd1);
1708 gen_op_iwmmxt_movq_wRn_M0(wrd);
1709 gen_op_iwmmxt_set_mup();
1710 gen_op_iwmmxt_set_cup();
1712 case 0x10c: case 0x50c: case 0x90c: case 0xd0c: /* WUNPCKIH */
1713 wrd = (insn >> 12) & 0xf;
1714 rd0 = (insn >> 16) & 0xf;
1715 rd1 = (insn >> 0) & 0xf;
1716 gen_op_iwmmxt_movq_M0_wRn(rd0);
1717 switch ((insn >> 22) & 3) {
1719 gen_op_iwmmxt_unpackhb_M0_wRn(rd1);
1722 gen_op_iwmmxt_unpackhw_M0_wRn(rd1);
1725 gen_op_iwmmxt_unpackhl_M0_wRn(rd1);
1730 gen_op_iwmmxt_movq_wRn_M0(wrd);
1731 gen_op_iwmmxt_set_mup();
1732 gen_op_iwmmxt_set_cup();
1734 case 0x012: case 0x112: case 0x412: case 0x512: /* WSAD */
1735 wrd = (insn >> 12) & 0xf;
1736 rd0 = (insn >> 16) & 0xf;
1737 rd1 = (insn >> 0) & 0xf;
1738 gen_op_iwmmxt_movq_M0_wRn(rd0);
1739 if (insn & (1 << 22))
1740 gen_op_iwmmxt_sadw_M0_wRn(rd1);
1742 gen_op_iwmmxt_sadb_M0_wRn(rd1);
1743 if (!(insn & (1 << 20)))
1744 gen_op_iwmmxt_addl_M0_wRn(wrd);
1745 gen_op_iwmmxt_movq_wRn_M0(wrd);
1746 gen_op_iwmmxt_set_mup();
1748 case 0x010: case 0x110: case 0x210: case 0x310: /* WMUL */
1749 wrd = (insn >> 12) & 0xf;
1750 rd0 = (insn >> 16) & 0xf;
1751 rd1 = (insn >> 0) & 0xf;
1752 gen_op_iwmmxt_movq_M0_wRn(rd0);
1753 if (insn & (1 << 21)) {
1754 if (insn & (1 << 20))
1755 gen_op_iwmmxt_mulshw_M0_wRn(rd1);
1757 gen_op_iwmmxt_mulslw_M0_wRn(rd1);
1759 if (insn & (1 << 20))
1760 gen_op_iwmmxt_muluhw_M0_wRn(rd1);
1762 gen_op_iwmmxt_mululw_M0_wRn(rd1);
1764 gen_op_iwmmxt_movq_wRn_M0(wrd);
1765 gen_op_iwmmxt_set_mup();
1767 case 0x410: case 0x510: case 0x610: case 0x710: /* WMAC */
1768 wrd = (insn >> 12) & 0xf;
1769 rd0 = (insn >> 16) & 0xf;
1770 rd1 = (insn >> 0) & 0xf;
1771 gen_op_iwmmxt_movq_M0_wRn(rd0);
1772 if (insn & (1 << 21))
1773 gen_op_iwmmxt_macsw_M0_wRn(rd1);
1775 gen_op_iwmmxt_macuw_M0_wRn(rd1);
1776 if (!(insn & (1 << 20))) {
1777 iwmmxt_load_reg(cpu_V1, wrd);
1778 tcg_gen_add_i64(cpu_M0, cpu_M0, cpu_V1);
1780 gen_op_iwmmxt_movq_wRn_M0(wrd);
1781 gen_op_iwmmxt_set_mup();
1783 case 0x006: case 0x406: case 0x806: case 0xc06: /* WCMPEQ */
1784 wrd = (insn >> 12) & 0xf;
1785 rd0 = (insn >> 16) & 0xf;
1786 rd1 = (insn >> 0) & 0xf;
1787 gen_op_iwmmxt_movq_M0_wRn(rd0);
1788 switch ((insn >> 22) & 3) {
1790 gen_op_iwmmxt_cmpeqb_M0_wRn(rd1);
1793 gen_op_iwmmxt_cmpeqw_M0_wRn(rd1);
1796 gen_op_iwmmxt_cmpeql_M0_wRn(rd1);
1801 gen_op_iwmmxt_movq_wRn_M0(wrd);
1802 gen_op_iwmmxt_set_mup();
1803 gen_op_iwmmxt_set_cup();
1805 case 0x800: case 0x900: case 0xc00: case 0xd00: /* WAVG2 */
1806 wrd = (insn >> 12) & 0xf;
1807 rd0 = (insn >> 16) & 0xf;
1808 rd1 = (insn >> 0) & 0xf;
1809 gen_op_iwmmxt_movq_M0_wRn(rd0);
1810 if (insn & (1 << 22)) {
1811 if (insn & (1 << 20))
1812 gen_op_iwmmxt_avgw1_M0_wRn(rd1);
1814 gen_op_iwmmxt_avgw0_M0_wRn(rd1);
1816 if (insn & (1 << 20))
1817 gen_op_iwmmxt_avgb1_M0_wRn(rd1);
1819 gen_op_iwmmxt_avgb0_M0_wRn(rd1);
1821 gen_op_iwmmxt_movq_wRn_M0(wrd);
1822 gen_op_iwmmxt_set_mup();
1823 gen_op_iwmmxt_set_cup();
1825 case 0x802: case 0x902: case 0xa02: case 0xb02: /* WALIGNR */
1826 wrd = (insn >> 12) & 0xf;
1827 rd0 = (insn >> 16) & 0xf;
1828 rd1 = (insn >> 0) & 0xf;
1829 gen_op_iwmmxt_movq_M0_wRn(rd0);
1830 gen_op_iwmmxt_movl_T0_wCx(ARM_IWMMXT_wCGR0 + ((insn >> 20) & 3));
1831 gen_op_movl_T1_im(7);
1832 gen_op_andl_T0_T1();
1833 gen_op_iwmmxt_align_M0_T0_wRn(rd1);
1834 gen_op_iwmmxt_movq_wRn_M0(wrd);
1835 gen_op_iwmmxt_set_mup();
1837 case 0x601: case 0x605: case 0x609: case 0x60d: /* TINSR */
1838 rd = (insn >> 12) & 0xf;
1839 wrd = (insn >> 16) & 0xf;
1840 gen_movl_T0_reg(s, rd);
1841 gen_op_iwmmxt_movq_M0_wRn(wrd);
1842 switch ((insn >> 6) & 3) {
1844 gen_op_movl_T1_im(0xff);
1845 gen_op_iwmmxt_insr_M0_T0_T1((insn & 7) << 3);
1848 gen_op_movl_T1_im(0xffff);
1849 gen_op_iwmmxt_insr_M0_T0_T1((insn & 3) << 4);
1852 gen_op_movl_T1_im(0xffffffff);
1853 gen_op_iwmmxt_insr_M0_T0_T1((insn & 1) << 5);
1858 gen_op_iwmmxt_movq_wRn_M0(wrd);
1859 gen_op_iwmmxt_set_mup();
1861 case 0x107: case 0x507: case 0x907: case 0xd07: /* TEXTRM */
1862 rd = (insn >> 12) & 0xf;
1863 wrd = (insn >> 16) & 0xf;
1866 gen_op_iwmmxt_movq_M0_wRn(wrd);
1867 switch ((insn >> 22) & 3) {
1870 gen_op_iwmmxt_extrsb_T0_M0((insn & 7) << 3);
1872 gen_op_iwmmxt_extru_T0_M0((insn & 7) << 3, 0xff);
1877 gen_op_iwmmxt_extrsw_T0_M0((insn & 3) << 4);
1879 gen_op_iwmmxt_extru_T0_M0((insn & 3) << 4, 0xffff);
1883 gen_op_iwmmxt_extru_T0_M0((insn & 1) << 5, ~0u);
1888 gen_movl_reg_T0(s, rd);
1890 case 0x117: case 0x517: case 0x917: case 0xd17: /* TEXTRC */
1891 if ((insn & 0x000ff008) != 0x0003f000)
1893 gen_op_iwmmxt_movl_T1_wCx(ARM_IWMMXT_wCASF);
1894 switch ((insn >> 22) & 3) {
1896 gen_op_shrl_T1_im(((insn & 7) << 2) + 0);
1899 gen_op_shrl_T1_im(((insn & 3) << 3) + 4);
1902 gen_op_shrl_T1_im(((insn & 1) << 4) + 12);
1907 gen_op_shll_T1_im(28);
1908 gen_set_nzcv(cpu_T[1]);
1910 case 0x401: case 0x405: case 0x409: case 0x40d: /* TBCST */
1911 rd = (insn >> 12) & 0xf;
1912 wrd = (insn >> 16) & 0xf;
1913 gen_movl_T0_reg(s, rd);
1914 switch ((insn >> 6) & 3) {
1916 gen_helper_iwmmxt_bcstb(cpu_M0, cpu_T[0]);
1919 gen_helper_iwmmxt_bcstw(cpu_M0, cpu_T[0]);
1922 gen_helper_iwmmxt_bcstl(cpu_M0, cpu_T[0]);
1927 gen_op_iwmmxt_movq_wRn_M0(wrd);
1928 gen_op_iwmmxt_set_mup();
1930 case 0x113: case 0x513: case 0x913: case 0xd13: /* TANDC */
1931 if ((insn & 0x000ff00f) != 0x0003f000)
1933 gen_op_iwmmxt_movl_T1_wCx(ARM_IWMMXT_wCASF);
1934 switch ((insn >> 22) & 3) {
1936 for (i = 0; i < 7; i ++) {
1937 gen_op_shll_T1_im(4);
1938 gen_op_andl_T0_T1();
1942 for (i = 0; i < 3; i ++) {
1943 gen_op_shll_T1_im(8);
1944 gen_op_andl_T0_T1();
1948 gen_op_shll_T1_im(16);
1949 gen_op_andl_T0_T1();
1954 gen_set_nzcv(cpu_T[0]);
1956 case 0x01c: case 0x41c: case 0x81c: case 0xc1c: /* WACC */
1957 wrd = (insn >> 12) & 0xf;
1958 rd0 = (insn >> 16) & 0xf;
1959 gen_op_iwmmxt_movq_M0_wRn(rd0);
1960 switch ((insn >> 22) & 3) {
1962 gen_helper_iwmmxt_addcb(cpu_M0, cpu_M0);
1965 gen_helper_iwmmxt_addcw(cpu_M0, cpu_M0);
1968 gen_helper_iwmmxt_addcl(cpu_M0, cpu_M0);
1973 gen_op_iwmmxt_movq_wRn_M0(wrd);
1974 gen_op_iwmmxt_set_mup();
1976 case 0x115: case 0x515: case 0x915: case 0xd15: /* TORC */
1977 if ((insn & 0x000ff00f) != 0x0003f000)
1979 gen_op_iwmmxt_movl_T1_wCx(ARM_IWMMXT_wCASF);
1980 switch ((insn >> 22) & 3) {
1982 for (i = 0; i < 7; i ++) {
1983 gen_op_shll_T1_im(4);
1988 for (i = 0; i < 3; i ++) {
1989 gen_op_shll_T1_im(8);
1994 gen_op_shll_T1_im(16);
2000 gen_set_nzcv(cpu_T[0]);
2002 case 0x103: case 0x503: case 0x903: case 0xd03: /* TMOVMSK */
2003 rd = (insn >> 12) & 0xf;
2004 rd0 = (insn >> 16) & 0xf;
2005 if ((insn & 0xf) != 0)
2007 gen_op_iwmmxt_movq_M0_wRn(rd0);
2008 switch ((insn >> 22) & 3) {
2010 gen_helper_iwmmxt_msbb(cpu_T[0], cpu_M0);
2013 gen_helper_iwmmxt_msbw(cpu_T[0], cpu_M0);
2016 gen_helper_iwmmxt_msbl(cpu_T[0], cpu_M0);
2021 gen_movl_reg_T0(s, rd);
2023 case 0x106: case 0x306: case 0x506: case 0x706: /* WCMPGT */
2024 case 0x906: case 0xb06: case 0xd06: case 0xf06:
2025 wrd = (insn >> 12) & 0xf;
2026 rd0 = (insn >> 16) & 0xf;
2027 rd1 = (insn >> 0) & 0xf;
2028 gen_op_iwmmxt_movq_M0_wRn(rd0);
2029 switch ((insn >> 22) & 3) {
2031 if (insn & (1 << 21))
2032 gen_op_iwmmxt_cmpgtsb_M0_wRn(rd1);
2034 gen_op_iwmmxt_cmpgtub_M0_wRn(rd1);
2037 if (insn & (1 << 21))
2038 gen_op_iwmmxt_cmpgtsw_M0_wRn(rd1);
2040 gen_op_iwmmxt_cmpgtuw_M0_wRn(rd1);
2043 if (insn & (1 << 21))
2044 gen_op_iwmmxt_cmpgtsl_M0_wRn(rd1);
2046 gen_op_iwmmxt_cmpgtul_M0_wRn(rd1);
2051 gen_op_iwmmxt_movq_wRn_M0(wrd);
2052 gen_op_iwmmxt_set_mup();
2053 gen_op_iwmmxt_set_cup();
2055 case 0x00e: case 0x20e: case 0x40e: case 0x60e: /* WUNPCKEL */
2056 case 0x80e: case 0xa0e: case 0xc0e: case 0xe0e:
2057 wrd = (insn >> 12) & 0xf;
2058 rd0 = (insn >> 16) & 0xf;
2059 gen_op_iwmmxt_movq_M0_wRn(rd0);
2060 switch ((insn >> 22) & 3) {
2062 if (insn & (1 << 21))
2063 gen_op_iwmmxt_unpacklsb_M0();
2065 gen_op_iwmmxt_unpacklub_M0();
2068 if (insn & (1 << 21))
2069 gen_op_iwmmxt_unpacklsw_M0();
2071 gen_op_iwmmxt_unpackluw_M0();
2074 if (insn & (1 << 21))
2075 gen_op_iwmmxt_unpacklsl_M0();
2077 gen_op_iwmmxt_unpacklul_M0();
2082 gen_op_iwmmxt_movq_wRn_M0(wrd);
2083 gen_op_iwmmxt_set_mup();
2084 gen_op_iwmmxt_set_cup();
2086 case 0x00c: case 0x20c: case 0x40c: case 0x60c: /* WUNPCKEH */
2087 case 0x80c: case 0xa0c: case 0xc0c: case 0xe0c:
2088 wrd = (insn >> 12) & 0xf;
2089 rd0 = (insn >> 16) & 0xf;
2090 gen_op_iwmmxt_movq_M0_wRn(rd0);
2091 switch ((insn >> 22) & 3) {
2093 if (insn & (1 << 21))
2094 gen_op_iwmmxt_unpackhsb_M0();
2096 gen_op_iwmmxt_unpackhub_M0();
2099 if (insn & (1 << 21))
2100 gen_op_iwmmxt_unpackhsw_M0();
2102 gen_op_iwmmxt_unpackhuw_M0();
2105 if (insn & (1 << 21))
2106 gen_op_iwmmxt_unpackhsl_M0();
2108 gen_op_iwmmxt_unpackhul_M0();
2113 gen_op_iwmmxt_movq_wRn_M0(wrd);
2114 gen_op_iwmmxt_set_mup();
2115 gen_op_iwmmxt_set_cup();
2117 case 0x204: case 0x604: case 0xa04: case 0xe04: /* WSRL */
2118 case 0x214: case 0x614: case 0xa14: case 0xe14:
2119 wrd = (insn >> 12) & 0xf;
2120 rd0 = (insn >> 16) & 0xf;
2121 gen_op_iwmmxt_movq_M0_wRn(rd0);
2122 if (gen_iwmmxt_shift(insn, 0xff))
2124 switch ((insn >> 22) & 3) {
2128 gen_helper_iwmmxt_srlw(cpu_M0, cpu_env, cpu_M0, cpu_T[0]);
2131 gen_helper_iwmmxt_srll(cpu_M0, cpu_env, cpu_M0, cpu_T[0]);
2134 gen_helper_iwmmxt_srlq(cpu_M0, cpu_env, cpu_M0, cpu_T[0]);
2137 gen_op_iwmmxt_movq_wRn_M0(wrd);
2138 gen_op_iwmmxt_set_mup();
2139 gen_op_iwmmxt_set_cup();
2141 case 0x004: case 0x404: case 0x804: case 0xc04: /* WSRA */
2142 case 0x014: case 0x414: case 0x814: case 0xc14:
2143 wrd = (insn >> 12) & 0xf;
2144 rd0 = (insn >> 16) & 0xf;
2145 gen_op_iwmmxt_movq_M0_wRn(rd0);
2146 if (gen_iwmmxt_shift(insn, 0xff))
2148 switch ((insn >> 22) & 3) {
2152 gen_helper_iwmmxt_sraw(cpu_M0, cpu_env, cpu_M0, cpu_T[0]);
2155 gen_helper_iwmmxt_sral(cpu_M0, cpu_env, cpu_M0, cpu_T[0]);
2158 gen_helper_iwmmxt_sraq(cpu_M0, cpu_env, cpu_M0, cpu_T[0]);
2161 gen_op_iwmmxt_movq_wRn_M0(wrd);
2162 gen_op_iwmmxt_set_mup();
2163 gen_op_iwmmxt_set_cup();
2165 case 0x104: case 0x504: case 0x904: case 0xd04: /* WSLL */
2166 case 0x114: case 0x514: case 0x914: case 0xd14:
2167 wrd = (insn >> 12) & 0xf;
2168 rd0 = (insn >> 16) & 0xf;
2169 gen_op_iwmmxt_movq_M0_wRn(rd0);
2170 if (gen_iwmmxt_shift(insn, 0xff))
2172 switch ((insn >> 22) & 3) {
2176 gen_helper_iwmmxt_sllw(cpu_M0, cpu_env, cpu_M0, cpu_T[0]);
2179 gen_helper_iwmmxt_slll(cpu_M0, cpu_env, cpu_M0, cpu_T[0]);
2182 gen_helper_iwmmxt_sllq(cpu_M0, cpu_env, cpu_M0, cpu_T[0]);
2185 gen_op_iwmmxt_movq_wRn_M0(wrd);
2186 gen_op_iwmmxt_set_mup();
2187 gen_op_iwmmxt_set_cup();
2189 case 0x304: case 0x704: case 0xb04: case 0xf04: /* WROR */
2190 case 0x314: case 0x714: case 0xb14: case 0xf14:
2191 wrd = (insn >> 12) & 0xf;
2192 rd0 = (insn >> 16) & 0xf;
2193 gen_op_iwmmxt_movq_M0_wRn(rd0);
2194 switch ((insn >> 22) & 3) {
2198 if (gen_iwmmxt_shift(insn, 0xf))
2200 gen_helper_iwmmxt_rorw(cpu_M0, cpu_env, cpu_M0, cpu_T[0]);
2203 if (gen_iwmmxt_shift(insn, 0x1f))
2205 gen_helper_iwmmxt_rorl(cpu_M0, cpu_env, cpu_M0, cpu_T[0]);
2208 if (gen_iwmmxt_shift(insn, 0x3f))
2210 gen_helper_iwmmxt_rorq(cpu_M0, cpu_env, cpu_M0, cpu_T[0]);
2213 gen_op_iwmmxt_movq_wRn_M0(wrd);
2214 gen_op_iwmmxt_set_mup();
2215 gen_op_iwmmxt_set_cup();
2217 case 0x116: case 0x316: case 0x516: case 0x716: /* WMIN */
2218 case 0x916: case 0xb16: case 0xd16: case 0xf16:
2219 wrd = (insn >> 12) & 0xf;
2220 rd0 = (insn >> 16) & 0xf;
2221 rd1 = (insn >> 0) & 0xf;
2222 gen_op_iwmmxt_movq_M0_wRn(rd0);
2223 switch ((insn >> 22) & 3) {
2225 if (insn & (1 << 21))
2226 gen_op_iwmmxt_minsb_M0_wRn(rd1);
2228 gen_op_iwmmxt_minub_M0_wRn(rd1);
2231 if (insn & (1 << 21))
2232 gen_op_iwmmxt_minsw_M0_wRn(rd1);
2234 gen_op_iwmmxt_minuw_M0_wRn(rd1);
2237 if (insn & (1 << 21))
2238 gen_op_iwmmxt_minsl_M0_wRn(rd1);
2240 gen_op_iwmmxt_minul_M0_wRn(rd1);
2245 gen_op_iwmmxt_movq_wRn_M0(wrd);
2246 gen_op_iwmmxt_set_mup();
2248 case 0x016: case 0x216: case 0x416: case 0x616: /* WMAX */
2249 case 0x816: case 0xa16: case 0xc16: case 0xe16:
2250 wrd = (insn >> 12) & 0xf;
2251 rd0 = (insn >> 16) & 0xf;
2252 rd1 = (insn >> 0) & 0xf;
2253 gen_op_iwmmxt_movq_M0_wRn(rd0);
2254 switch ((insn >> 22) & 3) {
2256 if (insn & (1 << 21))
2257 gen_op_iwmmxt_maxsb_M0_wRn(rd1);
2259 gen_op_iwmmxt_maxub_M0_wRn(rd1);
2262 if (insn & (1 << 21))
2263 gen_op_iwmmxt_maxsw_M0_wRn(rd1);
2265 gen_op_iwmmxt_maxuw_M0_wRn(rd1);
2268 if (insn & (1 << 21))
2269 gen_op_iwmmxt_maxsl_M0_wRn(rd1);
2271 gen_op_iwmmxt_maxul_M0_wRn(rd1);
2276 gen_op_iwmmxt_movq_wRn_M0(wrd);
2277 gen_op_iwmmxt_set_mup();
2279 case 0x002: case 0x102: case 0x202: case 0x302: /* WALIGNI */
2280 case 0x402: case 0x502: case 0x602: case 0x702:
2281 wrd = (insn >> 12) & 0xf;
2282 rd0 = (insn >> 16) & 0xf;
2283 rd1 = (insn >> 0) & 0xf;
2284 gen_op_iwmmxt_movq_M0_wRn(rd0);
2285 gen_op_movl_T0_im((insn >> 20) & 3);
2286 gen_op_iwmmxt_align_M0_T0_wRn(rd1);
2287 gen_op_iwmmxt_movq_wRn_M0(wrd);
2288 gen_op_iwmmxt_set_mup();
2290 case 0x01a: case 0x11a: case 0x21a: case 0x31a: /* WSUB */
2291 case 0x41a: case 0x51a: case 0x61a: case 0x71a:
2292 case 0x81a: case 0x91a: case 0xa1a: case 0xb1a:
2293 case 0xc1a: case 0xd1a: case 0xe1a: case 0xf1a:
2294 wrd = (insn >> 12) & 0xf;
2295 rd0 = (insn >> 16) & 0xf;
2296 rd1 = (insn >> 0) & 0xf;
2297 gen_op_iwmmxt_movq_M0_wRn(rd0);
2298 switch ((insn >> 20) & 0xf) {
2300 gen_op_iwmmxt_subnb_M0_wRn(rd1);
2303 gen_op_iwmmxt_subub_M0_wRn(rd1);
2306 gen_op_iwmmxt_subsb_M0_wRn(rd1);
2309 gen_op_iwmmxt_subnw_M0_wRn(rd1);
2312 gen_op_iwmmxt_subuw_M0_wRn(rd1);
2315 gen_op_iwmmxt_subsw_M0_wRn(rd1);
2318 gen_op_iwmmxt_subnl_M0_wRn(rd1);
2321 gen_op_iwmmxt_subul_M0_wRn(rd1);
2324 gen_op_iwmmxt_subsl_M0_wRn(rd1);
2329 gen_op_iwmmxt_movq_wRn_M0(wrd);
2330 gen_op_iwmmxt_set_mup();
2331 gen_op_iwmmxt_set_cup();
2333 case 0x01e: case 0x11e: case 0x21e: case 0x31e: /* WSHUFH */
2334 case 0x41e: case 0x51e: case 0x61e: case 0x71e:
2335 case 0x81e: case 0x91e: case 0xa1e: case 0xb1e:
2336 case 0xc1e: case 0xd1e: case 0xe1e: case 0xf1e:
2337 wrd = (insn >> 12) & 0xf;
2338 rd0 = (insn >> 16) & 0xf;
2339 gen_op_iwmmxt_movq_M0_wRn(rd0);
2340 gen_op_movl_T0_im(((insn >> 16) & 0xf0) | (insn & 0x0f));
2341 gen_helper_iwmmxt_shufh(cpu_M0, cpu_env, cpu_M0, cpu_T[0]);
2342 gen_op_iwmmxt_movq_wRn_M0(wrd);
2343 gen_op_iwmmxt_set_mup();
2344 gen_op_iwmmxt_set_cup();
2346 case 0x018: case 0x118: case 0x218: case 0x318: /* WADD */
2347 case 0x418: case 0x518: case 0x618: case 0x718:
2348 case 0x818: case 0x918: case 0xa18: case 0xb18:
2349 case 0xc18: case 0xd18: case 0xe18: case 0xf18:
2350 wrd = (insn >> 12) & 0xf;
2351 rd0 = (insn >> 16) & 0xf;
2352 rd1 = (insn >> 0) & 0xf;
2353 gen_op_iwmmxt_movq_M0_wRn(rd0);
2354 switch ((insn >> 20) & 0xf) {
2356 gen_op_iwmmxt_addnb_M0_wRn(rd1);
2359 gen_op_iwmmxt_addub_M0_wRn(rd1);
2362 gen_op_iwmmxt_addsb_M0_wRn(rd1);
2365 gen_op_iwmmxt_addnw_M0_wRn(rd1);
2368 gen_op_iwmmxt_adduw_M0_wRn(rd1);
2371 gen_op_iwmmxt_addsw_M0_wRn(rd1);
2374 gen_op_iwmmxt_addnl_M0_wRn(rd1);
2377 gen_op_iwmmxt_addul_M0_wRn(rd1);
2380 gen_op_iwmmxt_addsl_M0_wRn(rd1);
2385 gen_op_iwmmxt_movq_wRn_M0(wrd);
2386 gen_op_iwmmxt_set_mup();
2387 gen_op_iwmmxt_set_cup();
2389 case 0x008: case 0x108: case 0x208: case 0x308: /* WPACK */
2390 case 0x408: case 0x508: case 0x608: case 0x708:
2391 case 0x808: case 0x908: case 0xa08: case 0xb08:
2392 case 0xc08: case 0xd08: case 0xe08: case 0xf08:
2393 wrd = (insn >> 12) & 0xf;
2394 rd0 = (insn >> 16) & 0xf;
2395 rd1 = (insn >> 0) & 0xf;
2396 gen_op_iwmmxt_movq_M0_wRn(rd0);
2397 if (!(insn & (1 << 20)))
2399 switch ((insn >> 22) & 3) {
2403 if (insn & (1 << 21))
2404 gen_op_iwmmxt_packsw_M0_wRn(rd1);
2406 gen_op_iwmmxt_packuw_M0_wRn(rd1);
2409 if (insn & (1 << 21))
2410 gen_op_iwmmxt_packsl_M0_wRn(rd1);
2412 gen_op_iwmmxt_packul_M0_wRn(rd1);
2415 if (insn & (1 << 21))
2416 gen_op_iwmmxt_packsq_M0_wRn(rd1);
2418 gen_op_iwmmxt_packuq_M0_wRn(rd1);
2421 gen_op_iwmmxt_movq_wRn_M0(wrd);
2422 gen_op_iwmmxt_set_mup();
2423 gen_op_iwmmxt_set_cup();
2425 case 0x201: case 0x203: case 0x205: case 0x207:
2426 case 0x209: case 0x20b: case 0x20d: case 0x20f:
2427 case 0x211: case 0x213: case 0x215: case 0x217:
2428 case 0x219: case 0x21b: case 0x21d: case 0x21f:
2429 wrd = (insn >> 5) & 0xf;
2430 rd0 = (insn >> 12) & 0xf;
2431 rd1 = (insn >> 0) & 0xf;
2432 if (rd0 == 0xf || rd1 == 0xf)
2434 gen_op_iwmmxt_movq_M0_wRn(wrd);
2435 switch ((insn >> 16) & 0xf) {
2436 case 0x0: /* TMIA */
2437 gen_movl_T0_reg(s, rd0);
2438 gen_movl_T1_reg(s, rd1);
2439 gen_op_iwmmxt_muladdsl_M0_T0_T1();
2441 case 0x8: /* TMIAPH */
2442 gen_movl_T0_reg(s, rd0);
2443 gen_movl_T1_reg(s, rd1);
2444 gen_op_iwmmxt_muladdsw_M0_T0_T1();
2446 case 0xc: case 0xd: case 0xe: case 0xf: /* TMIAxy */
2447 gen_movl_T1_reg(s, rd0);
2448 if (insn & (1 << 16))
2449 gen_op_shrl_T1_im(16);
2450 gen_op_movl_T0_T1();
2451 gen_movl_T1_reg(s, rd1);
2452 if (insn & (1 << 17))
2453 gen_op_shrl_T1_im(16);
2454 gen_op_iwmmxt_muladdswl_M0_T0_T1();
2459 gen_op_iwmmxt_movq_wRn_M0(wrd);
2460 gen_op_iwmmxt_set_mup();
2469 /* Disassemble an XScale DSP instruction. Returns nonzero if an error occured
2470 (ie. an undefined instruction). */
2471 static int disas_dsp_insn(CPUState *env, DisasContext *s, uint32_t insn)
2473 int acc, rd0, rd1, rdhi, rdlo;
2475 if ((insn & 0x0ff00f10) == 0x0e200010) {
2476 /* Multiply with Internal Accumulate Format */
2477 rd0 = (insn >> 12) & 0xf;
2479 acc = (insn >> 5) & 7;
2484 switch ((insn >> 16) & 0xf) {
2486 gen_movl_T0_reg(s, rd0);
2487 gen_movl_T1_reg(s, rd1);
2488 gen_op_iwmmxt_muladdsl_M0_T0_T1();
2490 case 0x8: /* MIAPH */
2491 gen_movl_T0_reg(s, rd0);
2492 gen_movl_T1_reg(s, rd1);
2493 gen_op_iwmmxt_muladdsw_M0_T0_T1();
2495 case 0xc: /* MIABB */
2496 case 0xd: /* MIABT */
2497 case 0xe: /* MIATB */
2498 case 0xf: /* MIATT */
2499 gen_movl_T1_reg(s, rd0);
2500 if (insn & (1 << 16))
2501 gen_op_shrl_T1_im(16);
2502 gen_op_movl_T0_T1();
2503 gen_movl_T1_reg(s, rd1);
2504 if (insn & (1 << 17))
2505 gen_op_shrl_T1_im(16);
2506 gen_op_iwmmxt_muladdswl_M0_T0_T1();
2512 gen_op_iwmmxt_movq_wRn_M0(acc);
2516 if ((insn & 0x0fe00ff8) == 0x0c400000) {
2517 /* Internal Accumulator Access Format */
2518 rdhi = (insn >> 16) & 0xf;
2519 rdlo = (insn >> 12) & 0xf;
2525 if (insn & ARM_CP_RW_BIT) { /* MRA */
2526 gen_iwmmxt_movl_T0_T1_wRn(acc);
2527 gen_movl_reg_T0(s, rdlo);
2528 gen_op_movl_T0_im((1 << (40 - 32)) - 1);
2529 gen_op_andl_T0_T1();
2530 gen_movl_reg_T0(s, rdhi);
2532 gen_movl_T0_reg(s, rdlo);
2533 gen_movl_T1_reg(s, rdhi);
2534 gen_iwmmxt_movl_wRn_T0_T1(acc);
2542 /* Disassemble system coprocessor instruction. Return nonzero if
2543 instruction is not defined. */
2544 static int disas_cp_insn(CPUState *env, DisasContext *s, uint32_t insn)
2547 uint32_t rd = (insn >> 12) & 0xf;
2548 uint32_t cp = (insn >> 8) & 0xf;
2553 if (insn & ARM_CP_RW_BIT) {
2554 if (!env->cp[cp].cp_read)
2556 gen_set_pc_im(s->pc);
2558 gen_helper_get_cp(tmp, cpu_env, tcg_const_i32(insn));
2559 store_reg(s, rd, tmp);
2561 if (!env->cp[cp].cp_write)
2563 gen_set_pc_im(s->pc);
2564 tmp = load_reg(s, rd);
2565 gen_helper_set_cp(cpu_env, tcg_const_i32(insn), tmp);
2571 static int cp15_user_ok(uint32_t insn)
2573 int cpn = (insn >> 16) & 0xf;
2574 int cpm = insn & 0xf;
2575 int op = ((insn >> 5) & 7) | ((insn >> 18) & 0x38);
2577 if (cpn == 13 && cpm == 0) {
2579 if (op == 2 || (op == 3 && (insn & ARM_CP_RW_BIT)))
2583 /* ISB, DSB, DMB. */
2584 if ((cpm == 5 && op == 4)
2585 || (cpm == 10 && (op == 4 || op == 5)))
2591 /* Disassemble system coprocessor (cp15) instruction. Return nonzero if
2592 instruction is not defined. */
2593 static int disas_cp15_insn(CPUState *env, DisasContext *s, uint32_t insn)
2598 /* M profile cores use memory mapped registers instead of cp15. */
2599 if (arm_feature(env, ARM_FEATURE_M))
2602 if ((insn & (1 << 25)) == 0) {
2603 if (insn & (1 << 20)) {
2607 /* mcrr. Used for block cache operations, so implement as no-op. */
2610 if ((insn & (1 << 4)) == 0) {
2614 if (IS_USER(s) && !cp15_user_ok(insn)) {
2617 if ((insn & 0x0fff0fff) == 0x0e070f90
2618 || (insn & 0x0fff0fff) == 0x0e070f58) {
2619 /* Wait for interrupt. */
2620 gen_set_pc_im(s->pc);
2621 s->is_jmp = DISAS_WFI;
2624 rd = (insn >> 12) & 0xf;
2625 if (insn & ARM_CP_RW_BIT) {
2627 gen_helper_get_cp15(tmp, cpu_env, tcg_const_i32(insn));
2628 /* If the destination register is r15 then sets condition codes. */
2630 store_reg(s, rd, tmp);
2634 tmp = load_reg(s, rd);
2635 gen_helper_set_cp15(cpu_env, tcg_const_i32(insn), tmp);
2637 /* Normally we would always end the TB here, but Linux
2638 * arch/arm/mach-pxa/sleep.S expects two instructions following
2639 * an MMU enable to execute from cache. Imitate this behaviour. */
2640 if (!arm_feature(env, ARM_FEATURE_XSCALE) ||
2641 (insn & 0x0fff0fff) != 0x0e010f10)
2647 #define VFP_REG_SHR(x, n) (((n) > 0) ? (x) >> (n) : (x) << -(n))
2648 #define VFP_SREG(insn, bigbit, smallbit) \
2649 ((VFP_REG_SHR(insn, bigbit - 1) & 0x1e) | (((insn) >> (smallbit)) & 1))
2650 #define VFP_DREG(reg, insn, bigbit, smallbit) do { \
2651 if (arm_feature(env, ARM_FEATURE_VFP3)) { \
2652 reg = (((insn) >> (bigbit)) & 0x0f) \
2653 | (((insn) >> ((smallbit) - 4)) & 0x10); \
2655 if (insn & (1 << (smallbit))) \
2657 reg = ((insn) >> (bigbit)) & 0x0f; \
2660 #define VFP_SREG_D(insn) VFP_SREG(insn, 12, 22)
2661 #define VFP_DREG_D(reg, insn) VFP_DREG(reg, insn, 12, 22)
2662 #define VFP_SREG_N(insn) VFP_SREG(insn, 16, 7)
2663 #define VFP_DREG_N(reg, insn) VFP_DREG(reg, insn, 16, 7)
2664 #define VFP_SREG_M(insn) VFP_SREG(insn, 0, 5)
2665 #define VFP_DREG_M(reg, insn) VFP_DREG(reg, insn, 0, 5)
2667 /* Move between integer and VFP cores. */
2668 static TCGv gen_vfp_mrs(void)
2670 TCGv tmp = new_tmp();
2671 tcg_gen_mov_i32(tmp, cpu_F0s);
2675 static void gen_vfp_msr(TCGv tmp)
2677 tcg_gen_mov_i32(cpu_F0s, tmp);
2682 vfp_enabled(CPUState * env)
2684 return ((env->vfp.xregs[ARM_VFP_FPEXC] & (1 << 30)) != 0);
2687 static void gen_neon_dup_u8(TCGv var, int shift)
2689 TCGv tmp = new_tmp();
2691 tcg_gen_shri_i32(var, var, shift);
2692 tcg_gen_ext8u_i32(var, var);
2693 tcg_gen_shli_i32(tmp, var, 8);
2694 tcg_gen_or_i32(var, var, tmp);
2695 tcg_gen_shli_i32(tmp, var, 16);
2696 tcg_gen_or_i32(var, var, tmp);
2700 static void gen_neon_dup_low16(TCGv var)
2702 TCGv tmp = new_tmp();
2703 tcg_gen_ext16u_i32(var, var);
2704 tcg_gen_shli_i32(tmp, var, 16);
2705 tcg_gen_or_i32(var, var, tmp);
2709 static void gen_neon_dup_high16(TCGv var)
2711 TCGv tmp = new_tmp();
2712 tcg_gen_andi_i32(var, var, 0xffff0000);
2713 tcg_gen_shri_i32(tmp, var, 16);
2714 tcg_gen_or_i32(var, var, tmp);
2718 /* Disassemble a VFP instruction. Returns nonzero if an error occured
2719 (ie. an undefined instruction). */
2720 static int disas_vfp_insn(CPUState * env, DisasContext *s, uint32_t insn)
2722 uint32_t rd, rn, rm, op, i, n, offset, delta_d, delta_m, bank_mask;
2727 if (!arm_feature(env, ARM_FEATURE_VFP))
2730 if (!vfp_enabled(env)) {
2731 /* VFP disabled. Only allow fmxr/fmrx to/from some control regs. */
2732 if ((insn & 0x0fe00fff) != 0x0ee00a10)
2734 rn = (insn >> 16) & 0xf;
2735 if (rn != ARM_VFP_FPSID && rn != ARM_VFP_FPEXC
2736 && rn != ARM_VFP_MVFR1 && rn != ARM_VFP_MVFR0)
2739 dp = ((insn & 0xf00) == 0xb00);
2740 switch ((insn >> 24) & 0xf) {
2742 if (insn & (1 << 4)) {
2743 /* single register transfer */
2744 rd = (insn >> 12) & 0xf;
2749 VFP_DREG_N(rn, insn);
2752 if (insn & 0x00c00060
2753 && !arm_feature(env, ARM_FEATURE_NEON))
2756 pass = (insn >> 21) & 1;
2757 if (insn & (1 << 22)) {
2759 offset = ((insn >> 5) & 3) * 8;
2760 } else if (insn & (1 << 5)) {
2762 offset = (insn & (1 << 6)) ? 16 : 0;
2767 if (insn & ARM_CP_RW_BIT) {
2769 tmp = neon_load_reg(rn, pass);
2773 tcg_gen_shri_i32(tmp, tmp, offset);
2774 if (insn & (1 << 23))
2780 if (insn & (1 << 23)) {
2782 tcg_gen_shri_i32(tmp, tmp, 16);
2788 tcg_gen_sari_i32(tmp, tmp, 16);
2797 store_reg(s, rd, tmp);
2800 tmp = load_reg(s, rd);
2801 if (insn & (1 << 23)) {
2804 gen_neon_dup_u8(tmp, 0);
2805 } else if (size == 1) {
2806 gen_neon_dup_low16(tmp);
2808 for (n = 0; n <= pass * 2; n++) {
2810 tcg_gen_mov_i32(tmp2, tmp);
2811 neon_store_reg(rn, n, tmp2);
2813 neon_store_reg(rn, n, tmp);
2818 tmp2 = neon_load_reg(rn, pass);
2819 gen_bfi(tmp, tmp2, tmp, offset, 0xff);
2823 tmp2 = neon_load_reg(rn, pass);
2824 gen_bfi(tmp, tmp2, tmp, offset, 0xffff);
2830 neon_store_reg(rn, pass, tmp);
2834 if ((insn & 0x6f) != 0x00)
2836 rn = VFP_SREG_N(insn);
2837 if (insn & ARM_CP_RW_BIT) {
2839 if (insn & (1 << 21)) {
2840 /* system register */
2845 /* VFP2 allows access to FSID from userspace.
2846 VFP3 restricts all id registers to privileged
2849 && arm_feature(env, ARM_FEATURE_VFP3))
2851 tmp = load_cpu_field(vfp.xregs[rn]);
2856 tmp = load_cpu_field(vfp.xregs[rn]);
2858 case ARM_VFP_FPINST:
2859 case ARM_VFP_FPINST2:
2860 /* Not present in VFP3. */
2862 || arm_feature(env, ARM_FEATURE_VFP3))
2864 tmp = load_cpu_field(vfp.xregs[rn]);
2868 tmp = load_cpu_field(vfp.xregs[ARM_VFP_FPSCR]);
2869 tcg_gen_andi_i32(tmp, tmp, 0xf0000000);
2872 gen_helper_vfp_get_fpscr(tmp, cpu_env);
2878 || !arm_feature(env, ARM_FEATURE_VFP3))
2880 tmp = load_cpu_field(vfp.xregs[rn]);
2886 gen_mov_F0_vreg(0, rn);
2887 tmp = gen_vfp_mrs();
2890 /* Set the 4 flag bits in the CPSR. */
2894 store_reg(s, rd, tmp);
2898 tmp = load_reg(s, rd);
2899 if (insn & (1 << 21)) {
2901 /* system register */
2906 /* Writes are ignored. */
2909 gen_helper_vfp_set_fpscr(cpu_env, tmp);
2916 store_cpu_field(tmp, vfp.xregs[rn]);
2919 case ARM_VFP_FPINST:
2920 case ARM_VFP_FPINST2:
2921 store_cpu_field(tmp, vfp.xregs[rn]);
2928 gen_mov_vreg_F0(0, rn);
2933 /* data processing */
2934 /* The opcode is in bits 23, 21, 20 and 6. */
2935 op = ((insn >> 20) & 8) | ((insn >> 19) & 6) | ((insn >> 6) & 1);
2939 rn = ((insn >> 15) & 0x1e) | ((insn >> 7) & 1);
2941 /* rn is register number */
2942 VFP_DREG_N(rn, insn);
2945 if (op == 15 && (rn == 15 || rn > 17)) {
2946 /* Integer or single precision destination. */
2947 rd = VFP_SREG_D(insn);
2949 VFP_DREG_D(rd, insn);
2952 if (op == 15 && (rn == 16 || rn == 17)) {
2953 /* Integer source. */
2954 rm = ((insn << 1) & 0x1e) | ((insn >> 5) & 1);
2956 VFP_DREG_M(rm, insn);
2959 rn = VFP_SREG_N(insn);
2960 if (op == 15 && rn == 15) {
2961 /* Double precision destination. */
2962 VFP_DREG_D(rd, insn);
2964 rd = VFP_SREG_D(insn);
2966 rm = VFP_SREG_M(insn);
2969 veclen = env->vfp.vec_len;
2970 if (op == 15 && rn > 3)
2973 /* Shut up compiler warnings. */
2984 /* Figure out what type of vector operation this is. */
2985 if ((rd & bank_mask) == 0) {
2990 delta_d = (env->vfp.vec_stride >> 1) + 1;
2992 delta_d = env->vfp.vec_stride + 1;
2994 if ((rm & bank_mask) == 0) {
2995 /* mixed scalar/vector */
3004 /* Load the initial operands. */
3009 /* Integer source */
3010 gen_mov_F0_vreg(0, rm);
3015 gen_mov_F0_vreg(dp, rd);
3016 gen_mov_F1_vreg(dp, rm);
3020 /* Compare with zero */
3021 gen_mov_F0_vreg(dp, rd);
3032 /* Source and destination the same. */
3033 gen_mov_F0_vreg(dp, rd);
3036 /* One source operand. */
3037 gen_mov_F0_vreg(dp, rm);
3041 /* Two source operands. */
3042 gen_mov_F0_vreg(dp, rn);
3043 gen_mov_F1_vreg(dp, rm);
3047 /* Perform the calculation. */
3049 case 0: /* mac: fd + (fn * fm) */
3051 gen_mov_F1_vreg(dp, rd);
3054 case 1: /* nmac: fd - (fn * fm) */
3057 gen_mov_F1_vreg(dp, rd);
3060 case 2: /* msc: -fd + (fn * fm) */
3062 gen_mov_F1_vreg(dp, rd);
3065 case 3: /* nmsc: -fd - (fn * fm) */
3068 gen_mov_F1_vreg(dp, rd);
3071 case 4: /* mul: fn * fm */
3074 case 5: /* nmul: -(fn * fm) */
3078 case 6: /* add: fn + fm */
3081 case 7: /* sub: fn - fm */
3084 case 8: /* div: fn / fm */
3087 case 14: /* fconst */
3088 if (!arm_feature(env, ARM_FEATURE_VFP3))
3091 n = (insn << 12) & 0x80000000;
3092 i = ((insn >> 12) & 0x70) | (insn & 0xf);
3099 tcg_gen_movi_i64(cpu_F0d, ((uint64_t)n) << 32);
3106 tcg_gen_movi_i32(cpu_F0s, n);
3109 case 15: /* extension space */
3132 case 11: /* cmpez */
3136 case 15: /* single<->double conversion */
3138 gen_helper_vfp_fcvtsd(cpu_F0s, cpu_F0d, cpu_env);
3140 gen_helper_vfp_fcvtds(cpu_F0d, cpu_F0s, cpu_env);
3142 case 16: /* fuito */
3145 case 17: /* fsito */
3148 case 20: /* fshto */
3149 if (!arm_feature(env, ARM_FEATURE_VFP3))
3151 gen_vfp_shto(dp, 16 - rm);
3153 case 21: /* fslto */
3154 if (!arm_feature(env, ARM_FEATURE_VFP3))
3156 gen_vfp_slto(dp, 32 - rm);
3158 case 22: /* fuhto */
3159 if (!arm_feature(env, ARM_FEATURE_VFP3))
3161 gen_vfp_uhto(dp, 16 - rm);
3163 case 23: /* fulto */
3164 if (!arm_feature(env, ARM_FEATURE_VFP3))
3166 gen_vfp_ulto(dp, 32 - rm);
3168 case 24: /* ftoui */
3171 case 25: /* ftouiz */
3174 case 26: /* ftosi */
3177 case 27: /* ftosiz */
3180 case 28: /* ftosh */
3181 if (!arm_feature(env, ARM_FEATURE_VFP3))
3183 gen_vfp_tosh(dp, 16 - rm);
3185 case 29: /* ftosl */
3186 if (!arm_feature(env, ARM_FEATURE_VFP3))
3188 gen_vfp_tosl(dp, 32 - rm);
3190 case 30: /* ftouh */
3191 if (!arm_feature(env, ARM_FEATURE_VFP3))
3193 gen_vfp_touh(dp, 16 - rm);
3195 case 31: /* ftoul */
3196 if (!arm_feature(env, ARM_FEATURE_VFP3))
3198 gen_vfp_toul(dp, 32 - rm);
3200 default: /* undefined */
3201 printf ("rn:%d\n", rn);
3205 default: /* undefined */
3206 printf ("op:%d\n", op);
3210 /* Write back the result. */
3211 if (op == 15 && (rn >= 8 && rn <= 11))
3212 ; /* Comparison, do nothing. */
3213 else if (op == 15 && rn > 17)
3214 /* Integer result. */
3215 gen_mov_vreg_F0(0, rd);
3216 else if (op == 15 && rn == 15)
3218 gen_mov_vreg_F0(!dp, rd);
3220 gen_mov_vreg_F0(dp, rd);
3222 /* break out of the loop if we have finished */
3226 if (op == 15 && delta_m == 0) {
3227 /* single source one-many */
3229 rd = ((rd + delta_d) & (bank_mask - 1))
3231 gen_mov_vreg_F0(dp, rd);
3235 /* Setup the next operands. */
3237 rd = ((rd + delta_d) & (bank_mask - 1))
3241 /* One source operand. */
3242 rm = ((rm + delta_m) & (bank_mask - 1))
3244 gen_mov_F0_vreg(dp, rm);
3246 /* Two source operands. */
3247 rn = ((rn + delta_d) & (bank_mask - 1))
3249 gen_mov_F0_vreg(dp, rn);
3251 rm = ((rm + delta_m) & (bank_mask - 1))
3253 gen_mov_F1_vreg(dp, rm);
3261 if (dp && (insn & 0x03e00000) == 0x00400000) {
3262 /* two-register transfer */
3263 rn = (insn >> 16) & 0xf;
3264 rd = (insn >> 12) & 0xf;
3266 VFP_DREG_M(rm, insn);
3268 rm = VFP_SREG_M(insn);
3271 if (insn & ARM_CP_RW_BIT) {
3274 gen_mov_F0_vreg(0, rm * 2);
3275 tmp = gen_vfp_mrs();
3276 store_reg(s, rd, tmp);
3277 gen_mov_F0_vreg(0, rm * 2 + 1);
3278 tmp = gen_vfp_mrs();
3279 store_reg(s, rn, tmp);
3281 gen_mov_F0_vreg(0, rm);
3282 tmp = gen_vfp_mrs();
3283 store_reg(s, rn, tmp);
3284 gen_mov_F0_vreg(0, rm + 1);
3285 tmp = gen_vfp_mrs();
3286 store_reg(s, rd, tmp);
3291 tmp = load_reg(s, rd);
3293 gen_mov_vreg_F0(0, rm * 2);
3294 tmp = load_reg(s, rn);
3296 gen_mov_vreg_F0(0, rm * 2 + 1);
3298 tmp = load_reg(s, rn);
3300 gen_mov_vreg_F0(0, rm);
3301 tmp = load_reg(s, rd);
3303 gen_mov_vreg_F0(0, rm + 1);
3308 rn = (insn >> 16) & 0xf;
3310 VFP_DREG_D(rd, insn);
3312 rd = VFP_SREG_D(insn);
3313 if (s->thumb && rn == 15) {
3314 gen_op_movl_T1_im(s->pc & ~2);
3316 gen_movl_T1_reg(s, rn);
3318 if ((insn & 0x01200000) == 0x01000000) {
3319 /* Single load/store */
3320 offset = (insn & 0xff) << 2;
3321 if ((insn & (1 << 23)) == 0)
3323 gen_op_addl_T1_im(offset);
3324 if (insn & (1 << 20)) {
3326 gen_mov_vreg_F0(dp, rd);
3328 gen_mov_F0_vreg(dp, rd);
3332 /* load/store multiple */
3334 n = (insn >> 1) & 0x7f;
3338 if (insn & (1 << 24)) /* pre-decrement */
3339 gen_op_addl_T1_im(-((insn & 0xff) << 2));
3345 for (i = 0; i < n; i++) {
3346 if (insn & ARM_CP_RW_BIT) {
3349 gen_mov_vreg_F0(dp, rd + i);
3352 gen_mov_F0_vreg(dp, rd + i);
3355 gen_op_addl_T1_im(offset);
3357 if (insn & (1 << 21)) {
3359 if (insn & (1 << 24))
3360 offset = -offset * n;
3361 else if (dp && (insn & 1))
3367 gen_op_addl_T1_im(offset);
3368 gen_movl_reg_T1(s, rn);
3374 /* Should never happen. */
3380 static inline void gen_goto_tb(DisasContext *s, int n, uint32_t dest)
3382 TranslationBlock *tb;
3385 if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK)) {
3387 gen_set_pc_im(dest);
3388 tcg_gen_exit_tb((long)tb + n);
3390 gen_set_pc_im(dest);
3395 static inline void gen_jmp (DisasContext *s, uint32_t dest)
3397 if (unlikely(s->singlestep_enabled)) {
3398 /* An indirect jump so that we still trigger the debug exception. */
3403 gen_goto_tb(s, 0, dest);
3404 s->is_jmp = DISAS_TB_JUMP;
3408 static inline void gen_mulxy(TCGv t0, TCGv t1, int x, int y)
3411 tcg_gen_sari_i32(t0, t0, 16);
3415 tcg_gen_sari_i32(t1, t1, 16);
3418 tcg_gen_mul_i32(t0, t0, t1);
3421 /* Return the mask of PSR bits set by a MSR instruction. */
3422 static uint32_t msr_mask(CPUState *env, DisasContext *s, int flags, int spsr) {
3426 if (flags & (1 << 0))
3428 if (flags & (1 << 1))
3430 if (flags & (1 << 2))
3432 if (flags & (1 << 3))
3435 /* Mask out undefined bits. */
3436 mask &= ~CPSR_RESERVED;
3437 if (!arm_feature(env, ARM_FEATURE_V6))
3438 mask &= ~(CPSR_E | CPSR_GE);
3439 if (!arm_feature(env, ARM_FEATURE_THUMB2))
3441 /* Mask out execution state bits. */
3444 /* Mask out privileged bits. */
3450 /* Returns nonzero if access to the PSR is not permitted. */
3451 static int gen_set_psr_T0(DisasContext *s, uint32_t mask, int spsr)
3455 /* ??? This is also undefined in system mode. */
3459 tmp = load_cpu_field(spsr);
3460 tcg_gen_andi_i32(tmp, tmp, ~mask);
3461 tcg_gen_andi_i32(cpu_T[0], cpu_T[0], mask);
3462 tcg_gen_or_i32(tmp, tmp, cpu_T[0]);
3463 store_cpu_field(tmp, spsr);
3465 gen_set_cpsr(cpu_T[0], mask);
3471 /* Generate an old-style exception return. Marks pc as dead. */
3472 static void gen_exception_return(DisasContext *s, TCGv pc)
3475 store_reg(s, 15, pc);
3476 tmp = load_cpu_field(spsr);
3477 gen_set_cpsr(tmp, 0xffffffff);
3479 s->is_jmp = DISAS_UPDATE;
3482 /* Generate a v6 exception return. Marks both values as dead. */
3483 static void gen_rfe(DisasContext *s, TCGv pc, TCGv cpsr)
3485 gen_set_cpsr(cpsr, 0xffffffff);
3487 store_reg(s, 15, pc);
3488 s->is_jmp = DISAS_UPDATE;
3492 gen_set_condexec (DisasContext *s)
3494 if (s->condexec_mask) {
3495 uint32_t val = (s->condexec_cond << 4) | (s->condexec_mask >> 1);
3496 TCGv tmp = new_tmp();
3497 tcg_gen_movi_i32(tmp, val);
3498 store_cpu_field(tmp, condexec_bits);
3502 static void gen_nop_hint(DisasContext *s, int val)
3506 gen_set_pc_im(s->pc);
3507 s->is_jmp = DISAS_WFI;
3511 /* TODO: Implement SEV and WFE. May help SMP performance. */
3517 /* These macros help make the code more readable when migrating from the
3518 old dyngen helpers. They should probably be removed when
3519 T0/T1 are removed. */
3520 #define CPU_T001 cpu_T[0], cpu_T[0], cpu_T[1]
3521 #define CPU_T0E01 cpu_T[0], cpu_env, cpu_T[0], cpu_T[1]
3523 #define CPU_V001 cpu_V0, cpu_V0, cpu_V1
3525 static inline int gen_neon_add(int size)
3528 case 0: gen_helper_neon_add_u8(CPU_T001); break;
3529 case 1: gen_helper_neon_add_u16(CPU_T001); break;
3530 case 2: gen_op_addl_T0_T1(); break;
3536 static inline void gen_neon_rsb(int size)
3539 case 0: gen_helper_neon_sub_u8(cpu_T[0], cpu_T[1], cpu_T[0]); break;
3540 case 1: gen_helper_neon_sub_u16(cpu_T[0], cpu_T[1], cpu_T[0]); break;
3541 case 2: gen_op_rsbl_T0_T1(); break;
3546 /* 32-bit pairwise ops end up the same as the elementwise versions. */
3547 #define gen_helper_neon_pmax_s32 gen_helper_neon_max_s32
3548 #define gen_helper_neon_pmax_u32 gen_helper_neon_max_u32
3549 #define gen_helper_neon_pmin_s32 gen_helper_neon_min_s32
3550 #define gen_helper_neon_pmin_u32 gen_helper_neon_min_u32
3552 /* FIXME: This is wrong. They set the wrong overflow bit. */
3553 #define gen_helper_neon_qadd_s32(a, e, b, c) gen_helper_add_saturate(a, b, c)
3554 #define gen_helper_neon_qadd_u32(a, e, b, c) gen_helper_add_usaturate(a, b, c)
3555 #define gen_helper_neon_qsub_s32(a, e, b, c) gen_helper_sub_saturate(a, b, c)
3556 #define gen_helper_neon_qsub_u32(a, e, b, c) gen_helper_sub_usaturate(a, b, c)
3558 #define GEN_NEON_INTEGER_OP_ENV(name) do { \
3559 switch ((size << 1) | u) { \
3561 gen_helper_neon_##name##_s8(cpu_T[0], cpu_env, cpu_T[0], cpu_T[1]); \
3564 gen_helper_neon_##name##_u8(cpu_T[0], cpu_env, cpu_T[0], cpu_T[1]); \
3567 gen_helper_neon_##name##_s16(cpu_T[0], cpu_env, cpu_T[0], cpu_T[1]); \
3570 gen_helper_neon_##name##_u16(cpu_T[0], cpu_env, cpu_T[0], cpu_T[1]); \
3573 gen_helper_neon_##name##_s32(cpu_T[0], cpu_env, cpu_T[0], cpu_T[1]); \
3576 gen_helper_neon_##name##_u32(cpu_T[0], cpu_env, cpu_T[0], cpu_T[1]); \
3578 default: return 1; \
3581 #define GEN_NEON_INTEGER_OP(name) do { \
3582 switch ((size << 1) | u) { \
3584 gen_helper_neon_##name##_s8(cpu_T[0], cpu_T[0], cpu_T[1]); \
3587 gen_helper_neon_##name##_u8(cpu_T[0], cpu_T[0], cpu_T[1]); \
3590 gen_helper_neon_##name##_s16(cpu_T[0], cpu_T[0], cpu_T[1]); \
3593 gen_helper_neon_##name##_u16(cpu_T[0], cpu_T[0], cpu_T[1]); \
3596 gen_helper_neon_##name##_s32(cpu_T[0], cpu_T[0], cpu_T[1]); \
3599 gen_helper_neon_##name##_u32(cpu_T[0], cpu_T[0], cpu_T[1]); \
3601 default: return 1; \
3605 gen_neon_movl_scratch_T0(int scratch)
3609 offset = offsetof(CPUARMState, vfp.scratch[scratch]);
3610 tcg_gen_st_i32(cpu_T[0], cpu_env, offset);
3614 gen_neon_movl_scratch_T1(int scratch)
3618 offset = offsetof(CPUARMState, vfp.scratch[scratch]);
3619 tcg_gen_st_i32(cpu_T[1], cpu_env, offset);
3623 gen_neon_movl_T0_scratch(int scratch)
3627 offset = offsetof(CPUARMState, vfp.scratch[scratch]);
3628 tcg_gen_ld_i32(cpu_T[0], cpu_env, offset);
3632 gen_neon_movl_T1_scratch(int scratch)
3636 offset = offsetof(CPUARMState, vfp.scratch[scratch]);
3637 tcg_gen_ld_i32(cpu_T[1], cpu_env, offset);
3640 static inline void gen_neon_get_scalar(int size, int reg)
3643 NEON_GET_REG(T0, reg >> 1, reg & 1);
3645 NEON_GET_REG(T0, reg >> 2, (reg >> 1) & 1);
3647 gen_neon_dup_low16(cpu_T[0]);
3649 gen_neon_dup_high16(cpu_T[0]);
3653 static void gen_neon_unzip(int reg, int q, int tmp, int size)
3657 for (n = 0; n < q + 1; n += 2) {
3658 NEON_GET_REG(T0, reg, n);
3659 NEON_GET_REG(T0, reg, n + n);
3661 case 0: gen_helper_neon_unzip_u8(); break;
3662 case 1: gen_helper_neon_zip_u16(); break; /* zip and unzip are the same. */
3663 case 2: /* no-op */; break;
3666 gen_neon_movl_scratch_T0(tmp + n);
3667 gen_neon_movl_scratch_T1(tmp + n + 1);
3675 } neon_ls_element_type[11] = {
3689 /* Translate a NEON load/store element instruction. Return nonzero if the
3690 instruction is invalid. */
3691 static int disas_neon_ls_insn(CPUState * env, DisasContext *s, uint32_t insn)
3707 if (!vfp_enabled(env))
3709 VFP_DREG_D(rd, insn);
3710 rn = (insn >> 16) & 0xf;
3712 load = (insn & (1 << 21)) != 0;
3713 if ((insn & (1 << 23)) == 0) {
3714 /* Load store all elements. */
3715 op = (insn >> 8) & 0xf;
3716 size = (insn >> 6) & 3;
3717 if (op > 10 || size == 3)
3719 nregs = neon_ls_element_type[op].nregs;
3720 interleave = neon_ls_element_type[op].interleave;
3721 gen_movl_T1_reg(s, rn);
3722 stride = (1 << size) * interleave;
3723 for (reg = 0; reg < nregs; reg++) {
3724 if (interleave > 2 || (interleave == 2 && nregs == 2)) {
3725 gen_movl_T1_reg(s, rn);
3726 gen_op_addl_T1_im((1 << size) * reg);
3727 } else if (interleave == 2 && nregs == 4 && reg == 2) {
3728 gen_movl_T1_reg(s, rn);
3729 gen_op_addl_T1_im(1 << size);
3731 for (pass = 0; pass < 2; pass++) {
3734 tmp = gen_ld32(cpu_T[1], IS_USER(s));
3735 neon_store_reg(rd, pass, tmp);
3737 tmp = neon_load_reg(rd, pass);
3738 gen_st32(tmp, cpu_T[1], IS_USER(s));
3740 gen_op_addl_T1_im(stride);
3741 } else if (size == 1) {
3743 tmp = gen_ld16u(cpu_T[1], IS_USER(s));
3744 gen_op_addl_T1_im(stride);
3745 tmp2 = gen_ld16u(cpu_T[1], IS_USER(s));
3746 gen_op_addl_T1_im(stride);
3747 gen_bfi(tmp, tmp, tmp2, 16, 0xffff);
3749 neon_store_reg(rd, pass, tmp);
3751 tmp = neon_load_reg(rd, pass);
3753 tcg_gen_shri_i32(tmp2, tmp, 16);
3754 gen_st16(tmp, cpu_T[1], IS_USER(s));
3755 gen_op_addl_T1_im(stride);
3756 gen_st16(tmp2, cpu_T[1], IS_USER(s));
3757 gen_op_addl_T1_im(stride);
3759 } else /* size == 0 */ {
3762 for (n = 0; n < 4; n++) {
3763 tmp = gen_ld8u(cpu_T[1], IS_USER(s));
3764 gen_op_addl_T1_im(stride);
3768 gen_bfi(tmp2, tmp2, tmp, n * 8, 0xff);
3772 neon_store_reg(rd, pass, tmp2);
3774 tmp2 = neon_load_reg(rd, pass);
3775 for (n = 0; n < 4; n++) {
3778 tcg_gen_mov_i32(tmp, tmp2);
3780 tcg_gen_shri_i32(tmp, tmp2, n * 8);
3782 gen_st8(tmp, cpu_T[1], IS_USER(s));
3783 gen_op_addl_T1_im(stride);
3789 rd += neon_ls_element_type[op].spacing;
3793 size = (insn >> 10) & 3;
3795 /* Load single element to all lanes. */
3798 size = (insn >> 6) & 3;
3799 nregs = ((insn >> 8) & 3) + 1;
3800 stride = (insn & (1 << 5)) ? 2 : 1;
3801 gen_movl_T1_reg(s, rn);
3802 for (reg = 0; reg < nregs; reg++) {
3805 tmp = gen_ld8u(cpu_T[1], IS_USER(s));
3806 gen_neon_dup_u8(tmp, 0);
3809 tmp = gen_ld16u(cpu_T[1], IS_USER(s));
3810 gen_neon_dup_low16(tmp);
3813 tmp = gen_ld32(cpu_T[0], IS_USER(s));
3817 default: /* Avoid compiler warnings. */
3820 gen_op_addl_T1_im(1 << size);
3822 tcg_gen_mov_i32(tmp2, tmp);
3823 neon_store_reg(rd, 0, tmp2);
3824 neon_store_reg(rd, 1, tmp);
3827 stride = (1 << size) * nregs;
3829 /* Single element. */
3830 pass = (insn >> 7) & 1;
3833 shift = ((insn >> 5) & 3) * 8;
3837 shift = ((insn >> 6) & 1) * 16;
3838 stride = (insn & (1 << 5)) ? 2 : 1;
3842 stride = (insn & (1 << 6)) ? 2 : 1;
3847 nregs = ((insn >> 8) & 3) + 1;
3848 gen_movl_T1_reg(s, rn);
3849 for (reg = 0; reg < nregs; reg++) {
3853 tmp = gen_ld8u(cpu_T[1], IS_USER(s));
3856 tmp = gen_ld16u(cpu_T[1], IS_USER(s));
3859 tmp = gen_ld32(cpu_T[1], IS_USER(s));
3861 default: /* Avoid compiler warnings. */
3865 tmp2 = neon_load_reg(rd, pass);
3866 gen_bfi(tmp, tmp2, tmp, shift, size ? 0xffff : 0xff);
3869 neon_store_reg(rd, pass, tmp);
3870 } else { /* Store */
3871 tmp = neon_load_reg(rd, pass);
3873 tcg_gen_shri_i32(tmp, tmp, shift);
3876 gen_st8(tmp, cpu_T[1], IS_USER(s));
3879 gen_st16(tmp, cpu_T[1], IS_USER(s));
3882 gen_st32(tmp, cpu_T[1], IS_USER(s));
3887 gen_op_addl_T1_im(1 << size);
3889 stride = nregs * (1 << size);
3895 base = load_reg(s, rn);
3897 tcg_gen_addi_i32(base, base, stride);
3900 index = load_reg(s, rm);
3901 tcg_gen_add_i32(base, base, index);
3904 store_reg(s, rn, base);
3909 /* Bitwise select. dest = c ? t : f. Clobbers T and F. */
3910 static void gen_neon_bsl(TCGv dest, TCGv t, TCGv f, TCGv c)
3912 tcg_gen_and_i32(t, t, c);
3913 tcg_gen_bic_i32(f, f, c);
3914 tcg_gen_or_i32(dest, t, f);
3917 static inline void gen_neon_narrow(int size, TCGv dest, TCGv_i64 src)
3920 case 0: gen_helper_neon_narrow_u8(dest, src); break;
3921 case 1: gen_helper_neon_narrow_u16(dest, src); break;
3922 case 2: tcg_gen_trunc_i64_i32(dest, src); break;
3927 static inline void gen_neon_narrow_sats(int size, TCGv dest, TCGv_i64 src)
3930 case 0: gen_helper_neon_narrow_sat_s8(dest, cpu_env, src); break;
3931 case 1: gen_helper_neon_narrow_sat_s16(dest, cpu_env, src); break;
3932 case 2: gen_helper_neon_narrow_sat_s32(dest, cpu_env, src); break;
3937 static inline void gen_neon_narrow_satu(int size, TCGv dest, TCGv_i64 src)
3940 case 0: gen_helper_neon_narrow_sat_u8(dest, cpu_env, src); break;
3941 case 1: gen_helper_neon_narrow_sat_u16(dest, cpu_env, src); break;
3942 case 2: gen_helper_neon_narrow_sat_u32(dest, cpu_env, src); break;
3947 static inline void gen_neon_shift_narrow(int size, TCGv var, TCGv shift,
3953 case 1: gen_helper_neon_rshl_u16(var, var, shift); break;
3954 case 2: gen_helper_neon_rshl_u32(var, var, shift); break;
3959 case 1: gen_helper_neon_rshl_s16(var, var, shift); break;
3960 case 2: gen_helper_neon_rshl_s32(var, var, shift); break;
3967 case 1: gen_helper_neon_rshl_u16(var, var, shift); break;
3968 case 2: gen_helper_neon_rshl_u32(var, var, shift); break;
3973 case 1: gen_helper_neon_shl_s16(var, var, shift); break;
3974 case 2: gen_helper_neon_shl_s32(var, var, shift); break;
3981 static inline void gen_neon_widen(TCGv_i64 dest, TCGv src, int size, int u)
3985 case 0: gen_helper_neon_widen_u8(dest, src); break;
3986 case 1: gen_helper_neon_widen_u16(dest, src); break;
3987 case 2: tcg_gen_extu_i32_i64(dest, src); break;
3992 case 0: gen_helper_neon_widen_s8(dest, src); break;
3993 case 1: gen_helper_neon_widen_s16(dest, src); break;
3994 case 2: tcg_gen_ext_i32_i64(dest, src); break;
4001 static inline void gen_neon_addl(int size)
4004 case 0: gen_helper_neon_addl_u16(CPU_V001); break;
4005 case 1: gen_helper_neon_addl_u32(CPU_V001); break;
4006 case 2: tcg_gen_add_i64(CPU_V001); break;
4011 static inline void gen_neon_subl(int size)
4014 case 0: gen_helper_neon_subl_u16(CPU_V001); break;
4015 case 1: gen_helper_neon_subl_u32(CPU_V001); break;
4016 case 2: tcg_gen_sub_i64(CPU_V001); break;
4021 static inline void gen_neon_negl(TCGv_i64 var, int size)
4024 case 0: gen_helper_neon_negl_u16(var, var); break;
4025 case 1: gen_helper_neon_negl_u32(var, var); break;
4026 case 2: gen_helper_neon_negl_u64(var, var); break;
4031 static inline void gen_neon_addl_saturate(TCGv_i64 op0, TCGv_i64 op1, int size)
4034 case 1: gen_helper_neon_addl_saturate_s32(op0, cpu_env, op0, op1); break;
4035 case 2: gen_helper_neon_addl_saturate_s64(op0, cpu_env, op0, op1); break;
4040 static inline void gen_neon_mull(TCGv_i64 dest, TCGv a, TCGv b, int size, int u)
4044 switch ((size << 1) | u) {
4045 case 0: gen_helper_neon_mull_s8(dest, a, b); break;
4046 case 1: gen_helper_neon_mull_u8(dest, a, b); break;
4047 case 2: gen_helper_neon_mull_s16(dest, a, b); break;
4048 case 3: gen_helper_neon_mull_u16(dest, a, b); break;
4050 tmp = gen_muls_i64_i32(a, b);
4051 tcg_gen_mov_i64(dest, tmp);
4054 tmp = gen_mulu_i64_i32(a, b);
4055 tcg_gen_mov_i64(dest, tmp);
4065 /* Translate a NEON data processing instruction. Return nonzero if the
4066 instruction is invalid.
4067 We process data in a mixture of 32-bit and 64-bit chunks.
4068 Mostly we use 32-bit chunks so we can use normal scalar instructions. */
4070 static int disas_neon_data_insn(CPUState * env, DisasContext *s, uint32_t insn)
4088 if (!vfp_enabled(env))
4090 q = (insn & (1 << 6)) != 0;
4091 u = (insn >> 24) & 1;
4092 VFP_DREG_D(rd, insn);
4093 VFP_DREG_N(rn, insn);
4094 VFP_DREG_M(rm, insn);
4095 size = (insn >> 20) & 3;
4096 if ((insn & (1 << 23)) == 0) {
4097 /* Three register same length. */
4098 op = ((insn >> 7) & 0x1e) | ((insn >> 4) & 1);
4099 if (size == 3 && (op == 1 || op == 5 || op == 8 || op == 9
4100 || op == 10 || op == 11 || op == 16)) {
4101 /* 64-bit element instructions. */
4102 for (pass = 0; pass < (q ? 2 : 1); pass++) {
4103 neon_load_reg64(cpu_V0, rn + pass);
4104 neon_load_reg64(cpu_V1, rm + pass);
4108 gen_helper_neon_add_saturate_u64(CPU_V001);
4110 gen_helper_neon_add_saturate_s64(CPU_V001);
4115 gen_helper_neon_sub_saturate_u64(CPU_V001);
4117 gen_helper_neon_sub_saturate_s64(CPU_V001);
4122 gen_helper_neon_shl_u64(cpu_V0, cpu_V1, cpu_V0);
4124 gen_helper_neon_shl_s64(cpu_V0, cpu_V1, cpu_V0);
4129 gen_helper_neon_qshl_u64(cpu_V0, cpu_env,
4132 gen_helper_neon_qshl_s64(cpu_V1, cpu_env,
4136 case 10: /* VRSHL */
4138 gen_helper_neon_rshl_u64(cpu_V0, cpu_V1, cpu_V0);
4140 gen_helper_neon_rshl_s64(cpu_V0, cpu_V1, cpu_V0);
4143 case 11: /* VQRSHL */
4145 gen_helper_neon_qrshl_u64(cpu_V0, cpu_env,
4148 gen_helper_neon_qrshl_s64(cpu_V0, cpu_env,
4154 tcg_gen_sub_i64(CPU_V001);
4156 tcg_gen_add_i64(CPU_V001);
4162 neon_store_reg64(cpu_V0, rd + pass);
4169 case 10: /* VRSHL */
4170 case 11: /* VQRSHL */
4173 /* Shift instruction operands are reversed. */
4180 case 20: /* VPMAX */
4181 case 21: /* VPMIN */
4182 case 23: /* VPADD */
4185 case 26: /* VPADD (float) */
4186 pairwise = (u && size < 2);
4188 case 30: /* VPMIN/VPMAX (float) */
4195 for (pass = 0; pass < (q ? 4 : 2); pass++) {
4204 NEON_GET_REG(T0, rn, n);
4205 NEON_GET_REG(T1, rn, n + 1);
4207 NEON_GET_REG(T0, rm, n);
4208 NEON_GET_REG(T1, rm, n + 1);
4212 NEON_GET_REG(T0, rn, pass);
4213 NEON_GET_REG(T1, rm, pass);
4217 GEN_NEON_INTEGER_OP(hadd);
4220 GEN_NEON_INTEGER_OP_ENV(qadd);
4222 case 2: /* VRHADD */
4223 GEN_NEON_INTEGER_OP(rhadd);
4225 case 3: /* Logic ops. */
4226 switch ((u << 2) | size) {
4228 gen_op_andl_T0_T1();
4231 gen_op_bicl_T0_T1();
4241 gen_op_xorl_T0_T1();
4244 tmp = neon_load_reg(rd, pass);
4245 gen_neon_bsl(cpu_T[0], cpu_T[0], cpu_T[1], tmp);
4249 tmp = neon_load_reg(rd, pass);
4250 gen_neon_bsl(cpu_T[0], cpu_T[0], tmp, cpu_T[1]);
4254 tmp = neon_load_reg(rd, pass);
4255 gen_neon_bsl(cpu_T[0], tmp, cpu_T[0], cpu_T[1]);
4261 GEN_NEON_INTEGER_OP(hsub);
4264 GEN_NEON_INTEGER_OP_ENV(qsub);
4267 GEN_NEON_INTEGER_OP(cgt);
4270 GEN_NEON_INTEGER_OP(cge);
4273 GEN_NEON_INTEGER_OP(shl);
4276 GEN_NEON_INTEGER_OP_ENV(qshl);
4278 case 10: /* VRSHL */
4279 GEN_NEON_INTEGER_OP(rshl);
4281 case 11: /* VQRSHL */
4282 GEN_NEON_INTEGER_OP_ENV(qrshl);
4285 GEN_NEON_INTEGER_OP(max);
4288 GEN_NEON_INTEGER_OP(min);
4291 GEN_NEON_INTEGER_OP(abd);
4294 GEN_NEON_INTEGER_OP(abd);
4295 NEON_GET_REG(T1, rd, pass);
4299 if (!u) { /* VADD */
4300 if (gen_neon_add(size))
4304 case 0: gen_helper_neon_sub_u8(CPU_T001); break;
4305 case 1: gen_helper_neon_sub_u16(CPU_T001); break;
4306 case 2: gen_op_subl_T0_T1(); break;
4312 if (!u) { /* VTST */
4314 case 0: gen_helper_neon_tst_u8(CPU_T001); break;
4315 case 1: gen_helper_neon_tst_u16(CPU_T001); break;
4316 case 2: gen_helper_neon_tst_u32(CPU_T001); break;
4321 case 0: gen_helper_neon_ceq_u8(CPU_T001); break;
4322 case 1: gen_helper_neon_ceq_u16(CPU_T001); break;
4323 case 2: gen_helper_neon_ceq_u32(CPU_T001); break;
4328 case 18: /* Multiply. */
4330 case 0: gen_helper_neon_mul_u8(CPU_T001); break;
4331 case 1: gen_helper_neon_mul_u16(CPU_T001); break;
4332 case 2: gen_op_mul_T0_T1(); break;
4335 NEON_GET_REG(T1, rd, pass);
4343 if (u) { /* polynomial */
4344 gen_helper_neon_mul_p8(CPU_T001);
4345 } else { /* Integer */
4347 case 0: gen_helper_neon_mul_u8(CPU_T001); break;
4348 case 1: gen_helper_neon_mul_u16(CPU_T001); break;
4349 case 2: gen_op_mul_T0_T1(); break;
4354 case 20: /* VPMAX */
4355 GEN_NEON_INTEGER_OP(pmax);
4357 case 21: /* VPMIN */
4358 GEN_NEON_INTEGER_OP(pmin);
4360 case 22: /* Hultiply high. */
4361 if (!u) { /* VQDMULH */
4363 case 1: gen_helper_neon_qdmulh_s16(CPU_T0E01); break;
4364 case 2: gen_helper_neon_qdmulh_s32(CPU_T0E01); break;
4367 } else { /* VQRDHMUL */
4369 case 1: gen_helper_neon_qrdmulh_s16(CPU_T0E01); break;
4370 case 2: gen_helper_neon_qrdmulh_s32(CPU_T0E01); break;
4375 case 23: /* VPADD */
4379 case 0: gen_helper_neon_padd_u8(CPU_T001); break;
4380 case 1: gen_helper_neon_padd_u16(CPU_T001); break;
4381 case 2: gen_op_addl_T0_T1(); break;
4385 case 26: /* Floating point arithnetic. */
4386 switch ((u << 2) | size) {
4388 gen_helper_neon_add_f32(CPU_T001);
4391 gen_helper_neon_sub_f32(CPU_T001);
4394 gen_helper_neon_add_f32(CPU_T001);
4397 gen_helper_neon_abd_f32(CPU_T001);
4403 case 27: /* Float multiply. */
4404 gen_helper_neon_mul_f32(CPU_T001);
4406 NEON_GET_REG(T1, rd, pass);
4408 gen_helper_neon_add_f32(CPU_T001);
4410 gen_helper_neon_sub_f32(cpu_T[0], cpu_T[1], cpu_T[0]);
4414 case 28: /* Float compare. */
4416 gen_helper_neon_ceq_f32(CPU_T001);
4419 gen_helper_neon_cge_f32(CPU_T001);
4421 gen_helper_neon_cgt_f32(CPU_T001);
4424 case 29: /* Float compare absolute. */
4428 gen_helper_neon_acge_f32(CPU_T001);
4430 gen_helper_neon_acgt_f32(CPU_T001);
4432 case 30: /* Float min/max. */
4434 gen_helper_neon_max_f32(CPU_T001);
4436 gen_helper_neon_min_f32(CPU_T001);
4440 gen_helper_recps_f32(cpu_T[0], cpu_T[0], cpu_T[1], cpu_env);
4442 gen_helper_rsqrts_f32(cpu_T[0], cpu_T[0], cpu_T[1], cpu_env);
4447 /* Save the result. For elementwise operations we can put it
4448 straight into the destination register. For pairwise operations
4449 we have to be careful to avoid clobbering the source operands. */
4450 if (pairwise && rd == rm) {
4451 gen_neon_movl_scratch_T0(pass);
4453 NEON_SET_REG(T0, rd, pass);
4457 if (pairwise && rd == rm) {
4458 for (pass = 0; pass < (q ? 4 : 2); pass++) {
4459 gen_neon_movl_T0_scratch(pass);
4460 NEON_SET_REG(T0, rd, pass);
4463 /* End of 3 register same size operations. */
4464 } else if (insn & (1 << 4)) {
4465 if ((insn & 0x00380080) != 0) {
4466 /* Two registers and shift. */
4467 op = (insn >> 8) & 0xf;
4468 if (insn & (1 << 7)) {
4473 while ((insn & (1 << (size + 19))) == 0)
4476 shift = (insn >> 16) & ((1 << (3 + size)) - 1);
4477 /* To avoid excessive dumplication of ops we implement shift
4478 by immediate using the variable shift operations. */
4480 /* Shift by immediate:
4481 VSHR, VSRA, VRSHR, VRSRA, VSRI, VSHL, VQSHL, VQSHLU. */
4482 /* Right shifts are encoded as N - shift, where N is the
4483 element size in bits. */
4485 shift = shift - (1 << (size + 3));
4493 imm = (uint8_t) shift;
4498 imm = (uint16_t) shift;
4509 for (pass = 0; pass < count; pass++) {
4511 neon_load_reg64(cpu_V0, rm + pass);
4512 tcg_gen_movi_i64(cpu_V1, imm);
4517 gen_helper_neon_shl_u64(cpu_V0, cpu_V0, cpu_V1);
4519 gen_helper_neon_shl_s64(cpu_V0, cpu_V0, cpu_V1);
4524 gen_helper_neon_rshl_u64(cpu_V0, cpu_V0, cpu_V1);
4526 gen_helper_neon_rshl_s64(cpu_V0, cpu_V0, cpu_V1);
4531 gen_helper_neon_shl_u64(cpu_V0, cpu_V0, cpu_V1);
4533 case 5: /* VSHL, VSLI */
4534 gen_helper_neon_shl_u64(cpu_V0, cpu_V0, cpu_V1);
4538 gen_helper_neon_qshl_u64(cpu_V0, cpu_env, cpu_V0, cpu_V1);
4540 gen_helper_neon_qshl_s64(cpu_V0, cpu_env, cpu_V0, cpu_V1);
4542 case 7: /* VQSHLU */
4543 gen_helper_neon_qshl_u64(cpu_V0, cpu_env, cpu_V0, cpu_V1);
4546 if (op == 1 || op == 3) {
4548 neon_load_reg64(cpu_V0, rd + pass);
4549 tcg_gen_add_i64(cpu_V0, cpu_V0, cpu_V1);
4550 } else if (op == 4 || (op == 5 && u)) {
4552 cpu_abort(env, "VS[LR]I.64 not implemented");
4554 neon_store_reg64(cpu_V0, rd + pass);
4555 } else { /* size < 3 */
4556 /* Operands in T0 and T1. */
4557 gen_op_movl_T1_im(imm);
4558 NEON_GET_REG(T0, rm, pass);
4562 GEN_NEON_INTEGER_OP(shl);
4566 GEN_NEON_INTEGER_OP(rshl);
4571 GEN_NEON_INTEGER_OP(shl);
4573 case 5: /* VSHL, VSLI */
4575 case 0: gen_helper_neon_shl_u8(CPU_T001); break;
4576 case 1: gen_helper_neon_shl_u16(CPU_T001); break;
4577 case 2: gen_helper_neon_shl_u32(CPU_T001); break;
4582 GEN_NEON_INTEGER_OP_ENV(qshl);
4584 case 7: /* VQSHLU */
4586 case 0: gen_helper_neon_qshl_u8(CPU_T0E01); break;
4587 case 1: gen_helper_neon_qshl_u16(CPU_T0E01); break;
4588 case 2: gen_helper_neon_qshl_u32(CPU_T0E01); break;
4594 if (op == 1 || op == 3) {
4596 NEON_GET_REG(T1, rd, pass);
4598 } else if (op == 4 || (op == 5 && u)) {
4603 imm = 0xff >> -shift;
4605 imm = (uint8_t)(0xff << shift);
4611 imm = 0xffff >> -shift;
4613 imm = (uint16_t)(0xffff << shift);
4618 imm = 0xffffffffu >> -shift;
4620 imm = 0xffffffffu << shift;
4625 tmp = neon_load_reg(rd, pass);
4626 tcg_gen_andi_i32(cpu_T[0], cpu_T[0], imm);
4627 tcg_gen_andi_i32(tmp, tmp, ~imm);
4628 tcg_gen_or_i32(cpu_T[0], cpu_T[0], tmp);
4630 NEON_SET_REG(T0, rd, pass);
4633 } else if (op < 10) {
4634 /* Shift by immediate and narrow:
4635 VSHRN, VRSHRN, VQSHRN, VQRSHRN. */
4636 shift = shift - (1 << (size + 3));
4640 imm = (uint16_t)shift;
4642 tmp2 = tcg_const_i32(imm);
4643 TCGV_UNUSED_I64(tmp64);
4646 imm = (uint32_t)shift;
4647 tmp2 = tcg_const_i32(imm);
4648 TCGV_UNUSED_I64(tmp64);
4651 tmp64 = tcg_const_i64(shift);
4658 for (pass = 0; pass < 2; pass++) {
4660 neon_load_reg64(cpu_V0, rm + pass);
4663 gen_helper_neon_rshl_u64(cpu_V0, cpu_V0, tmp64);
4665 gen_helper_neon_rshl_s64(cpu_V0, cpu_V0, tmp64);
4668 gen_helper_neon_shl_u64(cpu_V0, cpu_V0, tmp64);
4670 gen_helper_neon_shl_s64(cpu_V0, cpu_V0, tmp64);
4673 tmp = neon_load_reg(rm + pass, 0);
4674 gen_neon_shift_narrow(size, tmp, tmp2, q, u);
4675 tmp3 = neon_load_reg(rm + pass, 1);
4676 gen_neon_shift_narrow(size, tmp3, tmp2, q, u);
4677 tcg_gen_concat_i32_i64(cpu_V0, tmp, tmp3);
4682 if (op == 8 && !u) {
4683 gen_neon_narrow(size - 1, tmp, cpu_V0);
4686 gen_neon_narrow_sats(size - 1, tmp, cpu_V0);
4688 gen_neon_narrow_satu(size - 1, tmp, cpu_V0);
4693 neon_store_reg(rd, 0, tmp2);
4694 neon_store_reg(rd, 1, tmp);
4697 } else if (op == 10) {
4701 tmp = neon_load_reg(rm, 0);
4702 tmp2 = neon_load_reg(rm, 1);
4703 for (pass = 0; pass < 2; pass++) {
4707 gen_neon_widen(cpu_V0, tmp, size, u);
4710 /* The shift is less than the width of the source
4711 type, so we can just shift the whole register. */
4712 tcg_gen_shli_i64(cpu_V0, cpu_V0, shift);
4713 if (size < 2 || !u) {
4716 imm = (0xffu >> (8 - shift));
4719 imm = 0xffff >> (16 - shift);
4721 imm64 = imm | (((uint64_t)imm) << 32);
4722 tcg_gen_andi_i64(cpu_V0, cpu_V0, imm64);
4725 neon_store_reg64(cpu_V0, rd + pass);
4727 } else if (op == 15 || op == 16) {
4728 /* VCVT fixed-point. */
4729 for (pass = 0; pass < (q ? 4 : 2); pass++) {
4730 tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, pass));
4733 gen_vfp_ulto(0, shift);
4735 gen_vfp_slto(0, shift);
4738 gen_vfp_toul(0, shift);
4740 gen_vfp_tosl(0, shift);
4742 tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, pass));
4747 } else { /* (insn & 0x00380080) == 0 */
4750 op = (insn >> 8) & 0xf;
4751 /* One register and immediate. */
4752 imm = (u << 7) | ((insn >> 12) & 0x70) | (insn & 0xf);
4753 invert = (insn & (1 << 5)) != 0;
4771 imm = (imm << 8) | (imm << 24);
4774 imm = (imm < 8) | 0xff;
4777 imm = (imm << 16) | 0xffff;
4780 imm |= (imm << 8) | (imm << 16) | (imm << 24);
4785 imm = ((imm & 0x80) << 24) | ((imm & 0x3f) << 19)
4786 | ((imm & 0x40) ? (0x1f << 25) : (1 << 30));
4792 if (op != 14 || !invert)
4793 gen_op_movl_T1_im(imm);
4795 for (pass = 0; pass < (q ? 4 : 2); pass++) {
4796 if (op & 1 && op < 12) {
4797 tmp = neon_load_reg(rd, pass);
4799 /* The immediate value has already been inverted, so
4801 tcg_gen_andi_i32(tmp, tmp, imm);
4803 tcg_gen_ori_i32(tmp, tmp, imm);
4808 if (op == 14 && invert) {
4811 for (n = 0; n < 4; n++) {
4812 if (imm & (1 << (n + (pass & 1) * 4)))
4813 val |= 0xff << (n * 8);
4815 tcg_gen_movi_i32(tmp, val);
4817 tcg_gen_movi_i32(tmp, imm);
4820 neon_store_reg(rd, pass, tmp);
4823 } else { /* (insn & 0x00800010 == 0x00800000) */
4825 op = (insn >> 8) & 0xf;
4826 if ((insn & (1 << 6)) == 0) {
4827 /* Three registers of different lengths. */
4831 /* prewiden, src1_wide, src2_wide */
4832 static const int neon_3reg_wide[16][3] = {
4833 {1, 0, 0}, /* VADDL */
4834 {1, 1, 0}, /* VADDW */
4835 {1, 0, 0}, /* VSUBL */
4836 {1, 1, 0}, /* VSUBW */
4837 {0, 1, 1}, /* VADDHN */
4838 {0, 0, 0}, /* VABAL */
4839 {0, 1, 1}, /* VSUBHN */
4840 {0, 0, 0}, /* VABDL */
4841 {0, 0, 0}, /* VMLAL */
4842 {0, 0, 0}, /* VQDMLAL */
4843 {0, 0, 0}, /* VMLSL */
4844 {0, 0, 0}, /* VQDMLSL */
4845 {0, 0, 0}, /* Integer VMULL */
4846 {0, 0, 0}, /* VQDMULL */
4847 {0, 0, 0} /* Polynomial VMULL */
4850 prewiden = neon_3reg_wide[op][0];
4851 src1_wide = neon_3reg_wide[op][1];
4852 src2_wide = neon_3reg_wide[op][2];
4854 if (size == 0 && (op == 9 || op == 11 || op == 13))
4857 /* Avoid overlapping operands. Wide source operands are
4858 always aligned so will never overlap with wide
4859 destinations in problematic ways. */
4860 if (rd == rm && !src2_wide) {
4861 NEON_GET_REG(T0, rm, 1);
4862 gen_neon_movl_scratch_T0(2);
4863 } else if (rd == rn && !src1_wide) {
4864 NEON_GET_REG(T0, rn, 1);
4865 gen_neon_movl_scratch_T0(2);
4868 for (pass = 0; pass < 2; pass++) {
4870 neon_load_reg64(cpu_V0, rn + pass);
4873 if (pass == 1 && rd == rn) {
4874 gen_neon_movl_T0_scratch(2);
4876 tcg_gen_mov_i32(tmp, cpu_T[0]);
4878 tmp = neon_load_reg(rn, pass);
4881 gen_neon_widen(cpu_V0, tmp, size, u);
4885 neon_load_reg64(cpu_V1, rm + pass);
4888 if (pass == 1 && rd == rm) {
4889 gen_neon_movl_T0_scratch(2);
4891 tcg_gen_mov_i32(tmp2, cpu_T[0]);
4893 tmp2 = neon_load_reg(rm, pass);
4896 gen_neon_widen(cpu_V1, tmp2, size, u);
4900 case 0: case 1: case 4: /* VADDL, VADDW, VADDHN, VRADDHN */
4901 gen_neon_addl(size);
4903 case 2: case 3: case 6: /* VSUBL, VSUBW, VSUBHL, VRSUBHL */
4904 gen_neon_subl(size);
4906 case 5: case 7: /* VABAL, VABDL */
4907 switch ((size << 1) | u) {
4909 gen_helper_neon_abdl_s16(cpu_V0, tmp, tmp2);
4912 gen_helper_neon_abdl_u16(cpu_V0, tmp, tmp2);
4915 gen_helper_neon_abdl_s32(cpu_V0, tmp, tmp2);
4918 gen_helper_neon_abdl_u32(cpu_V0, tmp, tmp2);
4921 gen_helper_neon_abdl_s64(cpu_V0, tmp, tmp2);
4924 gen_helper_neon_abdl_u64(cpu_V0, tmp, tmp2);
4931 case 8: case 9: case 10: case 11: case 12: case 13:
4932 /* VMLAL, VQDMLAL, VMLSL, VQDMLSL, VMULL, VQDMULL */
4933 gen_neon_mull(cpu_V0, tmp, tmp2, size, u);
4935 case 14: /* Polynomial VMULL */
4936 cpu_abort(env, "Polynomial VMULL not implemented");
4938 default: /* 15 is RESERVED. */
4941 if (op == 5 || op == 13 || (op >= 8 && op <= 11)) {
4943 if (op == 10 || op == 11) {
4944 gen_neon_negl(cpu_V0, size);
4948 neon_load_reg64(cpu_V1, rd + pass);
4952 case 5: case 8: case 10: /* VABAL, VMLAL, VMLSL */
4953 gen_neon_addl(size);
4955 case 9: case 11: /* VQDMLAL, VQDMLSL */
4956 gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
4957 gen_neon_addl_saturate(cpu_V0, cpu_V1, size);
4960 case 13: /* VQDMULL */
4961 gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
4966 neon_store_reg64(cpu_V0, rd + pass);
4967 } else if (op == 4 || op == 6) {
4968 /* Narrowing operation. */
4973 gen_helper_neon_narrow_high_u8(tmp, cpu_V0);
4976 gen_helper_neon_narrow_high_u16(tmp, cpu_V0);
4979 tcg_gen_shri_i64(cpu_V0, cpu_V0, 32);
4980 tcg_gen_trunc_i64_i32(tmp, cpu_V0);
4987 gen_helper_neon_narrow_round_high_u8(tmp, cpu_V0);
4990 gen_helper_neon_narrow_round_high_u16(tmp, cpu_V0);
4993 tcg_gen_addi_i64(cpu_V0, cpu_V0, 1u << 31);
4994 tcg_gen_shri_i64(cpu_V0, cpu_V0, 32);
4995 tcg_gen_trunc_i64_i32(tmp, cpu_V0);
5003 neon_store_reg(rd, 0, tmp3);
5004 neon_store_reg(rd, 1, tmp);
5007 /* Write back the result. */
5008 neon_store_reg64(cpu_V0, rd + pass);
5012 /* Two registers and a scalar. */
5014 case 0: /* Integer VMLA scalar */
5015 case 1: /* Float VMLA scalar */
5016 case 4: /* Integer VMLS scalar */
5017 case 5: /* Floating point VMLS scalar */
5018 case 8: /* Integer VMUL scalar */
5019 case 9: /* Floating point VMUL scalar */
5020 case 12: /* VQDMULH scalar */
5021 case 13: /* VQRDMULH scalar */
5022 gen_neon_get_scalar(size, rm);
5023 gen_neon_movl_scratch_T0(0);
5024 for (pass = 0; pass < (u ? 4 : 2); pass++) {
5026 gen_neon_movl_T0_scratch(0);
5027 NEON_GET_REG(T1, rn, pass);
5030 gen_helper_neon_qdmulh_s16(CPU_T0E01);
5032 gen_helper_neon_qdmulh_s32(CPU_T0E01);
5034 } else if (op == 13) {
5036 gen_helper_neon_qrdmulh_s16(CPU_T0E01);
5038 gen_helper_neon_qrdmulh_s32(CPU_T0E01);
5040 } else if (op & 1) {
5041 gen_helper_neon_mul_f32(CPU_T001);
5044 case 0: gen_helper_neon_mul_u8(CPU_T001); break;
5045 case 1: gen_helper_neon_mul_u16(CPU_T001); break;
5046 case 2: gen_op_mul_T0_T1(); break;
5052 NEON_GET_REG(T1, rd, pass);
5058 gen_helper_neon_add_f32(CPU_T001);
5064 gen_helper_neon_sub_f32(cpu_T[0], cpu_T[1], cpu_T[0]);
5070 NEON_SET_REG(T0, rd, pass);
5073 case 2: /* VMLAL sclar */
5074 case 3: /* VQDMLAL scalar */
5075 case 6: /* VMLSL scalar */
5076 case 7: /* VQDMLSL scalar */
5077 case 10: /* VMULL scalar */
5078 case 11: /* VQDMULL scalar */
5079 if (size == 0 && (op == 3 || op == 7 || op == 11))
5082 gen_neon_get_scalar(size, rm);
5083 NEON_GET_REG(T1, rn, 1);
5085 for (pass = 0; pass < 2; pass++) {
5087 tmp = neon_load_reg(rn, 0);
5090 tcg_gen_mov_i32(tmp, cpu_T[1]);
5093 tcg_gen_mov_i32(tmp2, cpu_T[0]);
5094 gen_neon_mull(cpu_V0, tmp, tmp2, size, u);
5095 if (op == 6 || op == 7) {
5096 gen_neon_negl(cpu_V0, size);
5099 neon_load_reg64(cpu_V1, rd + pass);
5103 gen_neon_addl(size);
5106 gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
5107 gen_neon_addl_saturate(cpu_V0, cpu_V1, size);
5113 gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
5118 neon_store_reg64(cpu_V0, rd + pass);
5121 default: /* 14 and 15 are RESERVED */
5125 } else { /* size == 3 */
5128 imm = (insn >> 8) & 0xf;
5135 neon_load_reg64(cpu_V0, rn);
5137 neon_load_reg64(cpu_V1, rn + 1);
5139 } else if (imm == 8) {
5140 neon_load_reg64(cpu_V0, rn + 1);
5142 neon_load_reg64(cpu_V1, rm);
5145 tmp64 = tcg_temp_new_i64();
5147 neon_load_reg64(cpu_V0, rn);
5148 neon_load_reg64(tmp64, rn + 1);
5150 neon_load_reg64(cpu_V0, rn + 1);
5151 neon_load_reg64(tmp64, rm);
5153 tcg_gen_shri_i64(cpu_V0, cpu_V0, (imm & 7) * 8);
5154 tcg_gen_shli_i64(cpu_V1, tmp64, 64 - ((imm & 7) * 8));
5155 tcg_gen_or_i64(cpu_V0, cpu_V0, cpu_V1);
5157 neon_load_reg64(cpu_V1, rm);
5159 neon_load_reg64(cpu_V1, rm + 1);
5162 tcg_gen_shli_i64(cpu_V1, cpu_V1, 64 - (imm * 8));
5163 tcg_gen_shri_i64(tmp64, tmp64, imm * 8);
5164 tcg_gen_or_i64(cpu_V1, cpu_V1, tmp64);
5167 neon_load_reg64(cpu_V0, rn);
5168 tcg_gen_shri_i64(cpu_V0, cpu_V0, imm * 8);
5169 neon_load_reg64(cpu_V1, rm);
5170 tcg_gen_shli_i64(cpu_V1, cpu_V1, 64 - (imm * 8));
5171 tcg_gen_or_i64(cpu_V0, cpu_V0, cpu_V1);
5173 neon_store_reg64(cpu_V0, rd);
5175 neon_store_reg64(cpu_V1, rd + 1);
5177 } else if ((insn & (1 << 11)) == 0) {
5178 /* Two register misc. */
5179 op = ((insn >> 12) & 0x30) | ((insn >> 7) & 0xf);
5180 size = (insn >> 18) & 3;
5182 case 0: /* VREV64 */
5185 for (pass = 0; pass < (q ? 2 : 1); pass++) {
5186 NEON_GET_REG(T0, rm, pass * 2);
5187 NEON_GET_REG(T1, rm, pass * 2 + 1);
5189 case 0: tcg_gen_bswap32_i32(cpu_T[0], cpu_T[0]); break;
5190 case 1: gen_swap_half(cpu_T[0]); break;
5191 case 2: /* no-op */ break;
5194 NEON_SET_REG(T0, rd, pass * 2 + 1);
5196 NEON_SET_REG(T1, rd, pass * 2);
5198 gen_op_movl_T0_T1();
5200 case 0: tcg_gen_bswap32_i32(cpu_T[0], cpu_T[0]); break;
5201 case 1: gen_swap_half(cpu_T[0]); break;
5204 NEON_SET_REG(T0, rd, pass * 2);
5208 case 4: case 5: /* VPADDL */
5209 case 12: case 13: /* VPADAL */
5212 for (pass = 0; pass < q + 1; pass++) {
5213 tmp = neon_load_reg(rm, pass * 2);
5214 gen_neon_widen(cpu_V0, tmp, size, op & 1);
5215 tmp = neon_load_reg(rm, pass * 2 + 1);
5216 gen_neon_widen(cpu_V1, tmp, size, op & 1);
5218 case 0: gen_helper_neon_paddl_u16(CPU_V001); break;
5219 case 1: gen_helper_neon_paddl_u32(CPU_V001); break;
5220 case 2: tcg_gen_add_i64(CPU_V001); break;
5225 neon_load_reg64(cpu_V1, rd + pass);
5226 gen_neon_addl(size);
5228 neon_store_reg64(cpu_V0, rd + pass);
5233 for (n = 0; n < (q ? 4 : 2); n += 2) {
5234 NEON_GET_REG(T0, rm, n);
5235 NEON_GET_REG(T1, rd, n + 1);
5236 NEON_SET_REG(T1, rm, n);
5237 NEON_SET_REG(T0, rd, n + 1);
5245 Rd A3 A2 A1 A0 B2 B0 A2 A0
5246 Rm B3 B2 B1 B0 B3 B1 A3 A1
5250 gen_neon_unzip(rd, q, 0, size);
5251 gen_neon_unzip(rm, q, 4, size);
5253 static int unzip_order_q[8] =
5254 {0, 2, 4, 6, 1, 3, 5, 7};
5255 for (n = 0; n < 8; n++) {
5256 int reg = (n < 4) ? rd : rm;
5257 gen_neon_movl_T0_scratch(unzip_order_q[n]);
5258 NEON_SET_REG(T0, reg, n % 4);
5261 static int unzip_order[4] =
5263 for (n = 0; n < 4; n++) {
5264 int reg = (n < 2) ? rd : rm;
5265 gen_neon_movl_T0_scratch(unzip_order[n]);
5266 NEON_SET_REG(T0, reg, n % 2);
5272 Rd A3 A2 A1 A0 B1 A1 B0 A0
5273 Rm B3 B2 B1 B0 B3 A3 B2 A2
5277 count = (q ? 4 : 2);
5278 for (n = 0; n < count; n++) {
5279 NEON_GET_REG(T0, rd, n);
5280 NEON_GET_REG(T1, rd, n);
5282 case 0: gen_helper_neon_zip_u8(); break;
5283 case 1: gen_helper_neon_zip_u16(); break;
5284 case 2: /* no-op */; break;
5287 gen_neon_movl_scratch_T0(n * 2);
5288 gen_neon_movl_scratch_T1(n * 2 + 1);
5290 for (n = 0; n < count * 2; n++) {
5291 int reg = (n < count) ? rd : rm;
5292 gen_neon_movl_T0_scratch(n);
5293 NEON_SET_REG(T0, reg, n % count);
5296 case 36: case 37: /* VMOVN, VQMOVUN, VQMOVN */
5300 for (pass = 0; pass < 2; pass++) {
5301 neon_load_reg64(cpu_V0, rm + pass);
5303 if (op == 36 && q == 0) {
5304 gen_neon_narrow(size, tmp, cpu_V0);
5306 gen_neon_narrow_satu(size, tmp, cpu_V0);
5308 gen_neon_narrow_sats(size, tmp, cpu_V0);
5313 neon_store_reg(rd, 0, tmp2);
5314 neon_store_reg(rd, 1, tmp);
5318 case 38: /* VSHLL */
5321 tmp = neon_load_reg(rm, 0);
5322 tmp2 = neon_load_reg(rm, 1);
5323 for (pass = 0; pass < 2; pass++) {
5326 gen_neon_widen(cpu_V0, tmp, size, 1);
5327 neon_store_reg64(cpu_V0, rd + pass);
5332 for (pass = 0; pass < (q ? 4 : 2); pass++) {
5333 if (op == 30 || op == 31 || op >= 58) {
5334 tcg_gen_ld_f32(cpu_F0s, cpu_env,
5335 neon_reg_offset(rm, pass));
5337 NEON_GET_REG(T0, rm, pass);
5340 case 1: /* VREV32 */
5342 case 0: tcg_gen_bswap32_i32(cpu_T[0], cpu_T[0]); break;
5343 case 1: gen_swap_half(cpu_T[0]); break;
5347 case 2: /* VREV16 */
5350 gen_rev16(cpu_T[0]);
5354 case 0: gen_helper_neon_cls_s8(cpu_T[0], cpu_T[0]); break;
5355 case 1: gen_helper_neon_cls_s16(cpu_T[0], cpu_T[0]); break;
5356 case 2: gen_helper_neon_cls_s32(cpu_T[0], cpu_T[0]); break;
5362 case 0: gen_helper_neon_clz_u8(cpu_T[0], cpu_T[0]); break;
5363 case 1: gen_helper_neon_clz_u16(cpu_T[0], cpu_T[0]); break;
5364 case 2: gen_helper_clz(cpu_T[0], cpu_T[0]); break;
5371 gen_helper_neon_cnt_u8(cpu_T[0], cpu_T[0]);
5378 case 14: /* VQABS */
5380 case 0: gen_helper_neon_qabs_s8(cpu_T[0], cpu_env, cpu_T[0]); break;
5381 case 1: gen_helper_neon_qabs_s16(cpu_T[0], cpu_env, cpu_T[0]); break;
5382 case 2: gen_helper_neon_qabs_s32(cpu_T[0], cpu_env, cpu_T[0]); break;
5386 case 15: /* VQNEG */
5388 case 0: gen_helper_neon_qneg_s8(cpu_T[0], cpu_env, cpu_T[0]); break;
5389 case 1: gen_helper_neon_qneg_s16(cpu_T[0], cpu_env, cpu_T[0]); break;
5390 case 2: gen_helper_neon_qneg_s32(cpu_T[0], cpu_env, cpu_T[0]); break;
5394 case 16: case 19: /* VCGT #0, VCLE #0 */
5395 gen_op_movl_T1_im(0);
5397 case 0: gen_helper_neon_cgt_s8(CPU_T001); break;
5398 case 1: gen_helper_neon_cgt_s16(CPU_T001); break;
5399 case 2: gen_helper_neon_cgt_s32(CPU_T001); break;
5405 case 17: case 20: /* VCGE #0, VCLT #0 */
5406 gen_op_movl_T1_im(0);
5408 case 0: gen_helper_neon_cge_s8(CPU_T001); break;
5409 case 1: gen_helper_neon_cge_s16(CPU_T001); break;
5410 case 2: gen_helper_neon_cge_s32(CPU_T001); break;
5416 case 18: /* VCEQ #0 */
5417 gen_op_movl_T1_im(0);
5419 case 0: gen_helper_neon_ceq_u8(CPU_T001); break;
5420 case 1: gen_helper_neon_ceq_u16(CPU_T001); break;
5421 case 2: gen_helper_neon_ceq_u32(CPU_T001); break;
5427 case 0: gen_helper_neon_abs_s8(cpu_T[0], cpu_T[0]); break;
5428 case 1: gen_helper_neon_abs_s16(cpu_T[0], cpu_T[0]); break;
5429 case 2: tcg_gen_abs_i32(cpu_T[0], cpu_T[0]); break;
5434 gen_op_movl_T1_im(0);
5439 case 24: case 27: /* Float VCGT #0, Float VCLE #0 */
5440 gen_op_movl_T1_im(0);
5441 gen_helper_neon_cgt_f32(CPU_T001);
5445 case 25: case 28: /* Float VCGE #0, Float VCLT #0 */
5446 gen_op_movl_T1_im(0);
5447 gen_helper_neon_cge_f32(CPU_T001);
5451 case 26: /* Float VCEQ #0 */
5452 gen_op_movl_T1_im(0);
5453 gen_helper_neon_ceq_f32(CPU_T001);
5455 case 30: /* Float VABS */
5458 case 31: /* Float VNEG */
5462 NEON_GET_REG(T1, rd, pass);
5463 NEON_SET_REG(T1, rm, pass);
5466 NEON_GET_REG(T1, rd, pass);
5468 case 0: gen_helper_neon_trn_u8(); break;
5469 case 1: gen_helper_neon_trn_u16(); break;
5473 NEON_SET_REG(T1, rm, pass);
5475 case 56: /* Integer VRECPE */
5476 gen_helper_recpe_u32(cpu_T[0], cpu_T[0], cpu_env);
5478 case 57: /* Integer VRSQRTE */
5479 gen_helper_rsqrte_u32(cpu_T[0], cpu_T[0], cpu_env);
5481 case 58: /* Float VRECPE */
5482 gen_helper_recpe_f32(cpu_F0s, cpu_F0s, cpu_env);
5484 case 59: /* Float VRSQRTE */
5485 gen_helper_rsqrte_f32(cpu_F0s, cpu_F0s, cpu_env);
5487 case 60: /* VCVT.F32.S32 */
5490 case 61: /* VCVT.F32.U32 */
5493 case 62: /* VCVT.S32.F32 */
5496 case 63: /* VCVT.U32.F32 */
5500 /* Reserved: 21, 29, 39-56 */
5503 if (op == 30 || op == 31 || op >= 58) {
5504 tcg_gen_st_f32(cpu_F0s, cpu_env,
5505 neon_reg_offset(rd, pass));
5507 NEON_SET_REG(T0, rd, pass);
5512 } else if ((insn & (1 << 10)) == 0) {
5514 n = ((insn >> 5) & 0x18) + 8;
5515 if (insn & (1 << 6)) {
5516 tmp = neon_load_reg(rd, 0);
5519 tcg_gen_movi_i32(tmp, 0);
5521 tmp2 = neon_load_reg(rm, 0);
5522 gen_helper_neon_tbl(tmp2, tmp2, tmp, tcg_const_i32(rn),
5525 if (insn & (1 << 6)) {
5526 tmp = neon_load_reg(rd, 1);
5529 tcg_gen_movi_i32(tmp, 0);
5531 tmp3 = neon_load_reg(rm, 1);
5532 gen_helper_neon_tbl(tmp3, tmp3, tmp, tcg_const_i32(rn),
5534 neon_store_reg(rd, 0, tmp2);
5535 neon_store_reg(rd, 1, tmp3);
5537 } else if ((insn & 0x380) == 0) {
5539 if (insn & (1 << 19)) {
5540 NEON_SET_REG(T0, rm, 1);
5542 NEON_SET_REG(T0, rm, 0);
5544 if (insn & (1 << 16)) {
5545 gen_neon_dup_u8(cpu_T[0], ((insn >> 17) & 3) * 8);
5546 } else if (insn & (1 << 17)) {
5547 if ((insn >> 18) & 1)
5548 gen_neon_dup_high16(cpu_T[0]);
5550 gen_neon_dup_low16(cpu_T[0]);
5552 for (pass = 0; pass < (q ? 4 : 2); pass++) {
5553 NEON_SET_REG(T0, rd, pass);
5563 static int disas_cp14_read(CPUState * env, DisasContext *s, uint32_t insn)
5565 int crn = (insn >> 16) & 0xf;
5566 int crm = insn & 0xf;
5567 int op1 = (insn >> 21) & 7;
5568 int op2 = (insn >> 5) & 7;
5569 int rt = (insn >> 12) & 0xf;
5572 if (arm_feature(env, ARM_FEATURE_THUMB2EE)) {
5573 if (op1 == 6 && crn == 0 && crm == 0 && op2 == 0) {
5577 tmp = load_cpu_field(teecr);
5578 store_reg(s, rt, tmp);
5581 if (op1 == 6 && crn == 1 && crm == 0 && op2 == 0) {
5583 if (IS_USER(s) && (env->teecr & 1))
5585 tmp = load_cpu_field(teehbr);
5586 store_reg(s, rt, tmp);
5590 fprintf(stderr, "Unknown cp14 read op1:%d crn:%d crm:%d op2:%d\n",
5591 op1, crn, crm, op2);
5595 static int disas_cp14_write(CPUState * env, DisasContext *s, uint32_t insn)
5597 int crn = (insn >> 16) & 0xf;
5598 int crm = insn & 0xf;
5599 int op1 = (insn >> 21) & 7;
5600 int op2 = (insn >> 5) & 7;
5601 int rt = (insn >> 12) & 0xf;
5604 if (arm_feature(env, ARM_FEATURE_THUMB2EE)) {
5605 if (op1 == 6 && crn == 0 && crm == 0 && op2 == 0) {
5609 tmp = load_reg(s, rt);
5610 gen_helper_set_teecr(cpu_env, tmp);
5614 if (op1 == 6 && crn == 1 && crm == 0 && op2 == 0) {
5616 if (IS_USER(s) && (env->teecr & 1))
5618 tmp = load_reg(s, rt);
5619 store_cpu_field(tmp, teehbr);
5623 fprintf(stderr, "Unknown cp14 write op1:%d crn:%d crm:%d op2:%d\n",
5624 op1, crn, crm, op2);
5628 static int disas_coproc_insn(CPUState * env, DisasContext *s, uint32_t insn)
5632 cpnum = (insn >> 8) & 0xf;
5633 if (arm_feature(env, ARM_FEATURE_XSCALE)
5634 && ((env->cp15.c15_cpar ^ 0x3fff) & (1 << cpnum)))
5640 if (arm_feature(env, ARM_FEATURE_IWMMXT)) {
5641 return disas_iwmmxt_insn(env, s, insn);
5642 } else if (arm_feature(env, ARM_FEATURE_XSCALE)) {
5643 return disas_dsp_insn(env, s, insn);
5648 return disas_vfp_insn (env, s, insn);
5650 /* Coprocessors 7-15 are architecturally reserved by ARM.
5651 Unfortunately Intel decided to ignore this. */
5652 if (arm_feature(env, ARM_FEATURE_XSCALE))
5654 if (insn & (1 << 20))
5655 return disas_cp14_read(env, s, insn);
5657 return disas_cp14_write(env, s, insn);
5659 return disas_cp15_insn (env, s, insn);
5662 /* Unknown coprocessor. See if the board has hooked it. */
5663 return disas_cp_insn (env, s, insn);
5668 /* Store a 64-bit value to a register pair. Clobbers val. */
5669 static void gen_storeq_reg(DisasContext *s, int rlow, int rhigh, TCGv_i64 val)
5673 tcg_gen_trunc_i64_i32(tmp, val);
5674 store_reg(s, rlow, tmp);
5676 tcg_gen_shri_i64(val, val, 32);
5677 tcg_gen_trunc_i64_i32(tmp, val);
5678 store_reg(s, rhigh, tmp);
5681 /* load a 32-bit value from a register and perform a 64-bit accumulate. */
5682 static void gen_addq_lo(DisasContext *s, TCGv_i64 val, int rlow)
5687 /* Load value and extend to 64 bits. */
5688 tmp = tcg_temp_new_i64();
5689 tmp2 = load_reg(s, rlow);
5690 tcg_gen_extu_i32_i64(tmp, tmp2);
5692 tcg_gen_add_i64(val, val, tmp);
5695 /* load and add a 64-bit value from a register pair. */
5696 static void gen_addq(DisasContext *s, TCGv_i64 val, int rlow, int rhigh)
5702 /* Load 64-bit value rd:rn. */
5703 tmpl = load_reg(s, rlow);
5704 tmph = load_reg(s, rhigh);
5705 tmp = tcg_temp_new_i64();
5706 tcg_gen_concat_i32_i64(tmp, tmpl, tmph);
5709 tcg_gen_add_i64(val, val, tmp);
5712 /* Set N and Z flags from a 64-bit value. */
5713 static void gen_logicq_cc(TCGv_i64 val)
5715 TCGv tmp = new_tmp();
5716 gen_helper_logicq_cc(tmp, val);
5721 static void disas_arm_insn(CPUState * env, DisasContext *s)
5723 unsigned int cond, insn, val, op1, i, shift, rm, rs, rn, rd, sh;
5730 insn = ldl_code(s->pc);
5733 /* M variants do not implement ARM mode. */
5738 /* Unconditional instructions. */
5739 if (((insn >> 25) & 7) == 1) {
5740 /* NEON Data processing. */
5741 if (!arm_feature(env, ARM_FEATURE_NEON))
5744 if (disas_neon_data_insn(env, s, insn))
5748 if ((insn & 0x0f100000) == 0x04000000) {
5749 /* NEON load/store. */
5750 if (!arm_feature(env, ARM_FEATURE_NEON))
5753 if (disas_neon_ls_insn(env, s, insn))
5757 if ((insn & 0x0d70f000) == 0x0550f000)
5759 else if ((insn & 0x0ffffdff) == 0x01010000) {
5762 if (insn & (1 << 9)) {
5763 /* BE8 mode not implemented. */
5767 } else if ((insn & 0x0fffff00) == 0x057ff000) {
5768 switch ((insn >> 4) & 0xf) {
5771 gen_helper_clrex(cpu_env);
5777 /* We don't emulate caches so these are a no-op. */
5782 } else if ((insn & 0x0e5fffe0) == 0x084d0500) {
5788 op1 = (insn & 0x1f);
5789 if (op1 == (env->uncached_cpsr & CPSR_M)) {
5790 addr = load_reg(s, 13);
5793 gen_helper_get_r13_banked(addr, cpu_env, tcg_const_i32(op1));
5795 i = (insn >> 23) & 3;
5797 case 0: offset = -4; break; /* DA */
5798 case 1: offset = -8; break; /* DB */
5799 case 2: offset = 0; break; /* IA */
5800 case 3: offset = 4; break; /* IB */
5804 tcg_gen_addi_i32(addr, addr, offset);
5805 tmp = load_reg(s, 14);
5806 gen_st32(tmp, addr, 0);
5808 gen_helper_cpsr_read(tmp);
5809 tcg_gen_addi_i32(addr, addr, 4);
5810 gen_st32(tmp, addr, 0);
5811 if (insn & (1 << 21)) {
5812 /* Base writeback. */
5814 case 0: offset = -8; break;
5815 case 1: offset = -4; break;
5816 case 2: offset = 4; break;
5817 case 3: offset = 0; break;
5821 tcg_gen_addi_i32(addr, tmp, offset);
5822 if (op1 == (env->uncached_cpsr & CPSR_M)) {
5823 gen_movl_reg_T1(s, 13);
5825 gen_helper_set_r13_banked(cpu_env, tcg_const_i32(op1), cpu_T[1]);
5830 } else if ((insn & 0x0e5fffe0) == 0x081d0a00) {
5836 rn = (insn >> 16) & 0xf;
5837 addr = load_reg(s, rn);
5838 i = (insn >> 23) & 3;
5840 case 0: offset = -4; break; /* DA */
5841 case 1: offset = -8; break; /* DB */
5842 case 2: offset = 0; break; /* IA */
5843 case 3: offset = 4; break; /* IB */
5847 tcg_gen_addi_i32(addr, addr, offset);
5848 /* Load PC into tmp and CPSR into tmp2. */
5849 tmp = gen_ld32(addr, 0);
5850 tcg_gen_addi_i32(addr, addr, 4);
5851 tmp2 = gen_ld32(addr, 0);
5852 if (insn & (1 << 21)) {
5853 /* Base writeback. */
5855 case 0: offset = -8; break;
5856 case 1: offset = -4; break;
5857 case 2: offset = 4; break;
5858 case 3: offset = 0; break;
5862 tcg_gen_addi_i32(addr, addr, offset);
5863 store_reg(s, rn, addr);
5867 gen_rfe(s, tmp, tmp2);
5868 } else if ((insn & 0x0e000000) == 0x0a000000) {
5869 /* branch link and change to thumb (blx <offset>) */
5872 val = (uint32_t)s->pc;
5874 tcg_gen_movi_i32(tmp, val);
5875 store_reg(s, 14, tmp);
5876 /* Sign-extend the 24-bit offset */
5877 offset = (((int32_t)insn) << 8) >> 8;
5878 /* offset * 4 + bit24 * 2 + (thumb bit) */
5879 val += (offset << 2) | ((insn >> 23) & 2) | 1;
5880 /* pipeline offset */
5884 } else if ((insn & 0x0e000f00) == 0x0c000100) {
5885 if (arm_feature(env, ARM_FEATURE_IWMMXT)) {
5886 /* iWMMXt register transfer. */
5887 if (env->cp15.c15_cpar & (1 << 1))
5888 if (!disas_iwmmxt_insn(env, s, insn))
5891 } else if ((insn & 0x0fe00000) == 0x0c400000) {
5892 /* Coprocessor double register transfer. */
5893 } else if ((insn & 0x0f000010) == 0x0e000010) {
5894 /* Additional coprocessor register transfer. */
5895 } else if ((insn & 0x0ff10020) == 0x01000000) {
5898 /* cps (privileged) */
5902 if (insn & (1 << 19)) {
5903 if (insn & (1 << 8))
5905 if (insn & (1 << 7))
5907 if (insn & (1 << 6))
5909 if (insn & (1 << 18))
5912 if (insn & (1 << 17)) {
5914 val |= (insn & 0x1f);
5917 gen_op_movl_T0_im(val);
5918 gen_set_psr_T0(s, mask, 0);
5925 /* if not always execute, we generate a conditional jump to
5927 s->condlabel = gen_new_label();
5928 gen_test_cc(cond ^ 1, s->condlabel);
5931 if ((insn & 0x0f900000) == 0x03000000) {
5932 if ((insn & (1 << 21)) == 0) {
5934 rd = (insn >> 12) & 0xf;
5935 val = ((insn >> 4) & 0xf000) | (insn & 0xfff);
5936 if ((insn & (1 << 22)) == 0) {
5939 tcg_gen_movi_i32(tmp, val);
5942 tmp = load_reg(s, rd);
5943 tcg_gen_ext16u_i32(tmp, tmp);
5944 tcg_gen_ori_i32(tmp, tmp, val << 16);
5946 store_reg(s, rd, tmp);
5948 if (((insn >> 12) & 0xf) != 0xf)
5950 if (((insn >> 16) & 0xf) == 0) {
5951 gen_nop_hint(s, insn & 0xff);
5953 /* CPSR = immediate */
5955 shift = ((insn >> 8) & 0xf) * 2;
5957 val = (val >> shift) | (val << (32 - shift));
5958 gen_op_movl_T0_im(val);
5959 i = ((insn & (1 << 22)) != 0);
5960 if (gen_set_psr_T0(s, msr_mask(env, s, (insn >> 16) & 0xf, i), i))
5964 } else if ((insn & 0x0f900000) == 0x01000000
5965 && (insn & 0x00000090) != 0x00000090) {
5966 /* miscellaneous instructions */
5967 op1 = (insn >> 21) & 3;
5968 sh = (insn >> 4) & 0xf;
5971 case 0x0: /* move program status register */
5974 gen_movl_T0_reg(s, rm);
5975 i = ((op1 & 2) != 0);
5976 if (gen_set_psr_T0(s, msr_mask(env, s, (insn >> 16) & 0xf, i), i))
5980 rd = (insn >> 12) & 0xf;
5984 tmp = load_cpu_field(spsr);
5987 gen_helper_cpsr_read(tmp);
5989 store_reg(s, rd, tmp);
5994 /* branch/exchange thumb (bx). */
5995 tmp = load_reg(s, rm);
5997 } else if (op1 == 3) {
5999 rd = (insn >> 12) & 0xf;
6000 tmp = load_reg(s, rm);
6001 gen_helper_clz(tmp, tmp);
6002 store_reg(s, rd, tmp);
6010 /* Trivial implementation equivalent to bx. */
6011 tmp = load_reg(s, rm);
6021 /* branch link/exchange thumb (blx) */
6022 tmp = load_reg(s, rm);
6024 tcg_gen_movi_i32(tmp2, s->pc);
6025 store_reg(s, 14, tmp2);
6028 case 0x5: /* saturating add/subtract */
6029 rd = (insn >> 12) & 0xf;
6030 rn = (insn >> 16) & 0xf;
6031 tmp = load_reg(s, rm);
6032 tmp2 = load_reg(s, rn);
6034 gen_helper_double_saturate(tmp2, tmp2);
6036 gen_helper_sub_saturate(tmp, tmp, tmp2);
6038 gen_helper_add_saturate(tmp, tmp, tmp2);
6040 store_reg(s, rd, tmp);
6045 gen_set_condexec(s);
6046 gen_set_pc_im(s->pc - 4);
6047 gen_exception(EXCP_BKPT);
6048 s->is_jmp = DISAS_JUMP;
6049 } else if (op1 == 3) {
6051 if (!(env->cp15.c0_c2[4] & 0xf000) || IS_USER(s))
6053 /* TODO: real implementation; execute as NOP for now */
6054 /*fprintf(stderr, "smc [0x%08x] pc=0x%08x\n", insn, s->pc);*/
6059 case 0x8: /* signed multiply */
6063 rs = (insn >> 8) & 0xf;
6064 rn = (insn >> 12) & 0xf;
6065 rd = (insn >> 16) & 0xf;
6067 /* (32 * 16) >> 16 */
6068 tmp = load_reg(s, rm);
6069 tmp2 = load_reg(s, rs);
6071 tcg_gen_sari_i32(tmp2, tmp2, 16);
6074 tmp64 = gen_muls_i64_i32(tmp, tmp2);
6075 tcg_gen_shri_i64(tmp64, tmp64, 16);
6077 tcg_gen_trunc_i64_i32(tmp, tmp64);
6078 if ((sh & 2) == 0) {
6079 tmp2 = load_reg(s, rn);
6080 gen_helper_add_setq(tmp, tmp, tmp2);
6083 store_reg(s, rd, tmp);
6086 tmp = load_reg(s, rm);
6087 tmp2 = load_reg(s, rs);
6088 gen_mulxy(tmp, tmp2, sh & 2, sh & 4);
6091 tmp64 = tcg_temp_new_i64();
6092 tcg_gen_ext_i32_i64(tmp64, tmp);
6094 gen_addq(s, tmp64, rn, rd);
6095 gen_storeq_reg(s, rn, rd, tmp64);
6098 tmp2 = load_reg(s, rn);
6099 gen_helper_add_setq(tmp, tmp, tmp2);
6102 store_reg(s, rd, tmp);
6109 } else if (((insn & 0x0e000000) == 0 &&
6110 (insn & 0x00000090) != 0x90) ||
6111 ((insn & 0x0e000000) == (1 << 25))) {
6112 int set_cc, logic_cc, shiftop;
6114 op1 = (insn >> 21) & 0xf;
6115 set_cc = (insn >> 20) & 1;
6116 logic_cc = table_logic_cc[op1] & set_cc;
6118 /* data processing instruction */
6119 if (insn & (1 << 25)) {
6120 /* immediate operand */
6122 shift = ((insn >> 8) & 0xf) * 2;
6124 val = (val >> shift) | (val << (32 - shift));
6127 tcg_gen_movi_i32(tmp2, val);
6128 if (logic_cc && shift) {
6129 gen_set_CF_bit31(tmp2);
6134 tmp2 = load_reg(s, rm);
6135 shiftop = (insn >> 5) & 3;
6136 if (!(insn & (1 << 4))) {
6137 shift = (insn >> 7) & 0x1f;
6138 gen_arm_shift_im(tmp2, shiftop, shift, logic_cc);
6140 rs = (insn >> 8) & 0xf;
6141 tmp = load_reg(s, rs);
6142 gen_arm_shift_reg(tmp2, shiftop, tmp, logic_cc);
6145 if (op1 != 0x0f && op1 != 0x0d) {
6146 rn = (insn >> 16) & 0xf;
6147 tmp = load_reg(s, rn);
6151 rd = (insn >> 12) & 0xf;
6154 tcg_gen_and_i32(tmp, tmp, tmp2);
6158 store_reg_bx(env, s, rd, tmp);
6161 tcg_gen_xor_i32(tmp, tmp, tmp2);
6165 store_reg_bx(env, s, rd, tmp);
6168 if (set_cc && rd == 15) {
6169 /* SUBS r15, ... is used for exception return. */
6173 gen_helper_sub_cc(tmp, tmp, tmp2);
6174 gen_exception_return(s, tmp);
6177 gen_helper_sub_cc(tmp, tmp, tmp2);
6179 tcg_gen_sub_i32(tmp, tmp, tmp2);
6181 store_reg_bx(env, s, rd, tmp);
6186 gen_helper_sub_cc(tmp, tmp2, tmp);
6188 tcg_gen_sub_i32(tmp, tmp2, tmp);
6190 store_reg_bx(env, s, rd, tmp);
6194 gen_helper_add_cc(tmp, tmp, tmp2);
6196 tcg_gen_add_i32(tmp, tmp, tmp2);
6198 store_reg_bx(env, s, rd, tmp);
6202 gen_helper_adc_cc(tmp, tmp, tmp2);
6204 gen_add_carry(tmp, tmp, tmp2);
6206 store_reg_bx(env, s, rd, tmp);
6210 gen_helper_sbc_cc(tmp, tmp, tmp2);
6212 gen_sub_carry(tmp, tmp, tmp2);
6214 store_reg_bx(env, s, rd, tmp);
6218 gen_helper_sbc_cc(tmp, tmp2, tmp);
6220 gen_sub_carry(tmp, tmp2, tmp);
6222 store_reg_bx(env, s, rd, tmp);
6226 tcg_gen_and_i32(tmp, tmp, tmp2);
6233 tcg_gen_xor_i32(tmp, tmp, tmp2);
6240 gen_helper_sub_cc(tmp, tmp, tmp2);
6246 gen_helper_add_cc(tmp, tmp, tmp2);
6251 tcg_gen_or_i32(tmp, tmp, tmp2);
6255 store_reg_bx(env, s, rd, tmp);
6258 if (logic_cc && rd == 15) {
6259 /* MOVS r15, ... is used for exception return. */
6263 gen_exception_return(s, tmp2);
6268 store_reg_bx(env, s, rd, tmp2);
6272 tcg_gen_bic_i32(tmp, tmp, tmp2);
6276 store_reg_bx(env, s, rd, tmp);
6280 tcg_gen_not_i32(tmp2, tmp2);
6284 store_reg_bx(env, s, rd, tmp2);
6287 if (op1 != 0x0f && op1 != 0x0d) {
6291 /* other instructions */
6292 op1 = (insn >> 24) & 0xf;
6296 /* multiplies, extra load/stores */
6297 sh = (insn >> 5) & 3;
6300 rd = (insn >> 16) & 0xf;
6301 rn = (insn >> 12) & 0xf;
6302 rs = (insn >> 8) & 0xf;
6304 op1 = (insn >> 20) & 0xf;
6306 case 0: case 1: case 2: case 3: case 6:
6308 tmp = load_reg(s, rs);
6309 tmp2 = load_reg(s, rm);
6310 tcg_gen_mul_i32(tmp, tmp, tmp2);
6312 if (insn & (1 << 22)) {
6313 /* Subtract (mls) */
6315 tmp2 = load_reg(s, rn);
6316 tcg_gen_sub_i32(tmp, tmp2, tmp);
6318 } else if (insn & (1 << 21)) {
6320 tmp2 = load_reg(s, rn);
6321 tcg_gen_add_i32(tmp, tmp, tmp2);
6324 if (insn & (1 << 20))
6326 store_reg(s, rd, tmp);
6330 tmp = load_reg(s, rs);
6331 tmp2 = load_reg(s, rm);
6332 if (insn & (1 << 22))
6333 tmp64 = gen_muls_i64_i32(tmp, tmp2);
6335 tmp64 = gen_mulu_i64_i32(tmp, tmp2);
6336 if (insn & (1 << 21)) /* mult accumulate */
6337 gen_addq(s, tmp64, rn, rd);
6338 if (!(insn & (1 << 23))) { /* double accumulate */
6340 gen_addq_lo(s, tmp64, rn);
6341 gen_addq_lo(s, tmp64, rd);
6343 if (insn & (1 << 20))
6344 gen_logicq_cc(tmp64);
6345 gen_storeq_reg(s, rn, rd, tmp64);
6349 rn = (insn >> 16) & 0xf;
6350 rd = (insn >> 12) & 0xf;
6351 if (insn & (1 << 23)) {
6352 /* load/store exclusive */
6353 op1 = (insn >> 21) & 0x3;
6358 gen_movl_T1_reg(s, rn);
6360 if (insn & (1 << 20)) {
6361 gen_helper_mark_exclusive(cpu_env, cpu_T[1]);
6364 tmp = gen_ld32(addr, IS_USER(s));
6366 case 1: /* ldrexd */
6367 tmp = gen_ld32(addr, IS_USER(s));
6368 store_reg(s, rd, tmp);
6369 tcg_gen_addi_i32(addr, addr, 4);
6370 tmp = gen_ld32(addr, IS_USER(s));
6373 case 2: /* ldrexb */
6374 tmp = gen_ld8u(addr, IS_USER(s));
6376 case 3: /* ldrexh */
6377 tmp = gen_ld16u(addr, IS_USER(s));
6382 store_reg(s, rd, tmp);
6384 int label = gen_new_label();
6386 gen_helper_test_exclusive(cpu_T[0], cpu_env, addr);
6387 tcg_gen_brcondi_i32(TCG_COND_NE, cpu_T[0],
6389 tmp = load_reg(s,rm);
6392 gen_st32(tmp, addr, IS_USER(s));
6394 case 1: /* strexd */
6395 gen_st32(tmp, addr, IS_USER(s));
6396 tcg_gen_addi_i32(addr, addr, 4);
6397 tmp = load_reg(s, rm + 1);
6398 gen_st32(tmp, addr, IS_USER(s));
6400 case 2: /* strexb */
6401 gen_st8(tmp, addr, IS_USER(s));
6403 case 3: /* strexh */
6404 gen_st16(tmp, addr, IS_USER(s));
6409 gen_set_label(label);
6410 gen_movl_reg_T0(s, rd);
6413 /* SWP instruction */
6416 /* ??? This is not really atomic. However we know
6417 we never have multiple CPUs running in parallel,
6418 so it is good enough. */
6419 addr = load_reg(s, rn);
6420 tmp = load_reg(s, rm);
6421 if (insn & (1 << 22)) {
6422 tmp2 = gen_ld8u(addr, IS_USER(s));
6423 gen_st8(tmp, addr, IS_USER(s));
6425 tmp2 = gen_ld32(addr, IS_USER(s));
6426 gen_st32(tmp, addr, IS_USER(s));
6429 store_reg(s, rd, tmp2);
6435 /* Misc load/store */
6436 rn = (insn >> 16) & 0xf;
6437 rd = (insn >> 12) & 0xf;
6438 addr = load_reg(s, rn);
6439 if (insn & (1 << 24))
6440 gen_add_datah_offset(s, insn, 0, addr);
6442 if (insn & (1 << 20)) {
6446 tmp = gen_ld16u(addr, IS_USER(s));
6449 tmp = gen_ld8s(addr, IS_USER(s));
6453 tmp = gen_ld16s(addr, IS_USER(s));
6457 } else if (sh & 2) {
6461 tmp = load_reg(s, rd);
6462 gen_st32(tmp, addr, IS_USER(s));
6463 tcg_gen_addi_i32(addr, addr, 4);
6464 tmp = load_reg(s, rd + 1);
6465 gen_st32(tmp, addr, IS_USER(s));
6469 tmp = gen_ld32(addr, IS_USER(s));
6470 store_reg(s, rd, tmp);
6471 tcg_gen_addi_i32(addr, addr, 4);
6472 tmp = gen_ld32(addr, IS_USER(s));
6476 address_offset = -4;
6479 tmp = load_reg(s, rd);
6480 gen_st16(tmp, addr, IS_USER(s));
6483 /* Perform base writeback before the loaded value to
6484 ensure correct behavior with overlapping index registers.
6485 ldrd with base writeback is is undefined if the
6486 destination and index registers overlap. */
6487 if (!(insn & (1 << 24))) {
6488 gen_add_datah_offset(s, insn, address_offset, addr);
6489 store_reg(s, rn, addr);
6490 } else if (insn & (1 << 21)) {
6492 tcg_gen_addi_i32(addr, addr, address_offset);
6493 store_reg(s, rn, addr);
6498 /* Complete the load. */
6499 store_reg(s, rd, tmp);
6508 if (insn & (1 << 4)) {
6510 /* Armv6 Media instructions. */
6512 rn = (insn >> 16) & 0xf;
6513 rd = (insn >> 12) & 0xf;
6514 rs = (insn >> 8) & 0xf;
6515 switch ((insn >> 23) & 3) {
6516 case 0: /* Parallel add/subtract. */
6517 op1 = (insn >> 20) & 7;
6518 tmp = load_reg(s, rn);
6519 tmp2 = load_reg(s, rm);
6520 sh = (insn >> 5) & 7;
6521 if ((op1 & 3) == 0 || sh == 5 || sh == 6)
6523 gen_arm_parallel_addsub(op1, sh, tmp, tmp2);
6525 store_reg(s, rd, tmp);
6528 if ((insn & 0x00700020) == 0) {
6529 /* Halfword pack. */
6530 tmp = load_reg(s, rn);
6531 tmp2 = load_reg(s, rm);
6532 shift = (insn >> 7) & 0x1f;
6533 if (insn & (1 << 6)) {
6537 tcg_gen_sari_i32(tmp2, tmp2, shift);
6538 tcg_gen_andi_i32(tmp, tmp, 0xffff0000);
6539 tcg_gen_ext16u_i32(tmp2, tmp2);
6543 tcg_gen_shli_i32(tmp2, tmp2, shift);
6544 tcg_gen_ext16u_i32(tmp, tmp);
6545 tcg_gen_andi_i32(tmp2, tmp2, 0xffff0000);
6547 tcg_gen_or_i32(tmp, tmp, tmp2);
6549 store_reg(s, rd, tmp);
6550 } else if ((insn & 0x00200020) == 0x00200000) {
6552 tmp = load_reg(s, rm);
6553 shift = (insn >> 7) & 0x1f;
6554 if (insn & (1 << 6)) {
6557 tcg_gen_sari_i32(tmp, tmp, shift);
6559 tcg_gen_shli_i32(tmp, tmp, shift);
6561 sh = (insn >> 16) & 0x1f;
6563 if (insn & (1 << 22))
6564 gen_helper_usat(tmp, tmp, tcg_const_i32(sh));
6566 gen_helper_ssat(tmp, tmp, tcg_const_i32(sh));
6568 store_reg(s, rd, tmp);
6569 } else if ((insn & 0x00300fe0) == 0x00200f20) {
6571 tmp = load_reg(s, rm);
6572 sh = (insn >> 16) & 0x1f;
6574 if (insn & (1 << 22))
6575 gen_helper_usat16(tmp, tmp, tcg_const_i32(sh));
6577 gen_helper_ssat16(tmp, tmp, tcg_const_i32(sh));
6579 store_reg(s, rd, tmp);
6580 } else if ((insn & 0x00700fe0) == 0x00000fa0) {
6582 tmp = load_reg(s, rn);
6583 tmp2 = load_reg(s, rm);
6585 tcg_gen_ld_i32(tmp3, cpu_env, offsetof(CPUState, GE));
6586 gen_helper_sel_flags(tmp, tmp3, tmp, tmp2);
6589 store_reg(s, rd, tmp);
6590 } else if ((insn & 0x000003e0) == 0x00000060) {
6591 tmp = load_reg(s, rm);
6592 shift = (insn >> 10) & 3;
6593 /* ??? In many cases it's not neccessary to do a
6594 rotate, a shift is sufficient. */
6596 tcg_gen_rori_i32(tmp, tmp, shift * 8);
6597 op1 = (insn >> 20) & 7;
6599 case 0: gen_sxtb16(tmp); break;
6600 case 2: gen_sxtb(tmp); break;
6601 case 3: gen_sxth(tmp); break;
6602 case 4: gen_uxtb16(tmp); break;
6603 case 6: gen_uxtb(tmp); break;
6604 case 7: gen_uxth(tmp); break;
6605 default: goto illegal_op;
6608 tmp2 = load_reg(s, rn);
6609 if ((op1 & 3) == 0) {
6610 gen_add16(tmp, tmp2);
6612 tcg_gen_add_i32(tmp, tmp, tmp2);
6616 store_reg(s, rd, tmp);
6617 } else if ((insn & 0x003f0f60) == 0x003f0f20) {
6619 tmp = load_reg(s, rm);
6620 if (insn & (1 << 22)) {
6621 if (insn & (1 << 7)) {
6625 gen_helper_rbit(tmp, tmp);
6628 if (insn & (1 << 7))
6631 tcg_gen_bswap32_i32(tmp, tmp);
6633 store_reg(s, rd, tmp);
6638 case 2: /* Multiplies (Type 3). */
6639 tmp = load_reg(s, rm);
6640 tmp2 = load_reg(s, rs);
6641 if (insn & (1 << 20)) {
6642 /* Signed multiply most significant [accumulate]. */
6643 tmp64 = gen_muls_i64_i32(tmp, tmp2);
6644 if (insn & (1 << 5))
6645 tcg_gen_addi_i64(tmp64, tmp64, 0x80000000u);
6646 tcg_gen_shri_i64(tmp64, tmp64, 32);
6648 tcg_gen_trunc_i64_i32(tmp, tmp64);
6650 tmp2 = load_reg(s, rd);
6651 if (insn & (1 << 6)) {
6652 tcg_gen_sub_i32(tmp, tmp, tmp2);
6654 tcg_gen_add_i32(tmp, tmp, tmp2);
6658 store_reg(s, rn, tmp);
6660 if (insn & (1 << 5))
6661 gen_swap_half(tmp2);
6662 gen_smul_dual(tmp, tmp2);
6663 /* This addition cannot overflow. */
6664 if (insn & (1 << 6)) {
6665 tcg_gen_sub_i32(tmp, tmp, tmp2);
6667 tcg_gen_add_i32(tmp, tmp, tmp2);
6670 if (insn & (1 << 22)) {
6671 /* smlald, smlsld */
6672 tmp64 = tcg_temp_new_i64();
6673 tcg_gen_ext_i32_i64(tmp64, tmp);
6675 gen_addq(s, tmp64, rd, rn);
6676 gen_storeq_reg(s, rd, rn, tmp64);
6678 /* smuad, smusd, smlad, smlsd */
6681 tmp2 = load_reg(s, rd);
6682 gen_helper_add_setq(tmp, tmp, tmp2);
6685 store_reg(s, rn, tmp);
6690 op1 = ((insn >> 17) & 0x38) | ((insn >> 5) & 7);
6692 case 0: /* Unsigned sum of absolute differences. */
6694 tmp = load_reg(s, rm);
6695 tmp2 = load_reg(s, rs);
6696 gen_helper_usad8(tmp, tmp, tmp2);
6699 tmp2 = load_reg(s, rd);
6700 tcg_gen_add_i32(tmp, tmp, tmp2);
6703 store_reg(s, rn, tmp);
6705 case 0x20: case 0x24: case 0x28: case 0x2c:
6706 /* Bitfield insert/clear. */
6708 shift = (insn >> 7) & 0x1f;
6709 i = (insn >> 16) & 0x1f;
6713 tcg_gen_movi_i32(tmp, 0);
6715 tmp = load_reg(s, rm);
6718 tmp2 = load_reg(s, rd);
6719 gen_bfi(tmp, tmp2, tmp, shift, (1u << i) - 1);
6722 store_reg(s, rd, tmp);
6724 case 0x12: case 0x16: case 0x1a: case 0x1e: /* sbfx */
6725 case 0x32: case 0x36: case 0x3a: case 0x3e: /* ubfx */
6727 tmp = load_reg(s, rm);
6728 shift = (insn >> 7) & 0x1f;
6729 i = ((insn >> 16) & 0x1f) + 1;
6734 gen_ubfx(tmp, shift, (1u << i) - 1);
6736 gen_sbfx(tmp, shift, i);
6739 store_reg(s, rd, tmp);
6749 /* Check for undefined extension instructions
6750 * per the ARM Bible IE:
6751 * xxxx 0111 1111 xxxx xxxx xxxx 1111 xxxx
6753 sh = (0xf << 20) | (0xf << 4);
6754 if (op1 == 0x7 && ((insn & sh) == sh))
6758 /* load/store byte/word */
6759 rn = (insn >> 16) & 0xf;
6760 rd = (insn >> 12) & 0xf;
6761 tmp2 = load_reg(s, rn);
6762 i = (IS_USER(s) || (insn & 0x01200000) == 0x00200000);
6763 if (insn & (1 << 24))
6764 gen_add_data_offset(s, insn, tmp2);
6765 if (insn & (1 << 20)) {
6767 if (insn & (1 << 22)) {
6768 tmp = gen_ld8u(tmp2, i);
6770 tmp = gen_ld32(tmp2, i);
6774 tmp = load_reg(s, rd);
6775 if (insn & (1 << 22))
6776 gen_st8(tmp, tmp2, i);
6778 gen_st32(tmp, tmp2, i);
6780 if (!(insn & (1 << 24))) {
6781 gen_add_data_offset(s, insn, tmp2);
6782 store_reg(s, rn, tmp2);
6783 } else if (insn & (1 << 21)) {
6784 store_reg(s, rn, tmp2);
6788 if (insn & (1 << 20)) {
6789 /* Complete the load. */
6793 store_reg(s, rd, tmp);
6799 int j, n, user, loaded_base;
6801 /* load/store multiple words */
6802 /* XXX: store correct base if write back */
6804 if (insn & (1 << 22)) {
6806 goto illegal_op; /* only usable in supervisor mode */
6808 if ((insn & (1 << 15)) == 0)
6811 rn = (insn >> 16) & 0xf;
6812 addr = load_reg(s, rn);
6814 /* compute total size */
6816 TCGV_UNUSED(loaded_var);
6819 if (insn & (1 << i))
6822 /* XXX: test invalid n == 0 case ? */
6823 if (insn & (1 << 23)) {
6824 if (insn & (1 << 24)) {
6826 tcg_gen_addi_i32(addr, addr, 4);
6828 /* post increment */
6831 if (insn & (1 << 24)) {
6833 tcg_gen_addi_i32(addr, addr, -(n * 4));
6835 /* post decrement */
6837 tcg_gen_addi_i32(addr, addr, -((n - 1) * 4));
6842 if (insn & (1 << i)) {
6843 if (insn & (1 << 20)) {
6845 tmp = gen_ld32(addr, IS_USER(s));
6849 gen_helper_set_user_reg(tcg_const_i32(i), tmp);
6851 } else if (i == rn) {
6855 store_reg(s, i, tmp);
6860 /* special case: r15 = PC + 8 */
6861 val = (long)s->pc + 4;
6863 tcg_gen_movi_i32(tmp, val);
6866 gen_helper_get_user_reg(tmp, tcg_const_i32(i));
6868 tmp = load_reg(s, i);
6870 gen_st32(tmp, addr, IS_USER(s));
6873 /* no need to add after the last transfer */
6875 tcg_gen_addi_i32(addr, addr, 4);
6878 if (insn & (1 << 21)) {
6880 if (insn & (1 << 23)) {
6881 if (insn & (1 << 24)) {
6884 /* post increment */
6885 tcg_gen_addi_i32(addr, addr, 4);
6888 if (insn & (1 << 24)) {
6891 tcg_gen_addi_i32(addr, addr, -((n - 1) * 4));
6893 /* post decrement */
6894 tcg_gen_addi_i32(addr, addr, -(n * 4));
6897 store_reg(s, rn, addr);
6902 store_reg(s, rn, loaded_var);
6904 if ((insn & (1 << 22)) && !user) {
6905 /* Restore CPSR from SPSR. */
6906 tmp = load_cpu_field(spsr);
6907 gen_set_cpsr(tmp, 0xffffffff);
6909 s->is_jmp = DISAS_UPDATE;
6918 /* branch (and link) */
6919 val = (int32_t)s->pc;
6920 if (insn & (1 << 24)) {
6922 tcg_gen_movi_i32(tmp, val);
6923 store_reg(s, 14, tmp);
6925 offset = (((int32_t)insn << 8) >> 8);
6926 val += (offset << 2) + 4;
6934 if (disas_coproc_insn(env, s, insn))
6939 gen_set_pc_im(s->pc);
6940 s->is_jmp = DISAS_SWI;
6944 gen_set_condexec(s);
6945 gen_set_pc_im(s->pc - 4);
6946 gen_exception(EXCP_UDEF);
6947 s->is_jmp = DISAS_JUMP;
6953 /* Return true if this is a Thumb-2 logical op. */
6955 thumb2_logic_op(int op)
6960 /* Generate code for a Thumb-2 data processing operation. If CONDS is nonzero
6961 then set condition code flags based on the result of the operation.
6962 If SHIFTER_OUT is nonzero then set the carry flag for logical operations
6963 to the high bit of T1.
6964 Returns zero if the opcode is valid. */
6967 gen_thumb2_data_op(DisasContext *s, int op, int conds, uint32_t shifter_out)
6974 gen_op_andl_T0_T1();
6978 gen_op_bicl_T0_T1();
6991 gen_op_xorl_T0_T1();
6996 gen_op_addl_T0_T1_cc();
6998 gen_op_addl_T0_T1();
7002 gen_op_adcl_T0_T1_cc();
7008 gen_op_sbcl_T0_T1_cc();
7014 gen_op_subl_T0_T1_cc();
7016 gen_op_subl_T0_T1();
7020 gen_op_rsbl_T0_T1_cc();
7022 gen_op_rsbl_T0_T1();
7024 default: /* 5, 6, 7, 9, 12, 15. */
7028 gen_op_logic_T0_cc();
7030 gen_set_CF_bit31(cpu_T[1]);
7035 /* Translate a 32-bit thumb instruction. Returns nonzero if the instruction
7037 static int disas_thumb2_insn(CPUState *env, DisasContext *s, uint16_t insn_hw1)
7039 uint32_t insn, imm, shift, offset;
7040 uint32_t rd, rn, rm, rs;
7051 if (!(arm_feature(env, ARM_FEATURE_THUMB2)
7052 || arm_feature (env, ARM_FEATURE_M))) {
7053 /* Thumb-1 cores may need to treat bl and blx as a pair of
7054 16-bit instructions to get correct prefetch abort behavior. */
7056 if ((insn & (1 << 12)) == 0) {
7057 /* Second half of blx. */
7058 offset = ((insn & 0x7ff) << 1);
7059 tmp = load_reg(s, 14);
7060 tcg_gen_addi_i32(tmp, tmp, offset);
7061 tcg_gen_andi_i32(tmp, tmp, 0xfffffffc);
7064 tcg_gen_movi_i32(tmp2, s->pc | 1);
7065 store_reg(s, 14, tmp2);
7069 if (insn & (1 << 11)) {
7070 /* Second half of bl. */
7071 offset = ((insn & 0x7ff) << 1) | 1;
7072 tmp = load_reg(s, 14);
7073 tcg_gen_addi_i32(tmp, tmp, offset);
7076 tcg_gen_movi_i32(tmp2, s->pc | 1);
7077 store_reg(s, 14, tmp2);
7081 if ((s->pc & ~TARGET_PAGE_MASK) == 0) {
7082 /* Instruction spans a page boundary. Implement it as two
7083 16-bit instructions in case the second half causes an
7085 offset = ((int32_t)insn << 21) >> 9;
7086 gen_op_movl_T0_im(s->pc + 2 + offset);
7087 gen_movl_reg_T0(s, 14);
7090 /* Fall through to 32-bit decode. */
7093 insn = lduw_code(s->pc);
7095 insn |= (uint32_t)insn_hw1 << 16;
7097 if ((insn & 0xf800e800) != 0xf000e800) {
7101 rn = (insn >> 16) & 0xf;
7102 rs = (insn >> 12) & 0xf;
7103 rd = (insn >> 8) & 0xf;
7105 switch ((insn >> 25) & 0xf) {
7106 case 0: case 1: case 2: case 3:
7107 /* 16-bit instructions. Should never happen. */
7110 if (insn & (1 << 22)) {
7111 /* Other load/store, table branch. */
7112 if (insn & 0x01200000) {
7113 /* Load/store doubleword. */
7116 tcg_gen_movi_i32(addr, s->pc & ~3);
7118 addr = load_reg(s, rn);
7120 offset = (insn & 0xff) * 4;
7121 if ((insn & (1 << 23)) == 0)
7123 if (insn & (1 << 24)) {
7124 tcg_gen_addi_i32(addr, addr, offset);
7127 if (insn & (1 << 20)) {
7129 tmp = gen_ld32(addr, IS_USER(s));
7130 store_reg(s, rs, tmp);
7131 tcg_gen_addi_i32(addr, addr, 4);
7132 tmp = gen_ld32(addr, IS_USER(s));
7133 store_reg(s, rd, tmp);
7136 tmp = load_reg(s, rs);
7137 gen_st32(tmp, addr, IS_USER(s));
7138 tcg_gen_addi_i32(addr, addr, 4);
7139 tmp = load_reg(s, rd);
7140 gen_st32(tmp, addr, IS_USER(s));
7142 if (insn & (1 << 21)) {
7143 /* Base writeback. */
7146 tcg_gen_addi_i32(addr, addr, offset - 4);
7147 store_reg(s, rn, addr);
7151 } else if ((insn & (1 << 23)) == 0) {
7152 /* Load/store exclusive word. */
7153 gen_movl_T1_reg(s, rn);
7155 if (insn & (1 << 20)) {
7156 gen_helper_mark_exclusive(cpu_env, cpu_T[1]);
7157 tmp = gen_ld32(addr, IS_USER(s));
7158 store_reg(s, rd, tmp);
7160 int label = gen_new_label();
7161 gen_helper_test_exclusive(cpu_T[0], cpu_env, addr);
7162 tcg_gen_brcondi_i32(TCG_COND_NE, cpu_T[0],
7164 tmp = load_reg(s, rs);
7165 gen_st32(tmp, cpu_T[1], IS_USER(s));
7166 gen_set_label(label);
7167 gen_movl_reg_T0(s, rd);
7169 } else if ((insn & (1 << 6)) == 0) {
7173 tcg_gen_movi_i32(addr, s->pc);
7175 addr = load_reg(s, rn);
7177 tmp = load_reg(s, rm);
7178 tcg_gen_add_i32(addr, addr, tmp);
7179 if (insn & (1 << 4)) {
7181 tcg_gen_add_i32(addr, addr, tmp);
7183 tmp = gen_ld16u(addr, IS_USER(s));
7186 tmp = gen_ld8u(addr, IS_USER(s));
7189 tcg_gen_shli_i32(tmp, tmp, 1);
7190 tcg_gen_addi_i32(tmp, tmp, s->pc);
7191 store_reg(s, 15, tmp);
7193 /* Load/store exclusive byte/halfword/doubleword. */
7194 /* ??? These are not really atomic. However we know
7195 we never have multiple CPUs running in parallel,
7196 so it is good enough. */
7197 op = (insn >> 4) & 0x3;
7198 /* Must use a global reg for the address because we have
7199 a conditional branch in the store instruction. */
7200 gen_movl_T1_reg(s, rn);
7202 if (insn & (1 << 20)) {
7203 gen_helper_mark_exclusive(cpu_env, addr);
7206 tmp = gen_ld8u(addr, IS_USER(s));
7209 tmp = gen_ld16u(addr, IS_USER(s));
7212 tmp = gen_ld32(addr, IS_USER(s));
7213 tcg_gen_addi_i32(addr, addr, 4);
7214 tmp2 = gen_ld32(addr, IS_USER(s));
7215 store_reg(s, rd, tmp2);
7220 store_reg(s, rs, tmp);
7222 int label = gen_new_label();
7223 /* Must use a global that is not killed by the branch. */
7224 gen_helper_test_exclusive(cpu_T[0], cpu_env, addr);
7225 tcg_gen_brcondi_i32(TCG_COND_NE, cpu_T[0], 0, label);
7226 tmp = load_reg(s, rs);
7229 gen_st8(tmp, addr, IS_USER(s));
7232 gen_st16(tmp, addr, IS_USER(s));
7235 gen_st32(tmp, addr, IS_USER(s));
7236 tcg_gen_addi_i32(addr, addr, 4);
7237 tmp = load_reg(s, rd);
7238 gen_st32(tmp, addr, IS_USER(s));
7243 gen_set_label(label);
7244 gen_movl_reg_T0(s, rm);
7248 /* Load/store multiple, RFE, SRS. */
7249 if (((insn >> 23) & 1) == ((insn >> 24) & 1)) {
7250 /* Not available in user mode. */
7253 if (insn & (1 << 20)) {
7255 addr = load_reg(s, rn);
7256 if ((insn & (1 << 24)) == 0)
7257 tcg_gen_addi_i32(addr, addr, -8);
7258 /* Load PC into tmp and CPSR into tmp2. */
7259 tmp = gen_ld32(addr, 0);
7260 tcg_gen_addi_i32(addr, addr, 4);
7261 tmp2 = gen_ld32(addr, 0);
7262 if (insn & (1 << 21)) {
7263 /* Base writeback. */
7264 if (insn & (1 << 24)) {
7265 tcg_gen_addi_i32(addr, addr, 4);
7267 tcg_gen_addi_i32(addr, addr, -4);
7269 store_reg(s, rn, addr);
7273 gen_rfe(s, tmp, tmp2);
7277 if (op == (env->uncached_cpsr & CPSR_M)) {
7278 addr = load_reg(s, 13);
7281 gen_helper_get_r13_banked(addr, cpu_env, tcg_const_i32(op));
7283 if ((insn & (1 << 24)) == 0) {
7284 tcg_gen_addi_i32(addr, addr, -8);
7286 tmp = load_reg(s, 14);
7287 gen_st32(tmp, addr, 0);
7288 tcg_gen_addi_i32(addr, addr, 4);
7290 gen_helper_cpsr_read(tmp);
7291 gen_st32(tmp, addr, 0);
7292 if (insn & (1 << 21)) {
7293 if ((insn & (1 << 24)) == 0) {
7294 tcg_gen_addi_i32(addr, addr, -4);
7296 tcg_gen_addi_i32(addr, addr, 4);
7298 if (op == (env->uncached_cpsr & CPSR_M)) {
7299 store_reg(s, 13, addr);
7301 gen_helper_set_r13_banked(cpu_env,
7302 tcg_const_i32(op), addr);
7310 /* Load/store multiple. */
7311 addr = load_reg(s, rn);
7313 for (i = 0; i < 16; i++) {
7314 if (insn & (1 << i))
7317 if (insn & (1 << 24)) {
7318 tcg_gen_addi_i32(addr, addr, -offset);
7321 for (i = 0; i < 16; i++) {
7322 if ((insn & (1 << i)) == 0)
7324 if (insn & (1 << 20)) {
7326 tmp = gen_ld32(addr, IS_USER(s));
7330 store_reg(s, i, tmp);
7334 tmp = load_reg(s, i);
7335 gen_st32(tmp, addr, IS_USER(s));
7337 tcg_gen_addi_i32(addr, addr, 4);
7339 if (insn & (1 << 21)) {
7340 /* Base register writeback. */
7341 if (insn & (1 << 24)) {
7342 tcg_gen_addi_i32(addr, addr, -offset);
7344 /* Fault if writeback register is in register list. */
7345 if (insn & (1 << rn))
7347 store_reg(s, rn, addr);
7354 case 5: /* Data processing register constant shift. */
7356 gen_op_movl_T0_im(0);
7358 gen_movl_T0_reg(s, rn);
7359 gen_movl_T1_reg(s, rm);
7360 op = (insn >> 21) & 0xf;
7361 shiftop = (insn >> 4) & 3;
7362 shift = ((insn >> 6) & 3) | ((insn >> 10) & 0x1c);
7363 conds = (insn & (1 << 20)) != 0;
7364 logic_cc = (conds && thumb2_logic_op(op));
7365 gen_arm_shift_im(cpu_T[1], shiftop, shift, logic_cc);
7366 if (gen_thumb2_data_op(s, op, conds, 0))
7369 gen_movl_reg_T0(s, rd);
7371 case 13: /* Misc data processing. */
7372 op = ((insn >> 22) & 6) | ((insn >> 7) & 1);
7373 if (op < 4 && (insn & 0xf000) != 0xf000)
7376 case 0: /* Register controlled shift. */
7377 tmp = load_reg(s, rn);
7378 tmp2 = load_reg(s, rm);
7379 if ((insn & 0x70) != 0)
7381 op = (insn >> 21) & 3;
7382 logic_cc = (insn & (1 << 20)) != 0;
7383 gen_arm_shift_reg(tmp, op, tmp2, logic_cc);
7386 store_reg_bx(env, s, rd, tmp);
7388 case 1: /* Sign/zero extend. */
7389 tmp = load_reg(s, rm);
7390 shift = (insn >> 4) & 3;
7391 /* ??? In many cases it's not neccessary to do a
7392 rotate, a shift is sufficient. */
7394 tcg_gen_rori_i32(tmp, tmp, shift * 8);
7395 op = (insn >> 20) & 7;
7397 case 0: gen_sxth(tmp); break;
7398 case 1: gen_uxth(tmp); break;
7399 case 2: gen_sxtb16(tmp); break;
7400 case 3: gen_uxtb16(tmp); break;
7401 case 4: gen_sxtb(tmp); break;
7402 case 5: gen_uxtb(tmp); break;
7403 default: goto illegal_op;
7406 tmp2 = load_reg(s, rn);
7407 if ((op >> 1) == 1) {
7408 gen_add16(tmp, tmp2);
7410 tcg_gen_add_i32(tmp, tmp, tmp2);
7414 store_reg(s, rd, tmp);
7416 case 2: /* SIMD add/subtract. */
7417 op = (insn >> 20) & 7;
7418 shift = (insn >> 4) & 7;
7419 if ((op & 3) == 3 || (shift & 3) == 3)
7421 tmp = load_reg(s, rn);
7422 tmp2 = load_reg(s, rm);
7423 gen_thumb2_parallel_addsub(op, shift, tmp, tmp2);
7425 store_reg(s, rd, tmp);
7427 case 3: /* Other data processing. */
7428 op = ((insn >> 17) & 0x38) | ((insn >> 4) & 7);
7430 /* Saturating add/subtract. */
7431 tmp = load_reg(s, rn);
7432 tmp2 = load_reg(s, rm);
7434 gen_helper_double_saturate(tmp, tmp);
7436 gen_helper_sub_saturate(tmp, tmp2, tmp);
7438 gen_helper_add_saturate(tmp, tmp, tmp2);
7441 tmp = load_reg(s, rn);
7443 case 0x0a: /* rbit */
7444 gen_helper_rbit(tmp, tmp);
7446 case 0x08: /* rev */
7447 tcg_gen_bswap32_i32(tmp, tmp);
7449 case 0x09: /* rev16 */
7452 case 0x0b: /* revsh */
7455 case 0x10: /* sel */
7456 tmp2 = load_reg(s, rm);
7458 tcg_gen_ld_i32(tmp3, cpu_env, offsetof(CPUState, GE));
7459 gen_helper_sel_flags(tmp, tmp3, tmp, tmp2);
7463 case 0x18: /* clz */
7464 gen_helper_clz(tmp, tmp);
7470 store_reg(s, rd, tmp);
7472 case 4: case 5: /* 32-bit multiply. Sum of absolute differences. */
7473 op = (insn >> 4) & 0xf;
7474 tmp = load_reg(s, rn);
7475 tmp2 = load_reg(s, rm);
7476 switch ((insn >> 20) & 7) {
7477 case 0: /* 32 x 32 -> 32 */
7478 tcg_gen_mul_i32(tmp, tmp, tmp2);
7481 tmp2 = load_reg(s, rs);
7483 tcg_gen_sub_i32(tmp, tmp2, tmp);
7485 tcg_gen_add_i32(tmp, tmp, tmp2);
7489 case 1: /* 16 x 16 -> 32 */
7490 gen_mulxy(tmp, tmp2, op & 2, op & 1);
7493 tmp2 = load_reg(s, rs);
7494 gen_helper_add_setq(tmp, tmp, tmp2);
7498 case 2: /* Dual multiply add. */
7499 case 4: /* Dual multiply subtract. */
7501 gen_swap_half(tmp2);
7502 gen_smul_dual(tmp, tmp2);
7503 /* This addition cannot overflow. */
7504 if (insn & (1 << 22)) {
7505 tcg_gen_sub_i32(tmp, tmp, tmp2);
7507 tcg_gen_add_i32(tmp, tmp, tmp2);
7512 tmp2 = load_reg(s, rs);
7513 gen_helper_add_setq(tmp, tmp, tmp2);
7517 case 3: /* 32 * 16 -> 32msb */
7519 tcg_gen_sari_i32(tmp2, tmp2, 16);
7522 tmp64 = gen_muls_i64_i32(tmp, tmp2);
7523 tcg_gen_shri_i64(tmp64, tmp64, 16);
7525 tcg_gen_trunc_i64_i32(tmp, tmp64);
7528 tmp2 = load_reg(s, rs);
7529 gen_helper_add_setq(tmp, tmp, tmp2);
7533 case 5: case 6: /* 32 * 32 -> 32msb */
7534 gen_imull(tmp, tmp2);
7535 if (insn & (1 << 5)) {
7536 gen_roundqd(tmp, tmp2);
7543 tmp2 = load_reg(s, rs);
7544 if (insn & (1 << 21)) {
7545 tcg_gen_add_i32(tmp, tmp, tmp2);
7547 tcg_gen_sub_i32(tmp, tmp2, tmp);
7552 case 7: /* Unsigned sum of absolute differences. */
7553 gen_helper_usad8(tmp, tmp, tmp2);
7556 tmp2 = load_reg(s, rs);
7557 tcg_gen_add_i32(tmp, tmp, tmp2);
7562 store_reg(s, rd, tmp);
7564 case 6: case 7: /* 64-bit multiply, Divide. */
7565 op = ((insn >> 4) & 0xf) | ((insn >> 16) & 0x70);
7566 tmp = load_reg(s, rn);
7567 tmp2 = load_reg(s, rm);
7568 if ((op & 0x50) == 0x10) {
7570 if (!arm_feature(env, ARM_FEATURE_DIV))
7573 gen_helper_udiv(tmp, tmp, tmp2);
7575 gen_helper_sdiv(tmp, tmp, tmp2);
7577 store_reg(s, rd, tmp);
7578 } else if ((op & 0xe) == 0xc) {
7579 /* Dual multiply accumulate long. */
7581 gen_swap_half(tmp2);
7582 gen_smul_dual(tmp, tmp2);
7584 tcg_gen_sub_i32(tmp, tmp, tmp2);
7586 tcg_gen_add_i32(tmp, tmp, tmp2);
7590 tmp64 = tcg_temp_new_i64();
7591 tcg_gen_ext_i32_i64(tmp64, tmp);
7593 gen_addq(s, tmp64, rs, rd);
7594 gen_storeq_reg(s, rs, rd, tmp64);
7597 /* Unsigned 64-bit multiply */
7598 tmp64 = gen_mulu_i64_i32(tmp, tmp2);
7602 gen_mulxy(tmp, tmp2, op & 2, op & 1);
7604 tmp64 = tcg_temp_new_i64();
7605 tcg_gen_ext_i32_i64(tmp64, tmp);
7608 /* Signed 64-bit multiply */
7609 tmp64 = gen_muls_i64_i32(tmp, tmp2);
7614 gen_addq_lo(s, tmp64, rs);
7615 gen_addq_lo(s, tmp64, rd);
7616 } else if (op & 0x40) {
7617 /* 64-bit accumulate. */
7618 gen_addq(s, tmp64, rs, rd);
7620 gen_storeq_reg(s, rs, rd, tmp64);
7625 case 6: case 7: case 14: case 15:
7627 if (((insn >> 24) & 3) == 3) {
7628 /* Translate into the equivalent ARM encoding. */
7629 insn = (insn & 0xe2ffffff) | ((insn & (1 << 28)) >> 4);
7630 if (disas_neon_data_insn(env, s, insn))
7633 if (insn & (1 << 28))
7635 if (disas_coproc_insn (env, s, insn))
7639 case 8: case 9: case 10: case 11:
7640 if (insn & (1 << 15)) {
7641 /* Branches, misc control. */
7642 if (insn & 0x5000) {
7643 /* Unconditional branch. */
7644 /* signextend(hw1[10:0]) -> offset[:12]. */
7645 offset = ((int32_t)insn << 5) >> 9 & ~(int32_t)0xfff;
7646 /* hw1[10:0] -> offset[11:1]. */
7647 offset |= (insn & 0x7ff) << 1;
7648 /* (~hw2[13, 11] ^ offset[24]) -> offset[23,22]
7649 offset[24:22] already have the same value because of the
7650 sign extension above. */
7651 offset ^= ((~insn) & (1 << 13)) << 10;
7652 offset ^= ((~insn) & (1 << 11)) << 11;
7654 if (insn & (1 << 14)) {
7655 /* Branch and link. */
7656 gen_op_movl_T1_im(s->pc | 1);
7657 gen_movl_reg_T1(s, 14);
7661 if (insn & (1 << 12)) {
7666 offset &= ~(uint32_t)2;
7667 gen_bx_im(s, offset);
7669 } else if (((insn >> 23) & 7) == 7) {
7671 if (insn & (1 << 13))
7674 if (insn & (1 << 26)) {
7675 /* Secure monitor call (v6Z) */
7676 goto illegal_op; /* not implemented. */
7678 op = (insn >> 20) & 7;
7680 case 0: /* msr cpsr. */
7682 tmp = load_reg(s, rn);
7683 addr = tcg_const_i32(insn & 0xff);
7684 gen_helper_v7m_msr(cpu_env, addr, tmp);
7689 case 1: /* msr spsr. */
7692 gen_movl_T0_reg(s, rn);
7693 if (gen_set_psr_T0(s,
7694 msr_mask(env, s, (insn >> 8) & 0xf, op == 1),
7698 case 2: /* cps, nop-hint. */
7699 if (((insn >> 8) & 7) == 0) {
7700 gen_nop_hint(s, insn & 0xff);
7702 /* Implemented as NOP in user mode. */
7707 if (insn & (1 << 10)) {
7708 if (insn & (1 << 7))
7710 if (insn & (1 << 6))
7712 if (insn & (1 << 5))
7714 if (insn & (1 << 9))
7715 imm = CPSR_A | CPSR_I | CPSR_F;
7717 if (insn & (1 << 8)) {
7719 imm |= (insn & 0x1f);
7722 gen_op_movl_T0_im(imm);
7723 gen_set_psr_T0(s, offset, 0);
7726 case 3: /* Special control operations. */
7727 op = (insn >> 4) & 0xf;
7730 gen_helper_clrex(cpu_env);
7735 /* These execute as NOPs. */
7743 /* Trivial implementation equivalent to bx. */
7744 tmp = load_reg(s, rn);
7747 case 5: /* Exception return. */
7748 /* Unpredictable in user mode. */
7750 case 6: /* mrs cpsr. */
7753 addr = tcg_const_i32(insn & 0xff);
7754 gen_helper_v7m_mrs(tmp, cpu_env, addr);
7756 gen_helper_cpsr_read(tmp);
7758 store_reg(s, rd, tmp);
7760 case 7: /* mrs spsr. */
7761 /* Not accessible in user mode. */
7762 if (IS_USER(s) || IS_M(env))
7764 tmp = load_cpu_field(spsr);
7765 store_reg(s, rd, tmp);
7770 /* Conditional branch. */
7771 op = (insn >> 22) & 0xf;
7772 /* Generate a conditional jump to next instruction. */
7773 s->condlabel = gen_new_label();
7774 gen_test_cc(op ^ 1, s->condlabel);
7777 /* offset[11:1] = insn[10:0] */
7778 offset = (insn & 0x7ff) << 1;
7779 /* offset[17:12] = insn[21:16]. */
7780 offset |= (insn & 0x003f0000) >> 4;
7781 /* offset[31:20] = insn[26]. */
7782 offset |= ((int32_t)((insn << 5) & 0x80000000)) >> 11;
7783 /* offset[18] = insn[13]. */
7784 offset |= (insn & (1 << 13)) << 5;
7785 /* offset[19] = insn[11]. */
7786 offset |= (insn & (1 << 11)) << 8;
7788 /* jump to the offset */
7789 gen_jmp(s, s->pc + offset);
7792 /* Data processing immediate. */
7793 if (insn & (1 << 25)) {
7794 if (insn & (1 << 24)) {
7795 if (insn & (1 << 20))
7797 /* Bitfield/Saturate. */
7798 op = (insn >> 21) & 7;
7800 shift = ((insn >> 6) & 3) | ((insn >> 10) & 0x1c);
7803 tcg_gen_movi_i32(tmp, 0);
7805 tmp = load_reg(s, rn);
7808 case 2: /* Signed bitfield extract. */
7810 if (shift + imm > 32)
7813 gen_sbfx(tmp, shift, imm);
7815 case 6: /* Unsigned bitfield extract. */
7817 if (shift + imm > 32)
7820 gen_ubfx(tmp, shift, (1u << imm) - 1);
7822 case 3: /* Bitfield insert/clear. */
7825 imm = imm + 1 - shift;
7827 tmp2 = load_reg(s, rd);
7828 gen_bfi(tmp, tmp2, tmp, shift, (1u << imm) - 1);
7834 default: /* Saturate. */
7837 tcg_gen_sari_i32(tmp, tmp, shift);
7839 tcg_gen_shli_i32(tmp, tmp, shift);
7841 tmp2 = tcg_const_i32(imm);
7844 if ((op & 1) && shift == 0)
7845 gen_helper_usat16(tmp, tmp, tmp2);
7847 gen_helper_usat(tmp, tmp, tmp2);
7850 if ((op & 1) && shift == 0)
7851 gen_helper_ssat16(tmp, tmp, tmp2);
7853 gen_helper_ssat(tmp, tmp, tmp2);
7857 store_reg(s, rd, tmp);
7859 imm = ((insn & 0x04000000) >> 15)
7860 | ((insn & 0x7000) >> 4) | (insn & 0xff);
7861 if (insn & (1 << 22)) {
7862 /* 16-bit immediate. */
7863 imm |= (insn >> 4) & 0xf000;
7864 if (insn & (1 << 23)) {
7866 tmp = load_reg(s, rd);
7867 tcg_gen_ext16u_i32(tmp, tmp);
7868 tcg_gen_ori_i32(tmp, tmp, imm << 16);
7872 tcg_gen_movi_i32(tmp, imm);
7875 /* Add/sub 12-bit immediate. */
7877 offset = s->pc & ~(uint32_t)3;
7878 if (insn & (1 << 23))
7883 tcg_gen_movi_i32(tmp, offset);
7885 tmp = load_reg(s, rn);
7886 if (insn & (1 << 23))
7887 tcg_gen_subi_i32(tmp, tmp, imm);
7889 tcg_gen_addi_i32(tmp, tmp, imm);
7892 store_reg(s, rd, tmp);
7895 int shifter_out = 0;
7896 /* modified 12-bit immediate. */
7897 shift = ((insn & 0x04000000) >> 23) | ((insn & 0x7000) >> 12);
7898 imm = (insn & 0xff);
7901 /* Nothing to do. */
7903 case 1: /* 00XY00XY */
7906 case 2: /* XY00XY00 */
7910 case 3: /* XYXYXYXY */
7914 default: /* Rotated constant. */
7915 shift = (shift << 1) | (imm >> 7);
7917 imm = imm << (32 - shift);
7921 gen_op_movl_T1_im(imm);
7922 rn = (insn >> 16) & 0xf;
7924 gen_op_movl_T0_im(0);
7926 gen_movl_T0_reg(s, rn);
7927 op = (insn >> 21) & 0xf;
7928 if (gen_thumb2_data_op(s, op, (insn & (1 << 20)) != 0,
7931 rd = (insn >> 8) & 0xf;
7933 gen_movl_reg_T0(s, rd);
7938 case 12: /* Load/store single data item. */
7943 if ((insn & 0x01100000) == 0x01000000) {
7944 if (disas_neon_ls_insn(env, s, insn))
7952 /* s->pc has already been incremented by 4. */
7953 imm = s->pc & 0xfffffffc;
7954 if (insn & (1 << 23))
7955 imm += insn & 0xfff;
7957 imm -= insn & 0xfff;
7958 tcg_gen_movi_i32(addr, imm);
7960 addr = load_reg(s, rn);
7961 if (insn & (1 << 23)) {
7962 /* Positive offset. */
7964 tcg_gen_addi_i32(addr, addr, imm);
7966 op = (insn >> 8) & 7;
7969 case 0: case 8: /* Shifted Register. */
7970 shift = (insn >> 4) & 0xf;
7973 tmp = load_reg(s, rm);
7975 tcg_gen_shli_i32(tmp, tmp, shift);
7976 tcg_gen_add_i32(addr, addr, tmp);
7979 case 4: /* Negative offset. */
7980 tcg_gen_addi_i32(addr, addr, -imm);
7982 case 6: /* User privilege. */
7983 tcg_gen_addi_i32(addr, addr, imm);
7986 case 1: /* Post-decrement. */
7989 case 3: /* Post-increment. */
7993 case 5: /* Pre-decrement. */
7996 case 7: /* Pre-increment. */
7997 tcg_gen_addi_i32(addr, addr, imm);
8005 op = ((insn >> 21) & 3) | ((insn >> 22) & 4);
8006 if (insn & (1 << 20)) {
8008 if (rs == 15 && op != 2) {
8011 /* Memory hint. Implemented as NOP. */
8014 case 0: tmp = gen_ld8u(addr, user); break;
8015 case 4: tmp = gen_ld8s(addr, user); break;
8016 case 1: tmp = gen_ld16u(addr, user); break;
8017 case 5: tmp = gen_ld16s(addr, user); break;
8018 case 2: tmp = gen_ld32(addr, user); break;
8019 default: goto illegal_op;
8024 store_reg(s, rs, tmp);
8031 tmp = load_reg(s, rs);
8033 case 0: gen_st8(tmp, addr, user); break;
8034 case 1: gen_st16(tmp, addr, user); break;
8035 case 2: gen_st32(tmp, addr, user); break;
8036 default: goto illegal_op;
8040 tcg_gen_addi_i32(addr, addr, imm);
8042 store_reg(s, rn, addr);
8056 static void disas_thumb_insn(CPUState *env, DisasContext *s)
8058 uint32_t val, insn, op, rm, rn, rd, shift, cond;
8065 if (s->condexec_mask) {
8066 cond = s->condexec_cond;
8067 s->condlabel = gen_new_label();
8068 gen_test_cc(cond ^ 1, s->condlabel);
8072 insn = lduw_code(s->pc);
8075 switch (insn >> 12) {
8078 op = (insn >> 11) & 3;
8081 rn = (insn >> 3) & 7;
8082 gen_movl_T0_reg(s, rn);
8083 if (insn & (1 << 10)) {
8085 gen_op_movl_T1_im((insn >> 6) & 7);
8088 rm = (insn >> 6) & 7;
8089 gen_movl_T1_reg(s, rm);
8091 if (insn & (1 << 9)) {
8092 if (s->condexec_mask)
8093 gen_op_subl_T0_T1();
8095 gen_op_subl_T0_T1_cc();
8097 if (s->condexec_mask)
8098 gen_op_addl_T0_T1();
8100 gen_op_addl_T0_T1_cc();
8102 gen_movl_reg_T0(s, rd);
8104 /* shift immediate */
8105 rm = (insn >> 3) & 7;
8106 shift = (insn >> 6) & 0x1f;
8107 tmp = load_reg(s, rm);
8108 gen_arm_shift_im(tmp, op, shift, s->condexec_mask == 0);
8109 if (!s->condexec_mask)
8111 store_reg(s, rd, tmp);
8115 /* arithmetic large immediate */
8116 op = (insn >> 11) & 3;
8117 rd = (insn >> 8) & 0x7;
8119 gen_op_movl_T0_im(insn & 0xff);
8121 gen_movl_T0_reg(s, rd);
8122 gen_op_movl_T1_im(insn & 0xff);
8126 if (!s->condexec_mask)
8127 gen_op_logic_T0_cc();
8130 gen_op_subl_T0_T1_cc();
8133 if (s->condexec_mask)
8134 gen_op_addl_T0_T1();
8136 gen_op_addl_T0_T1_cc();
8139 if (s->condexec_mask)
8140 gen_op_subl_T0_T1();
8142 gen_op_subl_T0_T1_cc();
8146 gen_movl_reg_T0(s, rd);
8149 if (insn & (1 << 11)) {
8150 rd = (insn >> 8) & 7;
8151 /* load pc-relative. Bit 1 of PC is ignored. */
8152 val = s->pc + 2 + ((insn & 0xff) * 4);
8153 val &= ~(uint32_t)2;
8155 tcg_gen_movi_i32(addr, val);
8156 tmp = gen_ld32(addr, IS_USER(s));
8158 store_reg(s, rd, tmp);
8161 if (insn & (1 << 10)) {
8162 /* data processing extended or blx */
8163 rd = (insn & 7) | ((insn >> 4) & 8);
8164 rm = (insn >> 3) & 0xf;
8165 op = (insn >> 8) & 3;
8168 gen_movl_T0_reg(s, rd);
8169 gen_movl_T1_reg(s, rm);
8170 gen_op_addl_T0_T1();
8171 gen_movl_reg_T0(s, rd);
8174 gen_movl_T0_reg(s, rd);
8175 gen_movl_T1_reg(s, rm);
8176 gen_op_subl_T0_T1_cc();
8178 case 2: /* mov/cpy */
8179 gen_movl_T0_reg(s, rm);
8180 gen_movl_reg_T0(s, rd);
8182 case 3:/* branch [and link] exchange thumb register */
8183 tmp = load_reg(s, rm);
8184 if (insn & (1 << 7)) {
8185 val = (uint32_t)s->pc | 1;
8187 tcg_gen_movi_i32(tmp2, val);
8188 store_reg(s, 14, tmp2);
8196 /* data processing register */
8198 rm = (insn >> 3) & 7;
8199 op = (insn >> 6) & 0xf;
8200 if (op == 2 || op == 3 || op == 4 || op == 7) {
8201 /* the shift/rotate ops want the operands backwards */
8210 if (op == 9) /* neg */
8211 gen_op_movl_T0_im(0);
8212 else if (op != 0xf) /* mvn doesn't read its first operand */
8213 gen_movl_T0_reg(s, rd);
8215 gen_movl_T1_reg(s, rm);
8218 gen_op_andl_T0_T1();
8219 if (!s->condexec_mask)
8220 gen_op_logic_T0_cc();
8223 gen_op_xorl_T0_T1();
8224 if (!s->condexec_mask)
8225 gen_op_logic_T0_cc();
8228 if (s->condexec_mask) {
8229 gen_helper_shl(cpu_T[1], cpu_T[1], cpu_T[0]);
8231 gen_helper_shl_cc(cpu_T[1], cpu_T[1], cpu_T[0]);
8232 gen_op_logic_T1_cc();
8236 if (s->condexec_mask) {
8237 gen_helper_shr(cpu_T[1], cpu_T[1], cpu_T[0]);
8239 gen_helper_shr_cc(cpu_T[1], cpu_T[1], cpu_T[0]);
8240 gen_op_logic_T1_cc();
8244 if (s->condexec_mask) {
8245 gen_helper_sar(cpu_T[1], cpu_T[1], cpu_T[0]);
8247 gen_helper_sar_cc(cpu_T[1], cpu_T[1], cpu_T[0]);
8248 gen_op_logic_T1_cc();
8252 if (s->condexec_mask)
8255 gen_op_adcl_T0_T1_cc();
8258 if (s->condexec_mask)
8261 gen_op_sbcl_T0_T1_cc();
8264 if (s->condexec_mask) {
8265 gen_helper_ror(cpu_T[1], cpu_T[1], cpu_T[0]);
8267 gen_helper_ror_cc(cpu_T[1], cpu_T[1], cpu_T[0]);
8268 gen_op_logic_T1_cc();
8272 gen_op_andl_T0_T1();
8273 gen_op_logic_T0_cc();
8277 if (s->condexec_mask)
8278 tcg_gen_neg_i32(cpu_T[0], cpu_T[1]);
8280 gen_op_subl_T0_T1_cc();
8283 gen_op_subl_T0_T1_cc();
8287 gen_op_addl_T0_T1_cc();
8292 if (!s->condexec_mask)
8293 gen_op_logic_T0_cc();
8296 gen_op_mull_T0_T1();
8297 if (!s->condexec_mask)
8298 gen_op_logic_T0_cc();
8301 gen_op_bicl_T0_T1();
8302 if (!s->condexec_mask)
8303 gen_op_logic_T0_cc();
8307 if (!s->condexec_mask)
8308 gen_op_logic_T1_cc();
8315 gen_movl_reg_T1(s, rm);
8317 gen_movl_reg_T0(s, rd);
8322 /* load/store register offset. */
8324 rn = (insn >> 3) & 7;
8325 rm = (insn >> 6) & 7;
8326 op = (insn >> 9) & 7;
8327 addr = load_reg(s, rn);
8328 tmp = load_reg(s, rm);
8329 tcg_gen_add_i32(addr, addr, tmp);
8332 if (op < 3) /* store */
8333 tmp = load_reg(s, rd);
8337 gen_st32(tmp, addr, IS_USER(s));
8340 gen_st16(tmp, addr, IS_USER(s));
8343 gen_st8(tmp, addr, IS_USER(s));
8346 tmp = gen_ld8s(addr, IS_USER(s));
8349 tmp = gen_ld32(addr, IS_USER(s));
8352 tmp = gen_ld16u(addr, IS_USER(s));
8355 tmp = gen_ld8u(addr, IS_USER(s));
8358 tmp = gen_ld16s(addr, IS_USER(s));
8361 if (op >= 3) /* load */
8362 store_reg(s, rd, tmp);
8367 /* load/store word immediate offset */
8369 rn = (insn >> 3) & 7;
8370 addr = load_reg(s, rn);
8371 val = (insn >> 4) & 0x7c;
8372 tcg_gen_addi_i32(addr, addr, val);
8374 if (insn & (1 << 11)) {
8376 tmp = gen_ld32(addr, IS_USER(s));
8377 store_reg(s, rd, tmp);
8380 tmp = load_reg(s, rd);
8381 gen_st32(tmp, addr, IS_USER(s));
8387 /* load/store byte immediate offset */
8389 rn = (insn >> 3) & 7;
8390 addr = load_reg(s, rn);
8391 val = (insn >> 6) & 0x1f;
8392 tcg_gen_addi_i32(addr, addr, val);
8394 if (insn & (1 << 11)) {
8396 tmp = gen_ld8u(addr, IS_USER(s));
8397 store_reg(s, rd, tmp);
8400 tmp = load_reg(s, rd);
8401 gen_st8(tmp, addr, IS_USER(s));
8407 /* load/store halfword immediate offset */
8409 rn = (insn >> 3) & 7;
8410 addr = load_reg(s, rn);
8411 val = (insn >> 5) & 0x3e;
8412 tcg_gen_addi_i32(addr, addr, val);
8414 if (insn & (1 << 11)) {
8416 tmp = gen_ld16u(addr, IS_USER(s));
8417 store_reg(s, rd, tmp);
8420 tmp = load_reg(s, rd);
8421 gen_st16(tmp, addr, IS_USER(s));
8427 /* load/store from stack */
8428 rd = (insn >> 8) & 7;
8429 addr = load_reg(s, 13);
8430 val = (insn & 0xff) * 4;
8431 tcg_gen_addi_i32(addr, addr, val);
8433 if (insn & (1 << 11)) {
8435 tmp = gen_ld32(addr, IS_USER(s));
8436 store_reg(s, rd, tmp);
8439 tmp = load_reg(s, rd);
8440 gen_st32(tmp, addr, IS_USER(s));
8446 /* add to high reg */
8447 rd = (insn >> 8) & 7;
8448 if (insn & (1 << 11)) {
8450 tmp = load_reg(s, 13);
8452 /* PC. bit 1 is ignored. */
8454 tcg_gen_movi_i32(tmp, (s->pc + 2) & ~(uint32_t)2);
8456 val = (insn & 0xff) * 4;
8457 tcg_gen_addi_i32(tmp, tmp, val);
8458 store_reg(s, rd, tmp);
8463 op = (insn >> 8) & 0xf;
8466 /* adjust stack pointer */
8467 tmp = load_reg(s, 13);
8468 val = (insn & 0x7f) * 4;
8469 if (insn & (1 << 7))
8470 val = -(int32_t)val;
8471 tcg_gen_addi_i32(tmp, tmp, val);
8472 store_reg(s, 13, tmp);
8475 case 2: /* sign/zero extend. */
8478 rm = (insn >> 3) & 7;
8479 tmp = load_reg(s, rm);
8480 switch ((insn >> 6) & 3) {
8481 case 0: gen_sxth(tmp); break;
8482 case 1: gen_sxtb(tmp); break;
8483 case 2: gen_uxth(tmp); break;
8484 case 3: gen_uxtb(tmp); break;
8486 store_reg(s, rd, tmp);
8488 case 4: case 5: case 0xc: case 0xd:
8490 addr = load_reg(s, 13);
8491 if (insn & (1 << 8))
8495 for (i = 0; i < 8; i++) {
8496 if (insn & (1 << i))
8499 if ((insn & (1 << 11)) == 0) {
8500 tcg_gen_addi_i32(addr, addr, -offset);
8502 for (i = 0; i < 8; i++) {
8503 if (insn & (1 << i)) {
8504 if (insn & (1 << 11)) {
8506 tmp = gen_ld32(addr, IS_USER(s));
8507 store_reg(s, i, tmp);
8510 tmp = load_reg(s, i);
8511 gen_st32(tmp, addr, IS_USER(s));
8513 /* advance to the next address. */
8514 tcg_gen_addi_i32(addr, addr, 4);
8518 if (insn & (1 << 8)) {
8519 if (insn & (1 << 11)) {
8521 tmp = gen_ld32(addr, IS_USER(s));
8522 /* don't set the pc until the rest of the instruction
8526 tmp = load_reg(s, 14);
8527 gen_st32(tmp, addr, IS_USER(s));
8529 tcg_gen_addi_i32(addr, addr, 4);
8531 if ((insn & (1 << 11)) == 0) {
8532 tcg_gen_addi_i32(addr, addr, -offset);
8534 /* write back the new stack pointer */
8535 store_reg(s, 13, addr);
8536 /* set the new PC value */
8537 if ((insn & 0x0900) == 0x0900)
8541 case 1: case 3: case 9: case 11: /* czb */
8543 tmp = load_reg(s, rm);
8544 s->condlabel = gen_new_label();
8546 if (insn & (1 << 11))
8547 tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 0, s->condlabel);
8549 tcg_gen_brcondi_i32(TCG_COND_NE, tmp, 0, s->condlabel);
8551 offset = ((insn & 0xf8) >> 2) | (insn & 0x200) >> 3;
8552 val = (uint32_t)s->pc + 2;
8557 case 15: /* IT, nop-hint. */
8558 if ((insn & 0xf) == 0) {
8559 gen_nop_hint(s, (insn >> 4) & 0xf);
8563 s->condexec_cond = (insn >> 4) & 0xe;
8564 s->condexec_mask = insn & 0x1f;
8565 /* No actual code generated for this insn, just setup state. */
8568 case 0xe: /* bkpt */
8569 gen_set_condexec(s);
8570 gen_set_pc_im(s->pc - 2);
8571 gen_exception(EXCP_BKPT);
8572 s->is_jmp = DISAS_JUMP;
8577 rn = (insn >> 3) & 0x7;
8579 tmp = load_reg(s, rn);
8580 switch ((insn >> 6) & 3) {
8581 case 0: tcg_gen_bswap32_i32(tmp, tmp); break;
8582 case 1: gen_rev16(tmp); break;
8583 case 3: gen_revsh(tmp); break;
8584 default: goto illegal_op;
8586 store_reg(s, rd, tmp);
8594 tmp = tcg_const_i32((insn & (1 << 4)) != 0);
8597 addr = tcg_const_i32(16);
8598 gen_helper_v7m_msr(cpu_env, addr, tmp);
8602 addr = tcg_const_i32(17);
8603 gen_helper_v7m_msr(cpu_env, addr, tmp);
8607 if (insn & (1 << 4))
8608 shift = CPSR_A | CPSR_I | CPSR_F;
8612 val = ((insn & 7) << 6) & shift;
8613 gen_op_movl_T0_im(val);
8614 gen_set_psr_T0(s, shift, 0);
8624 /* load/store multiple */
8625 rn = (insn >> 8) & 0x7;
8626 addr = load_reg(s, rn);
8627 for (i = 0; i < 8; i++) {
8628 if (insn & (1 << i)) {
8629 if (insn & (1 << 11)) {
8631 tmp = gen_ld32(addr, IS_USER(s));
8632 store_reg(s, i, tmp);
8635 tmp = load_reg(s, i);
8636 gen_st32(tmp, addr, IS_USER(s));
8638 /* advance to the next address */
8639 tcg_gen_addi_i32(addr, addr, 4);
8642 /* Base register writeback. */
8643 if ((insn & (1 << rn)) == 0) {
8644 store_reg(s, rn, addr);
8651 /* conditional branch or swi */
8652 cond = (insn >> 8) & 0xf;
8658 gen_set_condexec(s);
8659 gen_set_pc_im(s->pc);
8660 s->is_jmp = DISAS_SWI;
8663 /* generate a conditional jump to next instruction */
8664 s->condlabel = gen_new_label();
8665 gen_test_cc(cond ^ 1, s->condlabel);
8667 gen_movl_T1_reg(s, 15);
8669 /* jump to the offset */
8670 val = (uint32_t)s->pc + 2;
8671 offset = ((int32_t)insn << 24) >> 24;
8677 if (insn & (1 << 11)) {
8678 if (disas_thumb2_insn(env, s, insn))
8682 /* unconditional branch */
8683 val = (uint32_t)s->pc;
8684 offset = ((int32_t)insn << 21) >> 21;
8685 val += (offset << 1) + 2;
8690 if (disas_thumb2_insn(env, s, insn))
8696 gen_set_condexec(s);
8697 gen_set_pc_im(s->pc - 4);
8698 gen_exception(EXCP_UDEF);
8699 s->is_jmp = DISAS_JUMP;
8703 gen_set_condexec(s);
8704 gen_set_pc_im(s->pc - 2);
8705 gen_exception(EXCP_UDEF);
8706 s->is_jmp = DISAS_JUMP;
8709 /* generate intermediate code in gen_opc_buf and gen_opparam_buf for
8710 basic block 'tb'. If search_pc is TRUE, also generate PC
8711 information for each intermediate instruction. */
8712 static inline void gen_intermediate_code_internal(CPUState *env,
8713 TranslationBlock *tb,
8716 DisasContext dc1, *dc = &dc1;
8718 uint16_t *gen_opc_end;
8720 target_ulong pc_start;
8721 uint32_t next_page_start;
8725 /* generate intermediate code */
8727 memset(temps, 0, sizeof(temps));
8733 gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
8735 dc->is_jmp = DISAS_NEXT;
8737 dc->singlestep_enabled = env->singlestep_enabled;
8739 dc->thumb = env->thumb;
8740 dc->condexec_mask = (env->condexec_bits & 0xf) << 1;
8741 dc->condexec_cond = env->condexec_bits >> 4;
8742 #if !defined(CONFIG_USER_ONLY)
8744 dc->user = ((env->v7m.exception == 0) && (env->v7m.control & 1));
8746 dc->user = (env->uncached_cpsr & 0x1f) == ARM_CPU_MODE_USR;
8749 cpu_F0s = tcg_temp_new_i32();
8750 cpu_F1s = tcg_temp_new_i32();
8751 cpu_F0d = tcg_temp_new_i64();
8752 cpu_F1d = tcg_temp_new_i64();
8755 /* FIXME: cpu_M0 can probably be the same as cpu_V0. */
8756 cpu_M0 = tcg_temp_new_i64();
8757 next_page_start = (pc_start & TARGET_PAGE_MASK) + TARGET_PAGE_SIZE;
8760 max_insns = tb->cflags & CF_COUNT_MASK;
8762 max_insns = CF_COUNT_MASK;
8765 /* Reset the conditional execution bits immediately. This avoids
8766 complications trying to do it at the end of the block. */
8767 if (env->condexec_bits)
8769 TCGv tmp = new_tmp();
8770 tcg_gen_movi_i32(tmp, 0);
8771 store_cpu_field(tmp, condexec_bits);
8774 #ifdef CONFIG_USER_ONLY
8775 /* Intercept jump to the magic kernel page. */
8776 if (dc->pc >= 0xffff0000) {
8777 /* We always get here via a jump, so know we are not in a
8778 conditional execution block. */
8779 gen_exception(EXCP_KERNEL_TRAP);
8780 dc->is_jmp = DISAS_UPDATE;
8784 if (dc->pc >= 0xfffffff0 && IS_M(env)) {
8785 /* We always get here via a jump, so know we are not in a
8786 conditional execution block. */
8787 gen_exception(EXCP_EXCEPTION_EXIT);
8788 dc->is_jmp = DISAS_UPDATE;
8793 if (unlikely(!TAILQ_EMPTY(&env->breakpoints))) {
8794 TAILQ_FOREACH(bp, &env->breakpoints, entry) {
8795 if (bp->pc == dc->pc) {
8796 gen_set_condexec(dc);
8797 gen_set_pc_im(dc->pc);
8798 gen_exception(EXCP_DEBUG);
8799 dc->is_jmp = DISAS_JUMP;
8800 /* Advance PC so that clearing the breakpoint will
8801 invalidate this TB. */
8803 goto done_generating;
8809 j = gen_opc_ptr - gen_opc_buf;
8813 gen_opc_instr_start[lj++] = 0;
8815 gen_opc_pc[lj] = dc->pc;
8816 gen_opc_instr_start[lj] = 1;
8817 gen_opc_icount[lj] = num_insns;
8820 if (num_insns + 1 == max_insns && (tb->cflags & CF_LAST_IO))
8824 disas_thumb_insn(env, dc);
8825 if (dc->condexec_mask) {
8826 dc->condexec_cond = (dc->condexec_cond & 0xe)
8827 | ((dc->condexec_mask >> 4) & 1);
8828 dc->condexec_mask = (dc->condexec_mask << 1) & 0x1f;
8829 if (dc->condexec_mask == 0) {
8830 dc->condexec_cond = 0;
8834 disas_arm_insn(env, dc);
8837 fprintf(stderr, "Internal resource leak before %08x\n", dc->pc);
8841 if (dc->condjmp && !dc->is_jmp) {
8842 gen_set_label(dc->condlabel);
8845 /* Translation stops when a conditional branch is encountered.
8846 * Otherwise the subsequent code could get translated several times.
8847 * Also stop translation when a page boundary is reached. This
8848 * ensures prefetch aborts occur at the right place. */
8850 } while (!dc->is_jmp && gen_opc_ptr < gen_opc_end &&
8851 !env->singlestep_enabled &&
8853 dc->pc < next_page_start &&
8854 num_insns < max_insns);
8856 if (tb->cflags & CF_LAST_IO) {
8858 /* FIXME: This can theoretically happen with self-modifying
8860 cpu_abort(env, "IO on conditional branch instruction");
8865 /* At this stage dc->condjmp will only be set when the skipped
8866 instruction was a conditional branch or trap, and the PC has
8867 already been written. */
8868 if (unlikely(env->singlestep_enabled)) {
8869 /* Make sure the pc is updated, and raise a debug exception. */
8871 gen_set_condexec(dc);
8872 if (dc->is_jmp == DISAS_SWI) {
8873 gen_exception(EXCP_SWI);
8875 gen_exception(EXCP_DEBUG);
8877 gen_set_label(dc->condlabel);
8879 if (dc->condjmp || !dc->is_jmp) {
8880 gen_set_pc_im(dc->pc);
8883 gen_set_condexec(dc);
8884 if (dc->is_jmp == DISAS_SWI && !dc->condjmp) {
8885 gen_exception(EXCP_SWI);
8887 /* FIXME: Single stepping a WFI insn will not halt
8889 gen_exception(EXCP_DEBUG);
8892 /* While branches must always occur at the end of an IT block,
8893 there are a few other things that can cause us to terminate
8894 the TB in the middel of an IT block:
8895 - Exception generating instructions (bkpt, swi, undefined).
8897 - Hardware watchpoints.
8898 Hardware breakpoints have already been handled and skip this code.
8900 gen_set_condexec(dc);
8901 switch(dc->is_jmp) {
8903 gen_goto_tb(dc, 1, dc->pc);
8908 /* indicate that the hash table must be used to find the next TB */
8912 /* nothing more to generate */
8918 gen_exception(EXCP_SWI);
8922 gen_set_label(dc->condlabel);
8923 gen_set_condexec(dc);
8924 gen_goto_tb(dc, 1, dc->pc);
8930 gen_icount_end(tb, num_insns);
8931 *gen_opc_ptr = INDEX_op_end;
8934 if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
8935 qemu_log("----------------\n");
8936 qemu_log("IN: %s\n", lookup_symbol(pc_start));
8937 log_target_disas(pc_start, dc->pc - pc_start, env->thumb);
8942 j = gen_opc_ptr - gen_opc_buf;
8945 gen_opc_instr_start[lj++] = 0;
8947 tb->size = dc->pc - pc_start;
8948 tb->icount = num_insns;
8952 void gen_intermediate_code(CPUState *env, TranslationBlock *tb)
8954 gen_intermediate_code_internal(env, tb, 0);
8957 void gen_intermediate_code_pc(CPUState *env, TranslationBlock *tb)
8959 gen_intermediate_code_internal(env, tb, 1);
8962 static const char *cpu_mode_names[16] = {
8963 "usr", "fiq", "irq", "svc", "???", "???", "???", "abt",
8964 "???", "???", "???", "und", "???", "???", "???", "sys"
8967 void cpu_dump_state(CPUState *env, FILE *f,
8968 int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
8978 /* ??? This assumes float64 and double have the same layout.
8979 Oh well, it's only debug dumps. */
8988 cpu_fprintf(f, "R%02d=%08x", i, env->regs[i]);
8990 cpu_fprintf(f, "\n");
8992 cpu_fprintf(f, " ");
8994 psr = cpsr_read(env);
8995 cpu_fprintf(f, "PSR=%08x %c%c%c%c %c %s%d\n",
8997 psr & (1 << 31) ? 'N' : '-',
8998 psr & (1 << 30) ? 'Z' : '-',
8999 psr & (1 << 29) ? 'C' : '-',
9000 psr & (1 << 28) ? 'V' : '-',
9001 psr & CPSR_T ? 'T' : 'A',
9002 cpu_mode_names[psr & 0xf], (psr & 0x10) ? 32 : 26);
9005 for (i = 0; i < 16; i++) {
9006 d.d = env->vfp.regs[i];
9010 cpu_fprintf(f, "s%02d=%08x(%8g) s%02d=%08x(%8g) d%02d=%08x%08x(%8g)\n",
9011 i * 2, (int)s0.i, s0.s,
9012 i * 2 + 1, (int)s1.i, s1.s,
9013 i, (int)(uint32_t)d.l.upper, (int)(uint32_t)d.l.lower,
9016 cpu_fprintf(f, "FPSCR: %08x\n", (int)env->vfp.xregs[ARM_VFP_FPSCR]);
9020 void gen_pc_load(CPUState *env, TranslationBlock *tb,
9021 unsigned long searched_pc, int pc_pos, void *puc)
9023 env->regs[15] = gen_opc_pc[pc_pos];