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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
36 #define ENABLE_ARCH_5J 0
37 #define ENABLE_ARCH_6 arm_feature(env, ARM_FEATURE_V6)
38 #define ENABLE_ARCH_6K arm_feature(env, ARM_FEATURE_V6K)
39 #define ENABLE_ARCH_6T2 arm_feature(env, ARM_FEATURE_THUMB2)
40 #define ENABLE_ARCH_7 arm_feature(env, ARM_FEATURE_V7)
42 #define ARCH(x) if (!ENABLE_ARCH_##x) goto illegal_op;
44 /* internal defines */
45 typedef struct DisasContext {
48 /* Nonzero if this instruction has been conditionally skipped. */
50 /* The label that will be jumped to when the instruction is skipped. */
52 /* Thumb-2 condtional execution bits. */
55 struct TranslationBlock *tb;
56 int singlestep_enabled;
59 #if !defined(CONFIG_USER_ONLY)
64 #if defined(CONFIG_USER_ONLY)
67 #define IS_USER(s) (s->user)
70 /* These instructions trap after executing, so defer them until after the
71 conditional executions state has been updated. */
75 /* XXX: move that elsewhere */
80 /* We reuse the same 64-bit temporaries for efficiency. */
81 static TCGv cpu_V0, cpu_V1, cpu_M0;
83 /* FIXME: These should be removed. */
85 static TCGv cpu_F0s, cpu_F1s, cpu_F0d, cpu_F1d;
87 /* initialize TCG globals. */
88 void arm_translate_init(void)
90 cpu_env = tcg_global_reg_new(TCG_TYPE_PTR, TCG_AREG0, "env");
92 cpu_T[0] = tcg_global_reg_new(TCG_TYPE_I32, TCG_AREG1, "T0");
93 cpu_T[1] = tcg_global_reg_new(TCG_TYPE_I32, TCG_AREG2, "T1");
96 /* The code generator doesn't like lots of temporaries, so maintain our own
97 cache for reuse within a function. */
100 static TCGv temps[MAX_TEMPS];
102 /* Allocate a temporary variable. */
103 static TCGv new_tmp(void)
106 if (num_temps == MAX_TEMPS)
109 if (GET_TCGV(temps[num_temps]))
110 return temps[num_temps++];
112 tmp = tcg_temp_new(TCG_TYPE_I32);
113 temps[num_temps++] = tmp;
117 /* Release a temporary variable. */
118 static void dead_tmp(TCGv tmp)
123 if (GET_TCGV(temps[i]) == GET_TCGV(tmp))
126 /* Shuffle this temp to the last slot. */
127 while (GET_TCGV(temps[i]) != GET_TCGV(tmp))
129 while (i < num_temps) {
130 temps[i] = temps[i + 1];
136 static inline TCGv load_cpu_offset(int offset)
138 TCGv tmp = new_tmp();
139 tcg_gen_ld_i32(tmp, cpu_env, offset);
143 #define load_cpu_field(name) load_cpu_offset(offsetof(CPUState, name))
145 static inline void store_cpu_offset(TCGv var, int offset)
147 tcg_gen_st_i32(var, cpu_env, offset);
151 #define store_cpu_field(var, name) \
152 store_cpu_offset(var, offsetof(CPUState, name))
154 /* Set a variable to the value of a CPU register. */
155 static void load_reg_var(DisasContext *s, TCGv var, int reg)
159 /* normaly, since we updated PC, we need only to add one insn */
161 addr = (long)s->pc + 2;
163 addr = (long)s->pc + 4;
164 tcg_gen_movi_i32(var, addr);
166 tcg_gen_ld_i32(var, cpu_env, offsetof(CPUState, regs[reg]));
170 /* Create a new temporary and set it to the value of a CPU register. */
171 static inline TCGv load_reg(DisasContext *s, int reg)
173 TCGv tmp = new_tmp();
174 load_reg_var(s, tmp, reg);
178 /* Set a CPU register. The source must be a temporary and will be
180 static void store_reg(DisasContext *s, int reg, TCGv var)
183 tcg_gen_andi_i32(var, var, ~1);
184 s->is_jmp = DISAS_JUMP;
186 tcg_gen_st_i32(var, cpu_env, offsetof(CPUState, regs[reg]));
191 /* Basic operations. */
192 #define gen_op_movl_T0_T1() tcg_gen_mov_i32(cpu_T[0], cpu_T[1])
193 #define gen_op_movl_T1_T0() tcg_gen_mov_i32(cpu_T[1], cpu_T[0])
194 #define gen_op_movl_T0_im(im) tcg_gen_movi_i32(cpu_T[0], im)
195 #define gen_op_movl_T1_im(im) tcg_gen_movi_i32(cpu_T[1], im)
197 #define gen_op_addl_T1_im(im) tcg_gen_addi_i32(cpu_T[1], cpu_T[1], im)
198 #define gen_op_addl_T0_T1() tcg_gen_add_i32(cpu_T[0], cpu_T[0], cpu_T[1])
199 #define gen_op_subl_T0_T1() tcg_gen_sub_i32(cpu_T[0], cpu_T[0], cpu_T[1])
200 #define gen_op_rsbl_T0_T1() tcg_gen_sub_i32(cpu_T[0], cpu_T[1], cpu_T[0])
202 #define gen_op_addl_T0_T1_cc() gen_helper_add_cc(cpu_T[0], cpu_T[0], cpu_T[1])
203 #define gen_op_adcl_T0_T1_cc() gen_helper_adc_cc(cpu_T[0], cpu_T[0], cpu_T[1])
204 #define gen_op_subl_T0_T1_cc() gen_helper_sub_cc(cpu_T[0], cpu_T[0], cpu_T[1])
205 #define gen_op_sbcl_T0_T1_cc() gen_helper_sbc_cc(cpu_T[0], cpu_T[0], cpu_T[1])
206 #define gen_op_rsbl_T0_T1_cc() gen_helper_sub_cc(cpu_T[0], cpu_T[1], cpu_T[0])
207 #define gen_op_rscl_T0_T1_cc() gen_helper_sbc_cc(cpu_T[0], cpu_T[1], cpu_T[0])
209 #define gen_op_andl_T0_T1() tcg_gen_and_i32(cpu_T[0], cpu_T[0], cpu_T[1])
210 #define gen_op_xorl_T0_T1() tcg_gen_xor_i32(cpu_T[0], cpu_T[0], cpu_T[1])
211 #define gen_op_orl_T0_T1() tcg_gen_or_i32(cpu_T[0], cpu_T[0], cpu_T[1])
212 #define gen_op_notl_T0() tcg_gen_not_i32(cpu_T[0], cpu_T[0])
213 #define gen_op_notl_T1() tcg_gen_not_i32(cpu_T[1], cpu_T[1])
214 #define gen_op_logic_T0_cc() gen_logic_CC(cpu_T[0]);
215 #define gen_op_logic_T1_cc() gen_logic_CC(cpu_T[1]);
217 #define gen_op_shll_T0_im(im) tcg_gen_shli_i32(cpu_T[0], cpu_T[0], im)
218 #define gen_op_shll_T1_im(im) tcg_gen_shli_i32(cpu_T[1], cpu_T[1], im)
219 #define gen_op_shrl_T1_im(im) tcg_gen_shri_i32(cpu_T[1], cpu_T[1], im)
220 #define gen_op_sarl_T1_im(im) tcg_gen_sari_i32(cpu_T[1], cpu_T[1], im)
221 #define gen_op_rorl_T1_im(im) tcg_gen_rori_i32(cpu_T[1], cpu_T[1], im)
223 /* Value extensions. */
224 #define gen_uxtb(var) tcg_gen_andi_i32(var, var, 0xff)
225 #define gen_uxth(var) tcg_gen_andi_i32(var, var, 0xffff)
226 #define gen_sxtb(var) tcg_gen_ext8s_i32(var, var)
227 #define gen_sxth(var) tcg_gen_ext16s_i32(var, var)
229 #define gen_sxtb16(var) gen_helper_sxtb16(var, var)
230 #define gen_uxtb16(var) gen_helper_uxtb16(var, var)
232 #define gen_op_mul_T0_T1() tcg_gen_mul_i32(cpu_T[0], cpu_T[0], cpu_T[1])
234 #define gen_set_cpsr(var, mask) gen_helper_cpsr_write(var, tcg_const_i32(mask))
235 /* Set NZCV flags from the high 4 bits of var. */
236 #define gen_set_nzcv(var) gen_set_cpsr(var, CPSR_NZCV)
238 static void gen_exception(int excp)
240 TCGv tmp = new_tmp();
241 tcg_gen_movi_i32(tmp, excp);
242 gen_helper_exception(tmp);
246 static void gen_smul_dual(TCGv a, TCGv b)
248 TCGv tmp1 = new_tmp();
249 TCGv tmp2 = new_tmp();
250 tcg_gen_ext8s_i32(tmp1, a);
251 tcg_gen_ext8s_i32(tmp2, b);
252 tcg_gen_mul_i32(tmp1, tmp1, tmp2);
254 tcg_gen_sari_i32(a, a, 16);
255 tcg_gen_sari_i32(b, b, 16);
256 tcg_gen_mul_i32(b, b, a);
257 tcg_gen_mov_i32(a, tmp1);
261 /* Byteswap each halfword. */
262 static void gen_rev16(TCGv var)
264 TCGv tmp = new_tmp();
265 tcg_gen_shri_i32(tmp, var, 8);
266 tcg_gen_andi_i32(tmp, tmp, 0x00ff00ff);
267 tcg_gen_shli_i32(var, var, 8);
268 tcg_gen_andi_i32(var, var, 0xff00ff00);
269 tcg_gen_or_i32(var, var, tmp);
273 /* Byteswap low halfword and sign extend. */
274 static void gen_revsh(TCGv var)
276 TCGv tmp = new_tmp();
277 tcg_gen_shri_i32(tmp, var, 8);
278 tcg_gen_andi_i32(tmp, tmp, 0x00ff);
279 tcg_gen_shli_i32(var, var, 8);
280 tcg_gen_ext8s_i32(var, var);
281 tcg_gen_or_i32(var, var, tmp);
285 /* Unsigned bitfield extract. */
286 static void gen_ubfx(TCGv var, int shift, uint32_t mask)
289 tcg_gen_shri_i32(var, var, shift);
290 tcg_gen_andi_i32(var, var, mask);
293 /* Signed bitfield extract. */
294 static void gen_sbfx(TCGv var, int shift, int width)
299 tcg_gen_sari_i32(var, var, shift);
300 if (shift + width < 32) {
301 signbit = 1u << (width - 1);
302 tcg_gen_andi_i32(var, var, (1u << width) - 1);
303 tcg_gen_xori_i32(var, var, signbit);
304 tcg_gen_subi_i32(var, var, signbit);
308 /* Bitfield insertion. Insert val into base. Clobbers base and val. */
309 static void gen_bfi(TCGv dest, TCGv base, TCGv val, int shift, uint32_t mask)
311 tcg_gen_andi_i32(val, val, mask);
312 tcg_gen_shli_i32(val, val, shift);
313 tcg_gen_andi_i32(base, base, ~(mask << shift));
314 tcg_gen_or_i32(dest, base, val);
317 /* Round the top 32 bits of a 64-bit value. */
318 static void gen_roundqd(TCGv a, TCGv b)
320 tcg_gen_shri_i32(a, a, 31);
321 tcg_gen_add_i32(a, a, b);
324 /* FIXME: Most targets have native widening multiplication.
325 It would be good to use that instead of a full wide multiply. */
326 /* 32x32->64 multiply. Marks inputs as dead. */
327 static TCGv gen_mulu_i64_i32(TCGv a, TCGv b)
329 TCGv tmp1 = tcg_temp_new(TCG_TYPE_I64);
330 TCGv tmp2 = tcg_temp_new(TCG_TYPE_I64);
332 tcg_gen_extu_i32_i64(tmp1, a);
334 tcg_gen_extu_i32_i64(tmp2, b);
336 tcg_gen_mul_i64(tmp1, tmp1, tmp2);
340 static TCGv gen_muls_i64_i32(TCGv a, TCGv b)
342 TCGv tmp1 = tcg_temp_new(TCG_TYPE_I64);
343 TCGv tmp2 = tcg_temp_new(TCG_TYPE_I64);
345 tcg_gen_ext_i32_i64(tmp1, a);
347 tcg_gen_ext_i32_i64(tmp2, b);
349 tcg_gen_mul_i64(tmp1, tmp1, tmp2);
353 /* Unsigned 32x32->64 multiply. */
354 static void gen_op_mull_T0_T1(void)
356 TCGv tmp1 = tcg_temp_new(TCG_TYPE_I64);
357 TCGv tmp2 = tcg_temp_new(TCG_TYPE_I64);
359 tcg_gen_extu_i32_i64(tmp1, cpu_T[0]);
360 tcg_gen_extu_i32_i64(tmp2, cpu_T[1]);
361 tcg_gen_mul_i64(tmp1, tmp1, tmp2);
362 tcg_gen_trunc_i64_i32(cpu_T[0], tmp1);
363 tcg_gen_shri_i64(tmp1, tmp1, 32);
364 tcg_gen_trunc_i64_i32(cpu_T[1], tmp1);
367 /* Signed 32x32->64 multiply. */
368 static void gen_imull(TCGv a, TCGv b)
370 TCGv tmp1 = tcg_temp_new(TCG_TYPE_I64);
371 TCGv tmp2 = tcg_temp_new(TCG_TYPE_I64);
373 tcg_gen_ext_i32_i64(tmp1, a);
374 tcg_gen_ext_i32_i64(tmp2, b);
375 tcg_gen_mul_i64(tmp1, tmp1, tmp2);
376 tcg_gen_trunc_i64_i32(a, tmp1);
377 tcg_gen_shri_i64(tmp1, tmp1, 32);
378 tcg_gen_trunc_i64_i32(b, tmp1);
380 #define gen_op_imull_T0_T1() gen_imull(cpu_T[0], cpu_T[1])
382 /* Swap low and high halfwords. */
383 static void gen_swap_half(TCGv var)
385 TCGv tmp = new_tmp();
386 tcg_gen_shri_i32(tmp, var, 16);
387 tcg_gen_shli_i32(var, var, 16);
388 tcg_gen_or_i32(var, var, tmp);
392 /* Dual 16-bit add. Result placed in t0 and t1 is marked as dead.
393 tmp = (t0 ^ t1) & 0x8000;
396 t0 = (t0 + t1) ^ tmp;
399 static void gen_add16(TCGv t0, TCGv t1)
401 TCGv tmp = new_tmp();
402 tcg_gen_xor_i32(tmp, t0, t1);
403 tcg_gen_andi_i32(tmp, tmp, 0x8000);
404 tcg_gen_andi_i32(t0, t0, ~0x8000);
405 tcg_gen_andi_i32(t1, t1, ~0x8000);
406 tcg_gen_add_i32(t0, t0, t1);
407 tcg_gen_xor_i32(t0, t0, tmp);
412 #define gen_set_CF(var) tcg_gen_st_i32(var, cpu_env, offsetof(CPUState, CF))
414 /* Set CF to the top bit of var. */
415 static void gen_set_CF_bit31(TCGv var)
417 TCGv tmp = new_tmp();
418 tcg_gen_shri_i32(tmp, var, 31);
423 /* Set N and Z flags from var. */
424 static inline void gen_logic_CC(TCGv var)
426 tcg_gen_st_i32(var, cpu_env, offsetof(CPUState, NF));
427 tcg_gen_st_i32(var, cpu_env, offsetof(CPUState, ZF));
431 static void gen_adc_T0_T1(void)
435 tmp = load_cpu_field(CF);
436 tcg_gen_add_i32(cpu_T[0], cpu_T[0], tmp);
440 /* dest = T0 - T1 + CF - 1. */
441 static void gen_sub_carry(TCGv dest, TCGv t0, TCGv t1)
444 tcg_gen_sub_i32(dest, t0, t1);
445 tmp = load_cpu_field(CF);
446 tcg_gen_add_i32(dest, dest, tmp);
447 tcg_gen_subi_i32(dest, dest, 1);
451 #define gen_sbc_T0_T1() gen_sub_carry(cpu_T[0], cpu_T[0], cpu_T[1])
452 #define gen_rsc_T0_T1() gen_sub_carry(cpu_T[0], cpu_T[1], cpu_T[0])
454 /* FIXME: Implement this natively. */
455 static inline void tcg_gen_not_i32(TCGv t0, TCGv t1)
457 tcg_gen_xori_i32(t0, t1, ~0);
460 /* FIXME: Implement this natively. */
461 static inline void tcg_gen_neg_i64(TCGv dest, TCGv src)
463 tcg_gen_sub_i64(dest, tcg_const_i64(0), src);
466 /* T0 &= ~T1. Clobbers T1. */
467 /* FIXME: Implement bic natively. */
468 static inline void tcg_gen_bic_i32(TCGv dest, TCGv t0, TCGv t1)
470 TCGv tmp = new_tmp();
471 tcg_gen_not_i32(tmp, t1);
472 tcg_gen_and_i32(dest, t0, tmp);
475 static inline void gen_op_bicl_T0_T1(void)
481 /* FIXME: Implement this natively. */
482 #define tcg_gen_abs_i32(t0, t1) gen_helper_abs(t0, t1)
484 /* FIXME: Implement this natively. */
485 static void tcg_gen_rori_i32(TCGv t0, TCGv t1, int i)
493 tcg_gen_shri_i32(tmp, t1, i);
494 tcg_gen_shli_i32(t1, t1, 32 - i);
495 tcg_gen_or_i32(t0, t1, tmp);
499 static void shifter_out_im(TCGv var, int shift)
501 TCGv tmp = new_tmp();
503 tcg_gen_andi_i32(tmp, var, 1);
505 tcg_gen_shri_i32(tmp, var, shift);
507 tcg_gen_andi_i32(tmp, tmp, 1);
513 /* Shift by immediate. Includes special handling for shift == 0. */
514 static inline void gen_arm_shift_im(TCGv var, int shiftop, int shift, int flags)
520 shifter_out_im(var, 32 - shift);
521 tcg_gen_shli_i32(var, var, shift);
527 tcg_gen_shri_i32(var, var, 31);
530 tcg_gen_movi_i32(var, 0);
533 shifter_out_im(var, shift - 1);
534 tcg_gen_shri_i32(var, var, shift);
541 shifter_out_im(var, shift - 1);
544 tcg_gen_sari_i32(var, var, shift);
546 case 3: /* ROR/RRX */
549 shifter_out_im(var, shift - 1);
550 tcg_gen_rori_i32(var, var, shift); break;
552 TCGv tmp = load_cpu_field(CF);
554 shifter_out_im(var, 0);
555 tcg_gen_shri_i32(var, var, 1);
556 tcg_gen_shli_i32(tmp, tmp, 31);
557 tcg_gen_or_i32(var, var, tmp);
563 static inline void gen_arm_shift_reg(TCGv var, int shiftop,
564 TCGv shift, int flags)
568 case 0: gen_helper_shl_cc(var, var, shift); break;
569 case 1: gen_helper_shr_cc(var, var, shift); break;
570 case 2: gen_helper_sar_cc(var, var, shift); break;
571 case 3: gen_helper_ror_cc(var, var, shift); break;
575 case 0: gen_helper_shl(var, var, shift); break;
576 case 1: gen_helper_shr(var, var, shift); break;
577 case 2: gen_helper_sar(var, var, shift); break;
578 case 3: gen_helper_ror(var, var, shift); break;
584 #define PAS_OP(pfx) \
586 case 0: gen_pas_helper(glue(pfx,add16)); break; \
587 case 1: gen_pas_helper(glue(pfx,addsubx)); break; \
588 case 2: gen_pas_helper(glue(pfx,subaddx)); break; \
589 case 3: gen_pas_helper(glue(pfx,sub16)); break; \
590 case 4: gen_pas_helper(glue(pfx,add8)); break; \
591 case 7: gen_pas_helper(glue(pfx,sub8)); break; \
593 static void gen_arm_parallel_addsub(int op1, int op2, TCGv a, TCGv b)
598 #define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b, tmp)
600 tmp = tcg_temp_new(TCG_TYPE_PTR);
601 tcg_gen_addi_ptr(tmp, cpu_env, offsetof(CPUState, GE));
605 tmp = tcg_temp_new(TCG_TYPE_PTR);
606 tcg_gen_addi_ptr(tmp, cpu_env, offsetof(CPUState, GE));
609 #undef gen_pas_helper
610 #define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b)
623 #undef gen_pas_helper
628 /* For unknown reasons Arm and Thumb-2 use arbitrarily different encodings. */
629 #define PAS_OP(pfx) \
631 case 0: gen_pas_helper(glue(pfx,add8)); break; \
632 case 1: gen_pas_helper(glue(pfx,add16)); break; \
633 case 2: gen_pas_helper(glue(pfx,addsubx)); break; \
634 case 4: gen_pas_helper(glue(pfx,sub8)); break; \
635 case 5: gen_pas_helper(glue(pfx,sub16)); break; \
636 case 6: gen_pas_helper(glue(pfx,subaddx)); break; \
638 static void gen_thumb2_parallel_addsub(int op1, int op2, TCGv a, TCGv b)
643 #define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b, tmp)
645 tmp = tcg_temp_new(TCG_TYPE_PTR);
646 tcg_gen_addi_ptr(tmp, cpu_env, offsetof(CPUState, GE));
650 tmp = tcg_temp_new(TCG_TYPE_PTR);
651 tcg_gen_addi_ptr(tmp, cpu_env, offsetof(CPUState, GE));
654 #undef gen_pas_helper
655 #define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b)
668 #undef gen_pas_helper
673 static void gen_test_cc(int cc, int label)
680 zero = tcg_const_i32(0);
683 tmp = load_cpu_field(ZF);
684 tcg_gen_brcond_i32(TCG_COND_EQ, tmp, zero, label);
687 tmp = load_cpu_field(ZF);
688 tcg_gen_brcond_i32(TCG_COND_NE, tmp, zero, label);
691 tmp = load_cpu_field(CF);
692 tcg_gen_brcond_i32(TCG_COND_NE, tmp, zero, label);
695 tmp = load_cpu_field(CF);
696 tcg_gen_brcond_i32(TCG_COND_EQ, tmp, zero, label);
699 tmp = load_cpu_field(NF);
700 tcg_gen_brcond_i32(TCG_COND_LT, tmp, zero, label);
703 tmp = load_cpu_field(NF);
704 tcg_gen_brcond_i32(TCG_COND_GE, tmp, zero, label);
707 tmp = load_cpu_field(VF);
708 tcg_gen_brcond_i32(TCG_COND_LT, tmp, zero, label);
711 tmp = load_cpu_field(VF);
712 tcg_gen_brcond_i32(TCG_COND_GE, tmp, zero, label);
714 case 8: /* hi: C && !Z */
715 inv = gen_new_label();
716 tmp = load_cpu_field(CF);
717 tcg_gen_brcond_i32(TCG_COND_EQ, tmp, zero, inv);
719 tmp = load_cpu_field(ZF);
720 tcg_gen_brcond_i32(TCG_COND_NE, tmp, zero, label);
723 case 9: /* ls: !C || Z */
724 tmp = load_cpu_field(CF);
725 tcg_gen_brcond_i32(TCG_COND_EQ, tmp, zero, label);
727 tmp = load_cpu_field(ZF);
728 tcg_gen_brcond_i32(TCG_COND_EQ, tmp, zero, label);
730 case 10: /* ge: N == V -> N ^ V == 0 */
731 tmp = load_cpu_field(VF);
732 tmp2 = load_cpu_field(NF);
733 tcg_gen_xor_i32(tmp, tmp, tmp2);
735 tcg_gen_brcond_i32(TCG_COND_GE, tmp, zero, label);
737 case 11: /* lt: N != V -> N ^ V != 0 */
738 tmp = load_cpu_field(VF);
739 tmp2 = load_cpu_field(NF);
740 tcg_gen_xor_i32(tmp, tmp, tmp2);
742 tcg_gen_brcond_i32(TCG_COND_LT, tmp, zero, label);
744 case 12: /* gt: !Z && N == V */
745 inv = gen_new_label();
746 tmp = load_cpu_field(ZF);
747 tcg_gen_brcond_i32(TCG_COND_EQ, tmp, zero, inv);
749 tmp = load_cpu_field(VF);
750 tmp2 = load_cpu_field(NF);
751 tcg_gen_xor_i32(tmp, tmp, tmp2);
753 tcg_gen_brcond_i32(TCG_COND_GE, tmp, zero, label);
756 case 13: /* le: Z || N != V */
757 tmp = load_cpu_field(ZF);
758 tcg_gen_brcond_i32(TCG_COND_EQ, tmp, zero, label);
760 tmp = load_cpu_field(VF);
761 tmp2 = load_cpu_field(NF);
762 tcg_gen_xor_i32(tmp, tmp, tmp2);
764 tcg_gen_brcond_i32(TCG_COND_LT, tmp, zero, label);
767 fprintf(stderr, "Bad condition code 0x%x\n", cc);
773 const uint8_t table_logic_cc[16] = {
792 /* Set PC and Thumb state from an immediate address. */
793 static inline void gen_bx_im(DisasContext *s, uint32_t addr)
797 s->is_jmp = DISAS_UPDATE;
799 if (s->thumb != (addr & 1)) {
800 tcg_gen_movi_i32(tmp, addr & 1);
801 tcg_gen_st_i32(tmp, cpu_env, offsetof(CPUState, thumb));
803 tcg_gen_movi_i32(tmp, addr & ~1);
804 tcg_gen_st_i32(tmp, cpu_env, offsetof(CPUState, regs[15]));
808 /* Set PC and Thumb state from var. var is marked as dead. */
809 static inline void gen_bx(DisasContext *s, TCGv var)
813 s->is_jmp = DISAS_UPDATE;
815 tcg_gen_andi_i32(tmp, var, 1);
816 store_cpu_field(tmp, thumb);
817 tcg_gen_andi_i32(var, var, ~1);
818 store_cpu_field(var, regs[15]);
821 /* TODO: This should be removed. Use gen_bx instead. */
822 static inline void gen_bx_T0(DisasContext *s)
824 TCGv tmp = new_tmp();
825 tcg_gen_mov_i32(tmp, cpu_T[0]);
829 #if defined(CONFIG_USER_ONLY)
830 #define gen_ldst(name, s) gen_op_##name##_raw()
832 #define gen_ldst(name, s) do { \
835 gen_op_##name##_user(); \
837 gen_op_##name##_kernel(); \
840 static inline TCGv gen_ld8s(TCGv addr, int index)
842 TCGv tmp = new_tmp();
843 tcg_gen_qemu_ld8s(tmp, addr, index);
846 static inline TCGv gen_ld8u(TCGv addr, int index)
848 TCGv tmp = new_tmp();
849 tcg_gen_qemu_ld8u(tmp, addr, index);
852 static inline TCGv gen_ld16s(TCGv addr, int index)
854 TCGv tmp = new_tmp();
855 tcg_gen_qemu_ld16s(tmp, addr, index);
858 static inline TCGv gen_ld16u(TCGv addr, int index)
860 TCGv tmp = new_tmp();
861 tcg_gen_qemu_ld16u(tmp, addr, index);
864 static inline TCGv gen_ld32(TCGv addr, int index)
866 TCGv tmp = new_tmp();
867 tcg_gen_qemu_ld32u(tmp, addr, index);
870 static inline void gen_st8(TCGv val, TCGv addr, int index)
872 tcg_gen_qemu_st8(val, addr, index);
875 static inline void gen_st16(TCGv val, TCGv addr, int index)
877 tcg_gen_qemu_st16(val, addr, index);
880 static inline void gen_st32(TCGv val, TCGv addr, int index)
882 tcg_gen_qemu_st32(val, addr, index);
886 static inline void gen_movl_T0_reg(DisasContext *s, int reg)
888 load_reg_var(s, cpu_T[0], reg);
891 static inline void gen_movl_T1_reg(DisasContext *s, int reg)
893 load_reg_var(s, cpu_T[1], reg);
896 static inline void gen_movl_T2_reg(DisasContext *s, int reg)
898 load_reg_var(s, cpu_T[2], reg);
901 static inline void gen_set_pc_im(uint32_t val)
903 TCGv tmp = new_tmp();
904 tcg_gen_movi_i32(tmp, val);
905 store_cpu_field(tmp, regs[15]);
908 static inline void gen_movl_reg_TN(DisasContext *s, int reg, int t)
913 tcg_gen_andi_i32(tmp, cpu_T[t], ~1);
917 tcg_gen_st_i32(tmp, cpu_env, offsetof(CPUState, regs[reg]));
920 s->is_jmp = DISAS_JUMP;
924 static inline void gen_movl_reg_T0(DisasContext *s, int reg)
926 gen_movl_reg_TN(s, reg, 0);
929 static inline void gen_movl_reg_T1(DisasContext *s, int reg)
931 gen_movl_reg_TN(s, reg, 1);
934 /* Force a TB lookup after an instruction that changes the CPU state. */
935 static inline void gen_lookup_tb(DisasContext *s)
937 gen_op_movl_T0_im(s->pc);
938 gen_movl_reg_T0(s, 15);
939 s->is_jmp = DISAS_UPDATE;
942 static inline void gen_add_data_offset(DisasContext *s, unsigned int insn,
945 int val, rm, shift, shiftop;
948 if (!(insn & (1 << 25))) {
951 if (!(insn & (1 << 23)))
954 tcg_gen_addi_i32(var, var, val);
958 shift = (insn >> 7) & 0x1f;
959 shiftop = (insn >> 5) & 3;
960 offset = load_reg(s, rm);
961 gen_arm_shift_im(offset, shiftop, shift, 0);
962 if (!(insn & (1 << 23)))
963 tcg_gen_sub_i32(var, var, offset);
965 tcg_gen_add_i32(var, var, offset);
970 static inline void gen_add_datah_offset(DisasContext *s, unsigned int insn,
976 if (insn & (1 << 22)) {
978 val = (insn & 0xf) | ((insn >> 4) & 0xf0);
979 if (!(insn & (1 << 23)))
983 tcg_gen_addi_i32(var, var, val);
987 tcg_gen_addi_i32(var, var, extra);
989 offset = load_reg(s, rm);
990 if (!(insn & (1 << 23)))
991 tcg_gen_sub_i32(var, var, offset);
993 tcg_gen_add_i32(var, var, offset);
998 #define VFP_OP2(name) \
999 static inline void gen_vfp_##name(int dp) \
1002 gen_helper_vfp_##name##d(cpu_F0d, cpu_F0d, cpu_F1d, cpu_env); \
1004 gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, cpu_F1s, cpu_env); \
1007 #define VFP_OP1(name) \
1008 static inline void gen_vfp_##name(int dp, int arg) \
1011 gen_op_vfp_##name##d(arg); \
1013 gen_op_vfp_##name##s(arg); \
1023 static inline void gen_vfp_abs(int dp)
1026 gen_helper_vfp_absd(cpu_F0d, cpu_F0d);
1028 gen_helper_vfp_abss(cpu_F0s, cpu_F0s);
1031 static inline void gen_vfp_neg(int dp)
1034 gen_helper_vfp_negd(cpu_F0d, cpu_F0d);
1036 gen_helper_vfp_negs(cpu_F0s, cpu_F0s);
1039 static inline void gen_vfp_sqrt(int dp)
1042 gen_helper_vfp_sqrtd(cpu_F0d, cpu_F0d, cpu_env);
1044 gen_helper_vfp_sqrts(cpu_F0s, cpu_F0s, cpu_env);
1047 static inline void gen_vfp_cmp(int dp)
1050 gen_helper_vfp_cmpd(cpu_F0d, cpu_F1d, cpu_env);
1052 gen_helper_vfp_cmps(cpu_F0s, cpu_F1s, cpu_env);
1055 static inline void gen_vfp_cmpe(int dp)
1058 gen_helper_vfp_cmped(cpu_F0d, cpu_F1d, cpu_env);
1060 gen_helper_vfp_cmpes(cpu_F0s, cpu_F1s, cpu_env);
1063 static inline void gen_vfp_F1_ld0(int dp)
1066 tcg_gen_movi_i64(cpu_F1d, 0);
1068 tcg_gen_movi_i32(cpu_F1s, 0);
1071 static inline void gen_vfp_uito(int dp)
1074 gen_helper_vfp_uitod(cpu_F0d, cpu_F0s, cpu_env);
1076 gen_helper_vfp_uitos(cpu_F0s, cpu_F0s, cpu_env);
1079 static inline void gen_vfp_sito(int dp)
1082 gen_helper_vfp_sitod(cpu_F0d, cpu_F0s, cpu_env);
1084 gen_helper_vfp_sitos(cpu_F0s, cpu_F0s, cpu_env);
1087 static inline void gen_vfp_toui(int dp)
1090 gen_helper_vfp_touid(cpu_F0s, cpu_F0d, cpu_env);
1092 gen_helper_vfp_touis(cpu_F0s, cpu_F0s, cpu_env);
1095 static inline void gen_vfp_touiz(int dp)
1098 gen_helper_vfp_touizd(cpu_F0s, cpu_F0d, cpu_env);
1100 gen_helper_vfp_touizs(cpu_F0s, cpu_F0s, cpu_env);
1103 static inline void gen_vfp_tosi(int dp)
1106 gen_helper_vfp_tosid(cpu_F0s, cpu_F0d, cpu_env);
1108 gen_helper_vfp_tosis(cpu_F0s, cpu_F0s, cpu_env);
1111 static inline void gen_vfp_tosiz(int dp)
1114 gen_helper_vfp_tosizd(cpu_F0s, cpu_F0d, cpu_env);
1116 gen_helper_vfp_tosizs(cpu_F0s, cpu_F0s, cpu_env);
1119 #define VFP_GEN_FIX(name) \
1120 static inline void gen_vfp_##name(int dp, int shift) \
1123 gen_helper_vfp_##name##d(cpu_F0d, cpu_F0d, tcg_const_i32(shift), cpu_env);\
1125 gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, tcg_const_i32(shift), cpu_env);\
1137 static inline void gen_vfp_ld(DisasContext *s, int dp)
1140 tcg_gen_qemu_ld64(cpu_F0d, cpu_T[1], IS_USER(s));
1142 tcg_gen_qemu_ld32u(cpu_F0s, cpu_T[1], IS_USER(s));
1145 static inline void gen_vfp_st(DisasContext *s, int dp)
1148 tcg_gen_qemu_st64(cpu_F0d, cpu_T[1], IS_USER(s));
1150 tcg_gen_qemu_st32(cpu_F0s, cpu_T[1], IS_USER(s));
1154 vfp_reg_offset (int dp, int reg)
1157 return offsetof(CPUARMState, vfp.regs[reg]);
1159 return offsetof(CPUARMState, vfp.regs[reg >> 1])
1160 + offsetof(CPU_DoubleU, l.upper);
1162 return offsetof(CPUARMState, vfp.regs[reg >> 1])
1163 + offsetof(CPU_DoubleU, l.lower);
1167 /* Return the offset of a 32-bit piece of a NEON register.
1168 zero is the least significant end of the register. */
1170 neon_reg_offset (int reg, int n)
1174 return vfp_reg_offset(0, sreg);
1177 /* FIXME: Remove these. */
1178 #define neon_T0 cpu_T[0]
1179 #define neon_T1 cpu_T[1]
1180 #define NEON_GET_REG(T, reg, n) \
1181 tcg_gen_ld_i32(neon_##T, cpu_env, neon_reg_offset(reg, n))
1182 #define NEON_SET_REG(T, reg, n) \
1183 tcg_gen_st_i32(neon_##T, cpu_env, neon_reg_offset(reg, n))
1185 static TCGv neon_load_reg(int reg, int pass)
1187 TCGv tmp = new_tmp();
1188 tcg_gen_ld_i32(tmp, cpu_env, neon_reg_offset(reg, pass));
1192 static void neon_store_reg(int reg, int pass, TCGv var)
1194 tcg_gen_st_i32(var, cpu_env, neon_reg_offset(reg, pass));
1198 static inline void neon_load_reg64(TCGv var, int reg)
1200 tcg_gen_ld_i64(var, cpu_env, vfp_reg_offset(1, reg));
1203 static inline void neon_store_reg64(TCGv var, int reg)
1205 tcg_gen_st_i64(var, cpu_env, vfp_reg_offset(1, reg));
1208 #define tcg_gen_ld_f32 tcg_gen_ld_i32
1209 #define tcg_gen_ld_f64 tcg_gen_ld_i64
1210 #define tcg_gen_st_f32 tcg_gen_st_i32
1211 #define tcg_gen_st_f64 tcg_gen_st_i64
1213 static inline void gen_mov_F0_vreg(int dp, int reg)
1216 tcg_gen_ld_f64(cpu_F0d, cpu_env, vfp_reg_offset(dp, reg));
1218 tcg_gen_ld_f32(cpu_F0s, cpu_env, vfp_reg_offset(dp, reg));
1221 static inline void gen_mov_F1_vreg(int dp, int reg)
1224 tcg_gen_ld_f64(cpu_F1d, cpu_env, vfp_reg_offset(dp, reg));
1226 tcg_gen_ld_f32(cpu_F1s, cpu_env, vfp_reg_offset(dp, reg));
1229 static inline void gen_mov_vreg_F0(int dp, int reg)
1232 tcg_gen_st_f64(cpu_F0d, cpu_env, vfp_reg_offset(dp, reg));
1234 tcg_gen_st_f32(cpu_F0s, cpu_env, vfp_reg_offset(dp, reg));
1237 #define ARM_CP_RW_BIT (1 << 20)
1239 static inline void iwmmxt_load_reg(TCGv var, int reg)
1241 tcg_gen_ld_i64(var, cpu_env, offsetof(CPUState, iwmmxt.regs[reg]));
1244 static inline void iwmmxt_store_reg(TCGv var, int reg)
1246 tcg_gen_st_i64(var, cpu_env, offsetof(CPUState, iwmmxt.regs[reg]));
1249 static inline void gen_op_iwmmxt_movl_wCx_T0(int reg)
1251 tcg_gen_st_i32(cpu_T[0], cpu_env, offsetof(CPUState, iwmmxt.cregs[reg]));
1254 static inline void gen_op_iwmmxt_movl_T0_wCx(int reg)
1256 tcg_gen_ld_i32(cpu_T[0], cpu_env, offsetof(CPUState, iwmmxt.cregs[reg]));
1259 static inline void gen_op_iwmmxt_movl_T1_wCx(int reg)
1261 tcg_gen_ld_i32(cpu_T[1], cpu_env, offsetof(CPUState, iwmmxt.cregs[reg]));
1264 static inline void gen_op_iwmmxt_movq_wRn_M0(int rn)
1266 iwmmxt_store_reg(cpu_M0, rn);
1269 static inline void gen_op_iwmmxt_movq_M0_wRn(int rn)
1271 iwmmxt_load_reg(cpu_M0, rn);
1274 static inline void gen_op_iwmmxt_orq_M0_wRn(int rn)
1276 iwmmxt_load_reg(cpu_V1, rn);
1277 tcg_gen_or_i64(cpu_M0, cpu_M0, cpu_V1);
1280 static inline void gen_op_iwmmxt_andq_M0_wRn(int rn)
1282 iwmmxt_load_reg(cpu_V1, rn);
1283 tcg_gen_and_i64(cpu_M0, cpu_M0, cpu_V1);
1286 static inline void gen_op_iwmmxt_xorq_M0_wRn(int rn)
1288 iwmmxt_load_reg(cpu_V1, rn);
1289 tcg_gen_xor_i64(cpu_M0, cpu_M0, cpu_V1);
1292 #define IWMMXT_OP(name) \
1293 static inline void gen_op_iwmmxt_##name##_M0_wRn(int rn) \
1295 iwmmxt_load_reg(cpu_V1, rn); \
1296 gen_helper_iwmmxt_##name(cpu_M0, cpu_M0, cpu_V1); \
1299 #define IWMMXT_OP_ENV(name) \
1300 static inline void gen_op_iwmmxt_##name##_M0_wRn(int rn) \
1302 iwmmxt_load_reg(cpu_V1, rn); \
1303 gen_helper_iwmmxt_##name(cpu_M0, cpu_env, cpu_M0, cpu_V1); \
1306 #define IWMMXT_OP_ENV_SIZE(name) \
1307 IWMMXT_OP_ENV(name##b) \
1308 IWMMXT_OP_ENV(name##w) \
1309 IWMMXT_OP_ENV(name##l)
1311 #define IWMMXT_OP_ENV1(name) \
1312 static inline void gen_op_iwmmxt_##name##_M0(void) \
1314 gen_helper_iwmmxt_##name(cpu_M0, cpu_env, cpu_M0); \
1328 IWMMXT_OP_ENV_SIZE(unpackl)
1329 IWMMXT_OP_ENV_SIZE(unpackh)
1331 IWMMXT_OP_ENV1(unpacklub)
1332 IWMMXT_OP_ENV1(unpackluw)
1333 IWMMXT_OP_ENV1(unpacklul)
1334 IWMMXT_OP_ENV1(unpackhub)
1335 IWMMXT_OP_ENV1(unpackhuw)
1336 IWMMXT_OP_ENV1(unpackhul)
1337 IWMMXT_OP_ENV1(unpacklsb)
1338 IWMMXT_OP_ENV1(unpacklsw)
1339 IWMMXT_OP_ENV1(unpacklsl)
1340 IWMMXT_OP_ENV1(unpackhsb)
1341 IWMMXT_OP_ENV1(unpackhsw)
1342 IWMMXT_OP_ENV1(unpackhsl)
1344 IWMMXT_OP_ENV_SIZE(cmpeq)
1345 IWMMXT_OP_ENV_SIZE(cmpgtu)
1346 IWMMXT_OP_ENV_SIZE(cmpgts)
1348 IWMMXT_OP_ENV_SIZE(mins)
1349 IWMMXT_OP_ENV_SIZE(minu)
1350 IWMMXT_OP_ENV_SIZE(maxs)
1351 IWMMXT_OP_ENV_SIZE(maxu)
1353 IWMMXT_OP_ENV_SIZE(subn)
1354 IWMMXT_OP_ENV_SIZE(addn)
1355 IWMMXT_OP_ENV_SIZE(subu)
1356 IWMMXT_OP_ENV_SIZE(addu)
1357 IWMMXT_OP_ENV_SIZE(subs)
1358 IWMMXT_OP_ENV_SIZE(adds)
1360 IWMMXT_OP_ENV(avgb0)
1361 IWMMXT_OP_ENV(avgb1)
1362 IWMMXT_OP_ENV(avgw0)
1363 IWMMXT_OP_ENV(avgw1)
1367 IWMMXT_OP_ENV(packuw)
1368 IWMMXT_OP_ENV(packul)
1369 IWMMXT_OP_ENV(packuq)
1370 IWMMXT_OP_ENV(packsw)
1371 IWMMXT_OP_ENV(packsl)
1372 IWMMXT_OP_ENV(packsq)
1374 static inline void gen_op_iwmmxt_muladdsl_M0_T0_T1(void)
1376 gen_helper_iwmmxt_muladdsl(cpu_M0, cpu_M0, cpu_T[0], cpu_T[1]);
1379 static inline void gen_op_iwmmxt_muladdsw_M0_T0_T1(void)
1381 gen_helper_iwmmxt_muladdsw(cpu_M0, cpu_M0, cpu_T[0], cpu_T[1]);
1384 static inline void gen_op_iwmmxt_muladdswl_M0_T0_T1(void)
1386 gen_helper_iwmmxt_muladdswl(cpu_M0, cpu_M0, cpu_T[0], cpu_T[1]);
1389 static inline void gen_op_iwmmxt_align_M0_T0_wRn(int rn)
1391 iwmmxt_load_reg(cpu_V1, rn);
1392 gen_helper_iwmmxt_align(cpu_M0, cpu_M0, cpu_V1, cpu_T[0]);
1395 static inline void gen_op_iwmmxt_insr_M0_T0_T1(int shift)
1397 TCGv tmp = tcg_const_i32(shift);
1398 gen_helper_iwmmxt_insr(cpu_M0, cpu_M0, cpu_T[0], cpu_T[1], tmp);
1401 static inline void gen_op_iwmmxt_extrsb_T0_M0(int shift)
1403 tcg_gen_shri_i64(cpu_M0, cpu_M0, shift);
1404 tcg_gen_trunc_i64_i32(cpu_T[0], cpu_M0);
1405 tcg_gen_ext8s_i32(cpu_T[0], cpu_T[0]);
1408 static inline void gen_op_iwmmxt_extrsw_T0_M0(int shift)
1410 tcg_gen_shri_i64(cpu_M0, cpu_M0, shift);
1411 tcg_gen_trunc_i64_i32(cpu_T[0], cpu_M0);
1412 tcg_gen_ext16s_i32(cpu_T[0], cpu_T[0]);
1415 static inline void gen_op_iwmmxt_extru_T0_M0(int shift, uint32_t mask)
1417 tcg_gen_shri_i64(cpu_M0, cpu_M0, shift);
1418 tcg_gen_trunc_i64_i32(cpu_T[0], cpu_M0);
1420 tcg_gen_andi_i32(cpu_T[0], cpu_T[0], mask);
1423 static void gen_op_iwmmxt_set_mup(void)
1426 tmp = load_cpu_field(iwmmxt.cregs[ARM_IWMMXT_wCon]);
1427 tcg_gen_ori_i32(tmp, tmp, 2);
1428 store_cpu_field(tmp, iwmmxt.cregs[ARM_IWMMXT_wCon]);
1431 static void gen_op_iwmmxt_set_cup(void)
1434 tmp = load_cpu_field(iwmmxt.cregs[ARM_IWMMXT_wCon]);
1435 tcg_gen_ori_i32(tmp, tmp, 1);
1436 store_cpu_field(tmp, iwmmxt.cregs[ARM_IWMMXT_wCon]);
1439 static void gen_op_iwmmxt_setpsr_nz(void)
1441 TCGv tmp = new_tmp();
1442 gen_helper_iwmmxt_setpsr_nz(tmp, cpu_M0);
1443 store_cpu_field(tmp, iwmmxt.cregs[ARM_IWMMXT_wCASF]);
1446 static inline void gen_op_iwmmxt_addl_M0_wRn(int rn)
1448 iwmmxt_load_reg(cpu_V1, rn);
1449 tcg_gen_andi_i64(cpu_V1, cpu_V1, 0xffffffffu);
1450 tcg_gen_add_i64(cpu_M0, cpu_M0, cpu_V1);
1454 static void gen_iwmmxt_movl_T0_T1_wRn(int rn)
1456 iwmmxt_load_reg(cpu_V0, rn);
1457 tcg_gen_trunc_i64_i32(cpu_T[0], cpu_V0);
1458 tcg_gen_shri_i64(cpu_V0, cpu_V0, 32);
1459 tcg_gen_trunc_i64_i32(cpu_T[1], cpu_V0);
1462 static void gen_iwmmxt_movl_wRn_T0_T1(int rn)
1464 tcg_gen_extu_i32_i64(cpu_V0, cpu_T[0]);
1465 tcg_gen_extu_i32_i64(cpu_V1, cpu_T[0]);
1466 tcg_gen_shli_i64(cpu_V1, cpu_V1, 32);
1467 tcg_gen_or_i64(cpu_V0, cpu_V0, cpu_V1);
1468 iwmmxt_store_reg(cpu_V0, rn);
1471 static inline int gen_iwmmxt_address(DisasContext *s, uint32_t insn)
1476 rd = (insn >> 16) & 0xf;
1477 gen_movl_T1_reg(s, rd);
1479 offset = (insn & 0xff) << ((insn >> 7) & 2);
1480 if (insn & (1 << 24)) {
1482 if (insn & (1 << 23))
1483 gen_op_addl_T1_im(offset);
1485 gen_op_addl_T1_im(-offset);
1487 if (insn & (1 << 21))
1488 gen_movl_reg_T1(s, rd);
1489 } else if (insn & (1 << 21)) {
1491 if (insn & (1 << 23))
1492 gen_op_movl_T0_im(offset);
1494 gen_op_movl_T0_im(- offset);
1495 gen_op_addl_T0_T1();
1496 gen_movl_reg_T0(s, rd);
1497 } else if (!(insn & (1 << 23)))
1502 static inline int gen_iwmmxt_shift(uint32_t insn, uint32_t mask)
1504 int rd = (insn >> 0) & 0xf;
1506 if (insn & (1 << 8))
1507 if (rd < ARM_IWMMXT_wCGR0 || rd > ARM_IWMMXT_wCGR3)
1510 gen_op_iwmmxt_movl_T0_wCx(rd);
1512 gen_iwmmxt_movl_T0_T1_wRn(rd);
1514 gen_op_movl_T1_im(mask);
1515 gen_op_andl_T0_T1();
1519 /* Disassemble an iwMMXt instruction. Returns nonzero if an error occured
1520 (ie. an undefined instruction). */
1521 static int disas_iwmmxt_insn(CPUState *env, DisasContext *s, uint32_t insn)
1524 int rdhi, rdlo, rd0, rd1, i;
1527 if ((insn & 0x0e000e00) == 0x0c000000) {
1528 if ((insn & 0x0fe00ff0) == 0x0c400000) {
1530 rdlo = (insn >> 12) & 0xf;
1531 rdhi = (insn >> 16) & 0xf;
1532 if (insn & ARM_CP_RW_BIT) { /* TMRRC */
1533 gen_iwmmxt_movl_T0_T1_wRn(wrd);
1534 gen_movl_reg_T0(s, rdlo);
1535 gen_movl_reg_T1(s, rdhi);
1536 } else { /* TMCRR */
1537 gen_movl_T0_reg(s, rdlo);
1538 gen_movl_T1_reg(s, rdhi);
1539 gen_iwmmxt_movl_wRn_T0_T1(wrd);
1540 gen_op_iwmmxt_set_mup();
1545 wrd = (insn >> 12) & 0xf;
1546 if (gen_iwmmxt_address(s, insn))
1548 if (insn & ARM_CP_RW_BIT) {
1549 if ((insn >> 28) == 0xf) { /* WLDRW wCx */
1550 tmp = gen_ld32(cpu_T[1], IS_USER(s));
1551 tcg_gen_mov_i32(cpu_T[0], tmp);
1553 gen_op_iwmmxt_movl_wCx_T0(wrd);
1556 if (insn & (1 << 8)) {
1557 if (insn & (1 << 22)) { /* WLDRD */
1558 tcg_gen_qemu_ld64(cpu_M0, cpu_T[1], IS_USER(s));
1560 } else { /* WLDRW wRd */
1561 tmp = gen_ld32(cpu_T[1], IS_USER(s));
1564 if (insn & (1 << 22)) { /* WLDRH */
1565 tmp = gen_ld16u(cpu_T[1], IS_USER(s));
1566 } else { /* WLDRB */
1567 tmp = gen_ld8u(cpu_T[1], IS_USER(s));
1571 tcg_gen_extu_i32_i64(cpu_M0, tmp);
1574 gen_op_iwmmxt_movq_wRn_M0(wrd);
1577 if ((insn >> 28) == 0xf) { /* WSTRW wCx */
1578 gen_op_iwmmxt_movl_T0_wCx(wrd);
1580 tcg_gen_mov_i32(tmp, cpu_T[0]);
1581 gen_st32(tmp, cpu_T[1], IS_USER(s));
1583 gen_op_iwmmxt_movq_M0_wRn(wrd);
1585 if (insn & (1 << 8)) {
1586 if (insn & (1 << 22)) { /* WSTRD */
1588 tcg_gen_qemu_st64(cpu_M0, cpu_T[1], IS_USER(s));
1589 } else { /* WSTRW wRd */
1590 tcg_gen_trunc_i64_i32(tmp, cpu_M0);
1591 gen_st32(tmp, cpu_T[1], IS_USER(s));
1594 if (insn & (1 << 22)) { /* WSTRH */
1595 tcg_gen_trunc_i64_i32(tmp, cpu_M0);
1596 gen_st16(tmp, cpu_T[1], IS_USER(s));
1597 } else { /* WSTRB */
1598 tcg_gen_trunc_i64_i32(tmp, cpu_M0);
1599 gen_st8(tmp, cpu_T[1], IS_USER(s));
1607 if ((insn & 0x0f000000) != 0x0e000000)
1610 switch (((insn >> 12) & 0xf00) | ((insn >> 4) & 0xff)) {
1611 case 0x000: /* WOR */
1612 wrd = (insn >> 12) & 0xf;
1613 rd0 = (insn >> 0) & 0xf;
1614 rd1 = (insn >> 16) & 0xf;
1615 gen_op_iwmmxt_movq_M0_wRn(rd0);
1616 gen_op_iwmmxt_orq_M0_wRn(rd1);
1617 gen_op_iwmmxt_setpsr_nz();
1618 gen_op_iwmmxt_movq_wRn_M0(wrd);
1619 gen_op_iwmmxt_set_mup();
1620 gen_op_iwmmxt_set_cup();
1622 case 0x011: /* TMCR */
1625 rd = (insn >> 12) & 0xf;
1626 wrd = (insn >> 16) & 0xf;
1628 case ARM_IWMMXT_wCID:
1629 case ARM_IWMMXT_wCASF:
1631 case ARM_IWMMXT_wCon:
1632 gen_op_iwmmxt_set_cup();
1634 case ARM_IWMMXT_wCSSF:
1635 gen_op_iwmmxt_movl_T0_wCx(wrd);
1636 gen_movl_T1_reg(s, rd);
1637 gen_op_bicl_T0_T1();
1638 gen_op_iwmmxt_movl_wCx_T0(wrd);
1640 case ARM_IWMMXT_wCGR0:
1641 case ARM_IWMMXT_wCGR1:
1642 case ARM_IWMMXT_wCGR2:
1643 case ARM_IWMMXT_wCGR3:
1644 gen_op_iwmmxt_set_cup();
1645 gen_movl_reg_T0(s, rd);
1646 gen_op_iwmmxt_movl_wCx_T0(wrd);
1652 case 0x100: /* WXOR */
1653 wrd = (insn >> 12) & 0xf;
1654 rd0 = (insn >> 0) & 0xf;
1655 rd1 = (insn >> 16) & 0xf;
1656 gen_op_iwmmxt_movq_M0_wRn(rd0);
1657 gen_op_iwmmxt_xorq_M0_wRn(rd1);
1658 gen_op_iwmmxt_setpsr_nz();
1659 gen_op_iwmmxt_movq_wRn_M0(wrd);
1660 gen_op_iwmmxt_set_mup();
1661 gen_op_iwmmxt_set_cup();
1663 case 0x111: /* TMRC */
1666 rd = (insn >> 12) & 0xf;
1667 wrd = (insn >> 16) & 0xf;
1668 gen_op_iwmmxt_movl_T0_wCx(wrd);
1669 gen_movl_reg_T0(s, rd);
1671 case 0x300: /* WANDN */
1672 wrd = (insn >> 12) & 0xf;
1673 rd0 = (insn >> 0) & 0xf;
1674 rd1 = (insn >> 16) & 0xf;
1675 gen_op_iwmmxt_movq_M0_wRn(rd0);
1676 tcg_gen_neg_i64(cpu_M0, cpu_M0);
1677 gen_op_iwmmxt_andq_M0_wRn(rd1);
1678 gen_op_iwmmxt_setpsr_nz();
1679 gen_op_iwmmxt_movq_wRn_M0(wrd);
1680 gen_op_iwmmxt_set_mup();
1681 gen_op_iwmmxt_set_cup();
1683 case 0x200: /* WAND */
1684 wrd = (insn >> 12) & 0xf;
1685 rd0 = (insn >> 0) & 0xf;
1686 rd1 = (insn >> 16) & 0xf;
1687 gen_op_iwmmxt_movq_M0_wRn(rd0);
1688 gen_op_iwmmxt_andq_M0_wRn(rd1);
1689 gen_op_iwmmxt_setpsr_nz();
1690 gen_op_iwmmxt_movq_wRn_M0(wrd);
1691 gen_op_iwmmxt_set_mup();
1692 gen_op_iwmmxt_set_cup();
1694 case 0x810: case 0xa10: /* WMADD */
1695 wrd = (insn >> 12) & 0xf;
1696 rd0 = (insn >> 0) & 0xf;
1697 rd1 = (insn >> 16) & 0xf;
1698 gen_op_iwmmxt_movq_M0_wRn(rd0);
1699 if (insn & (1 << 21))
1700 gen_op_iwmmxt_maddsq_M0_wRn(rd1);
1702 gen_op_iwmmxt_madduq_M0_wRn(rd1);
1703 gen_op_iwmmxt_movq_wRn_M0(wrd);
1704 gen_op_iwmmxt_set_mup();
1706 case 0x10e: case 0x50e: case 0x90e: case 0xd0e: /* WUNPCKIL */
1707 wrd = (insn >> 12) & 0xf;
1708 rd0 = (insn >> 16) & 0xf;
1709 rd1 = (insn >> 0) & 0xf;
1710 gen_op_iwmmxt_movq_M0_wRn(rd0);
1711 switch ((insn >> 22) & 3) {
1713 gen_op_iwmmxt_unpacklb_M0_wRn(rd1);
1716 gen_op_iwmmxt_unpacklw_M0_wRn(rd1);
1719 gen_op_iwmmxt_unpackll_M0_wRn(rd1);
1724 gen_op_iwmmxt_movq_wRn_M0(wrd);
1725 gen_op_iwmmxt_set_mup();
1726 gen_op_iwmmxt_set_cup();
1728 case 0x10c: case 0x50c: case 0x90c: case 0xd0c: /* WUNPCKIH */
1729 wrd = (insn >> 12) & 0xf;
1730 rd0 = (insn >> 16) & 0xf;
1731 rd1 = (insn >> 0) & 0xf;
1732 gen_op_iwmmxt_movq_M0_wRn(rd0);
1733 switch ((insn >> 22) & 3) {
1735 gen_op_iwmmxt_unpackhb_M0_wRn(rd1);
1738 gen_op_iwmmxt_unpackhw_M0_wRn(rd1);
1741 gen_op_iwmmxt_unpackhl_M0_wRn(rd1);
1746 gen_op_iwmmxt_movq_wRn_M0(wrd);
1747 gen_op_iwmmxt_set_mup();
1748 gen_op_iwmmxt_set_cup();
1750 case 0x012: case 0x112: case 0x412: case 0x512: /* WSAD */
1751 wrd = (insn >> 12) & 0xf;
1752 rd0 = (insn >> 16) & 0xf;
1753 rd1 = (insn >> 0) & 0xf;
1754 gen_op_iwmmxt_movq_M0_wRn(rd0);
1755 if (insn & (1 << 22))
1756 gen_op_iwmmxt_sadw_M0_wRn(rd1);
1758 gen_op_iwmmxt_sadb_M0_wRn(rd1);
1759 if (!(insn & (1 << 20)))
1760 gen_op_iwmmxt_addl_M0_wRn(wrd);
1761 gen_op_iwmmxt_movq_wRn_M0(wrd);
1762 gen_op_iwmmxt_set_mup();
1764 case 0x010: case 0x110: case 0x210: case 0x310: /* WMUL */
1765 wrd = (insn >> 12) & 0xf;
1766 rd0 = (insn >> 16) & 0xf;
1767 rd1 = (insn >> 0) & 0xf;
1768 gen_op_iwmmxt_movq_M0_wRn(rd0);
1769 if (insn & (1 << 21)) {
1770 if (insn & (1 << 20))
1771 gen_op_iwmmxt_mulshw_M0_wRn(rd1);
1773 gen_op_iwmmxt_mulslw_M0_wRn(rd1);
1775 if (insn & (1 << 20))
1776 gen_op_iwmmxt_muluhw_M0_wRn(rd1);
1778 gen_op_iwmmxt_mululw_M0_wRn(rd1);
1780 gen_op_iwmmxt_movq_wRn_M0(wrd);
1781 gen_op_iwmmxt_set_mup();
1783 case 0x410: case 0x510: case 0x610: case 0x710: /* WMAC */
1784 wrd = (insn >> 12) & 0xf;
1785 rd0 = (insn >> 16) & 0xf;
1786 rd1 = (insn >> 0) & 0xf;
1787 gen_op_iwmmxt_movq_M0_wRn(rd0);
1788 if (insn & (1 << 21))
1789 gen_op_iwmmxt_macsw_M0_wRn(rd1);
1791 gen_op_iwmmxt_macuw_M0_wRn(rd1);
1792 if (!(insn & (1 << 20))) {
1793 iwmmxt_load_reg(cpu_V1, wrd);
1794 tcg_gen_add_i64(cpu_M0, cpu_M0, cpu_V1);
1796 gen_op_iwmmxt_movq_wRn_M0(wrd);
1797 gen_op_iwmmxt_set_mup();
1799 case 0x006: case 0x406: case 0x806: case 0xc06: /* WCMPEQ */
1800 wrd = (insn >> 12) & 0xf;
1801 rd0 = (insn >> 16) & 0xf;
1802 rd1 = (insn >> 0) & 0xf;
1803 gen_op_iwmmxt_movq_M0_wRn(rd0);
1804 switch ((insn >> 22) & 3) {
1806 gen_op_iwmmxt_cmpeqb_M0_wRn(rd1);
1809 gen_op_iwmmxt_cmpeqw_M0_wRn(rd1);
1812 gen_op_iwmmxt_cmpeql_M0_wRn(rd1);
1817 gen_op_iwmmxt_movq_wRn_M0(wrd);
1818 gen_op_iwmmxt_set_mup();
1819 gen_op_iwmmxt_set_cup();
1821 case 0x800: case 0x900: case 0xc00: case 0xd00: /* WAVG2 */
1822 wrd = (insn >> 12) & 0xf;
1823 rd0 = (insn >> 16) & 0xf;
1824 rd1 = (insn >> 0) & 0xf;
1825 gen_op_iwmmxt_movq_M0_wRn(rd0);
1826 if (insn & (1 << 22)) {
1827 if (insn & (1 << 20))
1828 gen_op_iwmmxt_avgw1_M0_wRn(rd1);
1830 gen_op_iwmmxt_avgw0_M0_wRn(rd1);
1832 if (insn & (1 << 20))
1833 gen_op_iwmmxt_avgb1_M0_wRn(rd1);
1835 gen_op_iwmmxt_avgb0_M0_wRn(rd1);
1837 gen_op_iwmmxt_movq_wRn_M0(wrd);
1838 gen_op_iwmmxt_set_mup();
1839 gen_op_iwmmxt_set_cup();
1841 case 0x802: case 0x902: case 0xa02: case 0xb02: /* WALIGNR */
1842 wrd = (insn >> 12) & 0xf;
1843 rd0 = (insn >> 16) & 0xf;
1844 rd1 = (insn >> 0) & 0xf;
1845 gen_op_iwmmxt_movq_M0_wRn(rd0);
1846 gen_op_iwmmxt_movl_T0_wCx(ARM_IWMMXT_wCGR0 + ((insn >> 20) & 3));
1847 gen_op_movl_T1_im(7);
1848 gen_op_andl_T0_T1();
1849 gen_op_iwmmxt_align_M0_T0_wRn(rd1);
1850 gen_op_iwmmxt_movq_wRn_M0(wrd);
1851 gen_op_iwmmxt_set_mup();
1853 case 0x601: case 0x605: case 0x609: case 0x60d: /* TINSR */
1854 rd = (insn >> 12) & 0xf;
1855 wrd = (insn >> 16) & 0xf;
1856 gen_movl_T0_reg(s, rd);
1857 gen_op_iwmmxt_movq_M0_wRn(wrd);
1858 switch ((insn >> 6) & 3) {
1860 gen_op_movl_T1_im(0xff);
1861 gen_op_iwmmxt_insr_M0_T0_T1((insn & 7) << 3);
1864 gen_op_movl_T1_im(0xffff);
1865 gen_op_iwmmxt_insr_M0_T0_T1((insn & 3) << 4);
1868 gen_op_movl_T1_im(0xffffffff);
1869 gen_op_iwmmxt_insr_M0_T0_T1((insn & 1) << 5);
1874 gen_op_iwmmxt_movq_wRn_M0(wrd);
1875 gen_op_iwmmxt_set_mup();
1877 case 0x107: case 0x507: case 0x907: case 0xd07: /* TEXTRM */
1878 rd = (insn >> 12) & 0xf;
1879 wrd = (insn >> 16) & 0xf;
1882 gen_op_iwmmxt_movq_M0_wRn(wrd);
1883 switch ((insn >> 22) & 3) {
1886 gen_op_iwmmxt_extrsb_T0_M0((insn & 7) << 3);
1888 gen_op_iwmmxt_extru_T0_M0((insn & 7) << 3, 0xff);
1893 gen_op_iwmmxt_extrsw_T0_M0((insn & 3) << 4);
1895 gen_op_iwmmxt_extru_T0_M0((insn & 3) << 4, 0xffff);
1899 gen_op_iwmmxt_extru_T0_M0((insn & 1) << 5, ~0u);
1904 gen_movl_reg_T0(s, rd);
1906 case 0x117: case 0x517: case 0x917: case 0xd17: /* TEXTRC */
1907 if ((insn & 0x000ff008) != 0x0003f000)
1909 gen_op_iwmmxt_movl_T1_wCx(ARM_IWMMXT_wCASF);
1910 switch ((insn >> 22) & 3) {
1912 gen_op_shrl_T1_im(((insn & 7) << 2) + 0);
1915 gen_op_shrl_T1_im(((insn & 3) << 3) + 4);
1918 gen_op_shrl_T1_im(((insn & 1) << 4) + 12);
1923 gen_op_shll_T1_im(28);
1924 gen_set_nzcv(cpu_T[1]);
1926 case 0x401: case 0x405: case 0x409: case 0x40d: /* TBCST */
1927 rd = (insn >> 12) & 0xf;
1928 wrd = (insn >> 16) & 0xf;
1929 gen_movl_T0_reg(s, rd);
1930 switch ((insn >> 6) & 3) {
1932 gen_helper_iwmmxt_bcstb(cpu_M0, cpu_T[0]);
1935 gen_helper_iwmmxt_bcstw(cpu_M0, cpu_T[0]);
1938 gen_helper_iwmmxt_bcstl(cpu_M0, cpu_T[0]);
1943 gen_op_iwmmxt_movq_wRn_M0(wrd);
1944 gen_op_iwmmxt_set_mup();
1946 case 0x113: case 0x513: case 0x913: case 0xd13: /* TANDC */
1947 if ((insn & 0x000ff00f) != 0x0003f000)
1949 gen_op_iwmmxt_movl_T1_wCx(ARM_IWMMXT_wCASF);
1950 switch ((insn >> 22) & 3) {
1952 for (i = 0; i < 7; i ++) {
1953 gen_op_shll_T1_im(4);
1954 gen_op_andl_T0_T1();
1958 for (i = 0; i < 3; i ++) {
1959 gen_op_shll_T1_im(8);
1960 gen_op_andl_T0_T1();
1964 gen_op_shll_T1_im(16);
1965 gen_op_andl_T0_T1();
1970 gen_set_nzcv(cpu_T[0]);
1972 case 0x01c: case 0x41c: case 0x81c: case 0xc1c: /* WACC */
1973 wrd = (insn >> 12) & 0xf;
1974 rd0 = (insn >> 16) & 0xf;
1975 gen_op_iwmmxt_movq_M0_wRn(rd0);
1976 switch ((insn >> 22) & 3) {
1978 gen_helper_iwmmxt_addcb(cpu_M0, cpu_M0);
1981 gen_helper_iwmmxt_addcw(cpu_M0, cpu_M0);
1984 gen_helper_iwmmxt_addcl(cpu_M0, cpu_M0);
1989 gen_op_iwmmxt_movq_wRn_M0(wrd);
1990 gen_op_iwmmxt_set_mup();
1992 case 0x115: case 0x515: case 0x915: case 0xd15: /* TORC */
1993 if ((insn & 0x000ff00f) != 0x0003f000)
1995 gen_op_iwmmxt_movl_T1_wCx(ARM_IWMMXT_wCASF);
1996 switch ((insn >> 22) & 3) {
1998 for (i = 0; i < 7; i ++) {
1999 gen_op_shll_T1_im(4);
2004 for (i = 0; i < 3; i ++) {
2005 gen_op_shll_T1_im(8);
2010 gen_op_shll_T1_im(16);
2016 gen_set_nzcv(cpu_T[0]);
2018 case 0x103: case 0x503: case 0x903: case 0xd03: /* TMOVMSK */
2019 rd = (insn >> 12) & 0xf;
2020 rd0 = (insn >> 16) & 0xf;
2021 if ((insn & 0xf) != 0)
2023 gen_op_iwmmxt_movq_M0_wRn(rd0);
2024 switch ((insn >> 22) & 3) {
2026 gen_helper_iwmmxt_msbb(cpu_T[0], cpu_M0);
2029 gen_helper_iwmmxt_msbw(cpu_T[0], cpu_M0);
2032 gen_helper_iwmmxt_msbl(cpu_T[0], cpu_M0);
2037 gen_movl_reg_T0(s, rd);
2039 case 0x106: case 0x306: case 0x506: case 0x706: /* WCMPGT */
2040 case 0x906: case 0xb06: case 0xd06: case 0xf06:
2041 wrd = (insn >> 12) & 0xf;
2042 rd0 = (insn >> 16) & 0xf;
2043 rd1 = (insn >> 0) & 0xf;
2044 gen_op_iwmmxt_movq_M0_wRn(rd0);
2045 switch ((insn >> 22) & 3) {
2047 if (insn & (1 << 21))
2048 gen_op_iwmmxt_cmpgtsb_M0_wRn(rd1);
2050 gen_op_iwmmxt_cmpgtub_M0_wRn(rd1);
2053 if (insn & (1 << 21))
2054 gen_op_iwmmxt_cmpgtsw_M0_wRn(rd1);
2056 gen_op_iwmmxt_cmpgtuw_M0_wRn(rd1);
2059 if (insn & (1 << 21))
2060 gen_op_iwmmxt_cmpgtsl_M0_wRn(rd1);
2062 gen_op_iwmmxt_cmpgtul_M0_wRn(rd1);
2067 gen_op_iwmmxt_movq_wRn_M0(wrd);
2068 gen_op_iwmmxt_set_mup();
2069 gen_op_iwmmxt_set_cup();
2071 case 0x00e: case 0x20e: case 0x40e: case 0x60e: /* WUNPCKEL */
2072 case 0x80e: case 0xa0e: case 0xc0e: case 0xe0e:
2073 wrd = (insn >> 12) & 0xf;
2074 rd0 = (insn >> 16) & 0xf;
2075 gen_op_iwmmxt_movq_M0_wRn(rd0);
2076 switch ((insn >> 22) & 3) {
2078 if (insn & (1 << 21))
2079 gen_op_iwmmxt_unpacklsb_M0();
2081 gen_op_iwmmxt_unpacklub_M0();
2084 if (insn & (1 << 21))
2085 gen_op_iwmmxt_unpacklsw_M0();
2087 gen_op_iwmmxt_unpackluw_M0();
2090 if (insn & (1 << 21))
2091 gen_op_iwmmxt_unpacklsl_M0();
2093 gen_op_iwmmxt_unpacklul_M0();
2098 gen_op_iwmmxt_movq_wRn_M0(wrd);
2099 gen_op_iwmmxt_set_mup();
2100 gen_op_iwmmxt_set_cup();
2102 case 0x00c: case 0x20c: case 0x40c: case 0x60c: /* WUNPCKEH */
2103 case 0x80c: case 0xa0c: case 0xc0c: case 0xe0c:
2104 wrd = (insn >> 12) & 0xf;
2105 rd0 = (insn >> 16) & 0xf;
2106 gen_op_iwmmxt_movq_M0_wRn(rd0);
2107 switch ((insn >> 22) & 3) {
2109 if (insn & (1 << 21))
2110 gen_op_iwmmxt_unpackhsb_M0();
2112 gen_op_iwmmxt_unpackhub_M0();
2115 if (insn & (1 << 21))
2116 gen_op_iwmmxt_unpackhsw_M0();
2118 gen_op_iwmmxt_unpackhuw_M0();
2121 if (insn & (1 << 21))
2122 gen_op_iwmmxt_unpackhsl_M0();
2124 gen_op_iwmmxt_unpackhul_M0();
2129 gen_op_iwmmxt_movq_wRn_M0(wrd);
2130 gen_op_iwmmxt_set_mup();
2131 gen_op_iwmmxt_set_cup();
2133 case 0x204: case 0x604: case 0xa04: case 0xe04: /* WSRL */
2134 case 0x214: case 0x614: case 0xa14: case 0xe14:
2135 wrd = (insn >> 12) & 0xf;
2136 rd0 = (insn >> 16) & 0xf;
2137 gen_op_iwmmxt_movq_M0_wRn(rd0);
2138 if (gen_iwmmxt_shift(insn, 0xff))
2140 switch ((insn >> 22) & 3) {
2144 gen_helper_iwmmxt_srlw(cpu_M0, cpu_env, cpu_M0, cpu_T[0]);
2147 gen_helper_iwmmxt_srll(cpu_M0, cpu_env, cpu_M0, cpu_T[0]);
2150 gen_helper_iwmmxt_srlq(cpu_M0, cpu_env, cpu_M0, cpu_T[0]);
2153 gen_op_iwmmxt_movq_wRn_M0(wrd);
2154 gen_op_iwmmxt_set_mup();
2155 gen_op_iwmmxt_set_cup();
2157 case 0x004: case 0x404: case 0x804: case 0xc04: /* WSRA */
2158 case 0x014: case 0x414: case 0x814: case 0xc14:
2159 wrd = (insn >> 12) & 0xf;
2160 rd0 = (insn >> 16) & 0xf;
2161 gen_op_iwmmxt_movq_M0_wRn(rd0);
2162 if (gen_iwmmxt_shift(insn, 0xff))
2164 switch ((insn >> 22) & 3) {
2168 gen_helper_iwmmxt_sraw(cpu_M0, cpu_env, cpu_M0, cpu_T[0]);
2171 gen_helper_iwmmxt_sral(cpu_M0, cpu_env, cpu_M0, cpu_T[0]);
2174 gen_helper_iwmmxt_sraq(cpu_M0, cpu_env, cpu_M0, cpu_T[0]);
2177 gen_op_iwmmxt_movq_wRn_M0(wrd);
2178 gen_op_iwmmxt_set_mup();
2179 gen_op_iwmmxt_set_cup();
2181 case 0x104: case 0x504: case 0x904: case 0xd04: /* WSLL */
2182 case 0x114: case 0x514: case 0x914: case 0xd14:
2183 wrd = (insn >> 12) & 0xf;
2184 rd0 = (insn >> 16) & 0xf;
2185 gen_op_iwmmxt_movq_M0_wRn(rd0);
2186 if (gen_iwmmxt_shift(insn, 0xff))
2188 switch ((insn >> 22) & 3) {
2192 gen_helper_iwmmxt_sllw(cpu_M0, cpu_env, cpu_M0, cpu_T[0]);
2195 gen_helper_iwmmxt_slll(cpu_M0, cpu_env, cpu_M0, cpu_T[0]);
2198 gen_helper_iwmmxt_sllq(cpu_M0, cpu_env, cpu_M0, cpu_T[0]);
2201 gen_op_iwmmxt_movq_wRn_M0(wrd);
2202 gen_op_iwmmxt_set_mup();
2203 gen_op_iwmmxt_set_cup();
2205 case 0x304: case 0x704: case 0xb04: case 0xf04: /* WROR */
2206 case 0x314: case 0x714: case 0xb14: case 0xf14:
2207 wrd = (insn >> 12) & 0xf;
2208 rd0 = (insn >> 16) & 0xf;
2209 gen_op_iwmmxt_movq_M0_wRn(rd0);
2210 switch ((insn >> 22) & 3) {
2214 if (gen_iwmmxt_shift(insn, 0xf))
2216 gen_helper_iwmmxt_rorw(cpu_M0, cpu_env, cpu_M0, cpu_T[0]);
2219 if (gen_iwmmxt_shift(insn, 0x1f))
2221 gen_helper_iwmmxt_rorl(cpu_M0, cpu_env, cpu_M0, cpu_T[0]);
2224 if (gen_iwmmxt_shift(insn, 0x3f))
2226 gen_helper_iwmmxt_rorq(cpu_M0, cpu_env, cpu_M0, cpu_T[0]);
2229 gen_op_iwmmxt_movq_wRn_M0(wrd);
2230 gen_op_iwmmxt_set_mup();
2231 gen_op_iwmmxt_set_cup();
2233 case 0x116: case 0x316: case 0x516: case 0x716: /* WMIN */
2234 case 0x916: case 0xb16: case 0xd16: case 0xf16:
2235 wrd = (insn >> 12) & 0xf;
2236 rd0 = (insn >> 16) & 0xf;
2237 rd1 = (insn >> 0) & 0xf;
2238 gen_op_iwmmxt_movq_M0_wRn(rd0);
2239 switch ((insn >> 22) & 3) {
2241 if (insn & (1 << 21))
2242 gen_op_iwmmxt_minsb_M0_wRn(rd1);
2244 gen_op_iwmmxt_minub_M0_wRn(rd1);
2247 if (insn & (1 << 21))
2248 gen_op_iwmmxt_minsw_M0_wRn(rd1);
2250 gen_op_iwmmxt_minuw_M0_wRn(rd1);
2253 if (insn & (1 << 21))
2254 gen_op_iwmmxt_minsl_M0_wRn(rd1);
2256 gen_op_iwmmxt_minul_M0_wRn(rd1);
2261 gen_op_iwmmxt_movq_wRn_M0(wrd);
2262 gen_op_iwmmxt_set_mup();
2264 case 0x016: case 0x216: case 0x416: case 0x616: /* WMAX */
2265 case 0x816: case 0xa16: case 0xc16: case 0xe16:
2266 wrd = (insn >> 12) & 0xf;
2267 rd0 = (insn >> 16) & 0xf;
2268 rd1 = (insn >> 0) & 0xf;
2269 gen_op_iwmmxt_movq_M0_wRn(rd0);
2270 switch ((insn >> 22) & 3) {
2272 if (insn & (1 << 21))
2273 gen_op_iwmmxt_maxsb_M0_wRn(rd1);
2275 gen_op_iwmmxt_maxub_M0_wRn(rd1);
2278 if (insn & (1 << 21))
2279 gen_op_iwmmxt_maxsw_M0_wRn(rd1);
2281 gen_op_iwmmxt_maxuw_M0_wRn(rd1);
2284 if (insn & (1 << 21))
2285 gen_op_iwmmxt_maxsl_M0_wRn(rd1);
2287 gen_op_iwmmxt_maxul_M0_wRn(rd1);
2292 gen_op_iwmmxt_movq_wRn_M0(wrd);
2293 gen_op_iwmmxt_set_mup();
2295 case 0x002: case 0x102: case 0x202: case 0x302: /* WALIGNI */
2296 case 0x402: case 0x502: case 0x602: case 0x702:
2297 wrd = (insn >> 12) & 0xf;
2298 rd0 = (insn >> 16) & 0xf;
2299 rd1 = (insn >> 0) & 0xf;
2300 gen_op_iwmmxt_movq_M0_wRn(rd0);
2301 gen_op_movl_T0_im((insn >> 20) & 3);
2302 gen_op_iwmmxt_align_M0_T0_wRn(rd1);
2303 gen_op_iwmmxt_movq_wRn_M0(wrd);
2304 gen_op_iwmmxt_set_mup();
2306 case 0x01a: case 0x11a: case 0x21a: case 0x31a: /* WSUB */
2307 case 0x41a: case 0x51a: case 0x61a: case 0x71a:
2308 case 0x81a: case 0x91a: case 0xa1a: case 0xb1a:
2309 case 0xc1a: case 0xd1a: case 0xe1a: case 0xf1a:
2310 wrd = (insn >> 12) & 0xf;
2311 rd0 = (insn >> 16) & 0xf;
2312 rd1 = (insn >> 0) & 0xf;
2313 gen_op_iwmmxt_movq_M0_wRn(rd0);
2314 switch ((insn >> 20) & 0xf) {
2316 gen_op_iwmmxt_subnb_M0_wRn(rd1);
2319 gen_op_iwmmxt_subub_M0_wRn(rd1);
2322 gen_op_iwmmxt_subsb_M0_wRn(rd1);
2325 gen_op_iwmmxt_subnw_M0_wRn(rd1);
2328 gen_op_iwmmxt_subuw_M0_wRn(rd1);
2331 gen_op_iwmmxt_subsw_M0_wRn(rd1);
2334 gen_op_iwmmxt_subnl_M0_wRn(rd1);
2337 gen_op_iwmmxt_subul_M0_wRn(rd1);
2340 gen_op_iwmmxt_subsl_M0_wRn(rd1);
2345 gen_op_iwmmxt_movq_wRn_M0(wrd);
2346 gen_op_iwmmxt_set_mup();
2347 gen_op_iwmmxt_set_cup();
2349 case 0x01e: case 0x11e: case 0x21e: case 0x31e: /* WSHUFH */
2350 case 0x41e: case 0x51e: case 0x61e: case 0x71e:
2351 case 0x81e: case 0x91e: case 0xa1e: case 0xb1e:
2352 case 0xc1e: case 0xd1e: case 0xe1e: case 0xf1e:
2353 wrd = (insn >> 12) & 0xf;
2354 rd0 = (insn >> 16) & 0xf;
2355 gen_op_iwmmxt_movq_M0_wRn(rd0);
2356 gen_op_movl_T0_im(((insn >> 16) & 0xf0) | (insn & 0x0f));
2357 gen_helper_iwmmxt_shufh(cpu_M0, cpu_env, cpu_M0, cpu_T[0]);
2358 gen_op_iwmmxt_movq_wRn_M0(wrd);
2359 gen_op_iwmmxt_set_mup();
2360 gen_op_iwmmxt_set_cup();
2362 case 0x018: case 0x118: case 0x218: case 0x318: /* WADD */
2363 case 0x418: case 0x518: case 0x618: case 0x718:
2364 case 0x818: case 0x918: case 0xa18: case 0xb18:
2365 case 0xc18: case 0xd18: case 0xe18: case 0xf18:
2366 wrd = (insn >> 12) & 0xf;
2367 rd0 = (insn >> 16) & 0xf;
2368 rd1 = (insn >> 0) & 0xf;
2369 gen_op_iwmmxt_movq_M0_wRn(rd0);
2370 switch ((insn >> 20) & 0xf) {
2372 gen_op_iwmmxt_addnb_M0_wRn(rd1);
2375 gen_op_iwmmxt_addub_M0_wRn(rd1);
2378 gen_op_iwmmxt_addsb_M0_wRn(rd1);
2381 gen_op_iwmmxt_addnw_M0_wRn(rd1);
2384 gen_op_iwmmxt_adduw_M0_wRn(rd1);
2387 gen_op_iwmmxt_addsw_M0_wRn(rd1);
2390 gen_op_iwmmxt_addnl_M0_wRn(rd1);
2393 gen_op_iwmmxt_addul_M0_wRn(rd1);
2396 gen_op_iwmmxt_addsl_M0_wRn(rd1);
2401 gen_op_iwmmxt_movq_wRn_M0(wrd);
2402 gen_op_iwmmxt_set_mup();
2403 gen_op_iwmmxt_set_cup();
2405 case 0x008: case 0x108: case 0x208: case 0x308: /* WPACK */
2406 case 0x408: case 0x508: case 0x608: case 0x708:
2407 case 0x808: case 0x908: case 0xa08: case 0xb08:
2408 case 0xc08: case 0xd08: case 0xe08: case 0xf08:
2409 wrd = (insn >> 12) & 0xf;
2410 rd0 = (insn >> 16) & 0xf;
2411 rd1 = (insn >> 0) & 0xf;
2412 gen_op_iwmmxt_movq_M0_wRn(rd0);
2413 if (!(insn & (1 << 20)))
2415 switch ((insn >> 22) & 3) {
2419 if (insn & (1 << 21))
2420 gen_op_iwmmxt_packsw_M0_wRn(rd1);
2422 gen_op_iwmmxt_packuw_M0_wRn(rd1);
2425 if (insn & (1 << 21))
2426 gen_op_iwmmxt_packsl_M0_wRn(rd1);
2428 gen_op_iwmmxt_packul_M0_wRn(rd1);
2431 if (insn & (1 << 21))
2432 gen_op_iwmmxt_packsq_M0_wRn(rd1);
2434 gen_op_iwmmxt_packuq_M0_wRn(rd1);
2437 gen_op_iwmmxt_movq_wRn_M0(wrd);
2438 gen_op_iwmmxt_set_mup();
2439 gen_op_iwmmxt_set_cup();
2441 case 0x201: case 0x203: case 0x205: case 0x207:
2442 case 0x209: case 0x20b: case 0x20d: case 0x20f:
2443 case 0x211: case 0x213: case 0x215: case 0x217:
2444 case 0x219: case 0x21b: case 0x21d: case 0x21f:
2445 wrd = (insn >> 5) & 0xf;
2446 rd0 = (insn >> 12) & 0xf;
2447 rd1 = (insn >> 0) & 0xf;
2448 if (rd0 == 0xf || rd1 == 0xf)
2450 gen_op_iwmmxt_movq_M0_wRn(wrd);
2451 switch ((insn >> 16) & 0xf) {
2452 case 0x0: /* TMIA */
2453 gen_movl_T0_reg(s, rd0);
2454 gen_movl_T1_reg(s, rd1);
2455 gen_op_iwmmxt_muladdsl_M0_T0_T1();
2457 case 0x8: /* TMIAPH */
2458 gen_movl_T0_reg(s, rd0);
2459 gen_movl_T1_reg(s, rd1);
2460 gen_op_iwmmxt_muladdsw_M0_T0_T1();
2462 case 0xc: case 0xd: case 0xe: case 0xf: /* TMIAxy */
2463 gen_movl_T1_reg(s, rd0);
2464 if (insn & (1 << 16))
2465 gen_op_shrl_T1_im(16);
2466 gen_op_movl_T0_T1();
2467 gen_movl_T1_reg(s, rd1);
2468 if (insn & (1 << 17))
2469 gen_op_shrl_T1_im(16);
2470 gen_op_iwmmxt_muladdswl_M0_T0_T1();
2475 gen_op_iwmmxt_movq_wRn_M0(wrd);
2476 gen_op_iwmmxt_set_mup();
2485 /* Disassemble an XScale DSP instruction. Returns nonzero if an error occured
2486 (ie. an undefined instruction). */
2487 static int disas_dsp_insn(CPUState *env, DisasContext *s, uint32_t insn)
2489 int acc, rd0, rd1, rdhi, rdlo;
2491 if ((insn & 0x0ff00f10) == 0x0e200010) {
2492 /* Multiply with Internal Accumulate Format */
2493 rd0 = (insn >> 12) & 0xf;
2495 acc = (insn >> 5) & 7;
2500 switch ((insn >> 16) & 0xf) {
2502 gen_movl_T0_reg(s, rd0);
2503 gen_movl_T1_reg(s, rd1);
2504 gen_op_iwmmxt_muladdsl_M0_T0_T1();
2506 case 0x8: /* MIAPH */
2507 gen_movl_T0_reg(s, rd0);
2508 gen_movl_T1_reg(s, rd1);
2509 gen_op_iwmmxt_muladdsw_M0_T0_T1();
2511 case 0xc: /* MIABB */
2512 case 0xd: /* MIABT */
2513 case 0xe: /* MIATB */
2514 case 0xf: /* MIATT */
2515 gen_movl_T1_reg(s, rd0);
2516 if (insn & (1 << 16))
2517 gen_op_shrl_T1_im(16);
2518 gen_op_movl_T0_T1();
2519 gen_movl_T1_reg(s, rd1);
2520 if (insn & (1 << 17))
2521 gen_op_shrl_T1_im(16);
2522 gen_op_iwmmxt_muladdswl_M0_T0_T1();
2528 gen_op_iwmmxt_movq_wRn_M0(acc);
2532 if ((insn & 0x0fe00ff8) == 0x0c400000) {
2533 /* Internal Accumulator Access Format */
2534 rdhi = (insn >> 16) & 0xf;
2535 rdlo = (insn >> 12) & 0xf;
2541 if (insn & ARM_CP_RW_BIT) { /* MRA */
2542 gen_iwmmxt_movl_T0_T1_wRn(acc);
2543 gen_movl_reg_T0(s, rdlo);
2544 gen_op_movl_T0_im((1 << (40 - 32)) - 1);
2545 gen_op_andl_T0_T1();
2546 gen_movl_reg_T0(s, rdhi);
2548 gen_movl_T0_reg(s, rdlo);
2549 gen_movl_T1_reg(s, rdhi);
2550 gen_iwmmxt_movl_wRn_T0_T1(acc);
2558 /* Disassemble system coprocessor instruction. Return nonzero if
2559 instruction is not defined. */
2560 static int disas_cp_insn(CPUState *env, DisasContext *s, uint32_t insn)
2563 uint32_t rd = (insn >> 12) & 0xf;
2564 uint32_t cp = (insn >> 8) & 0xf;
2569 if (insn & ARM_CP_RW_BIT) {
2570 if (!env->cp[cp].cp_read)
2572 gen_set_pc_im(s->pc);
2574 gen_helper_get_cp(tmp, cpu_env, tcg_const_i32(insn));
2575 store_reg(s, rd, tmp);
2577 if (!env->cp[cp].cp_write)
2579 gen_set_pc_im(s->pc);
2580 tmp = load_reg(s, rd);
2581 gen_helper_set_cp(cpu_env, tcg_const_i32(insn), tmp);
2586 static int cp15_user_ok(uint32_t insn)
2588 int cpn = (insn >> 16) & 0xf;
2589 int cpm = insn & 0xf;
2590 int op = ((insn >> 5) & 7) | ((insn >> 18) & 0x38);
2592 if (cpn == 13 && cpm == 0) {
2594 if (op == 2 || (op == 3 && (insn & ARM_CP_RW_BIT)))
2598 /* ISB, DSB, DMB. */
2599 if ((cpm == 5 && op == 4)
2600 || (cpm == 10 && (op == 4 || op == 5)))
2606 /* Disassemble system coprocessor (cp15) instruction. Return nonzero if
2607 instruction is not defined. */
2608 static int disas_cp15_insn(CPUState *env, DisasContext *s, uint32_t insn)
2613 /* M profile cores use memory mapped registers instead of cp15. */
2614 if (arm_feature(env, ARM_FEATURE_M))
2617 if ((insn & (1 << 25)) == 0) {
2618 if (insn & (1 << 20)) {
2622 /* mcrr. Used for block cache operations, so implement as no-op. */
2625 if ((insn & (1 << 4)) == 0) {
2629 if (IS_USER(s) && !cp15_user_ok(insn)) {
2632 if ((insn & 0x0fff0fff) == 0x0e070f90
2633 || (insn & 0x0fff0fff) == 0x0e070f58) {
2634 /* Wait for interrupt. */
2635 gen_set_pc_im(s->pc);
2636 s->is_jmp = DISAS_WFI;
2639 rd = (insn >> 12) & 0xf;
2640 if (insn & ARM_CP_RW_BIT) {
2642 gen_helper_get_cp15(tmp, cpu_env, tcg_const_i32(insn));
2643 /* If the destination register is r15 then sets condition codes. */
2645 store_reg(s, rd, tmp);
2649 tmp = load_reg(s, rd);
2650 gen_helper_set_cp15(cpu_env, tcg_const_i32(insn), tmp);
2652 /* Normally we would always end the TB here, but Linux
2653 * arch/arm/mach-pxa/sleep.S expects two instructions following
2654 * an MMU enable to execute from cache. Imitate this behaviour. */
2655 if (!arm_feature(env, ARM_FEATURE_XSCALE) ||
2656 (insn & 0x0fff0fff) != 0x0e010f10)
2662 #define VFP_REG_SHR(x, n) (((n) > 0) ? (x) >> (n) : (x) << -(n))
2663 #define VFP_SREG(insn, bigbit, smallbit) \
2664 ((VFP_REG_SHR(insn, bigbit - 1) & 0x1e) | (((insn) >> (smallbit)) & 1))
2665 #define VFP_DREG(reg, insn, bigbit, smallbit) do { \
2666 if (arm_feature(env, ARM_FEATURE_VFP3)) { \
2667 reg = (((insn) >> (bigbit)) & 0x0f) \
2668 | (((insn) >> ((smallbit) - 4)) & 0x10); \
2670 if (insn & (1 << (smallbit))) \
2672 reg = ((insn) >> (bigbit)) & 0x0f; \
2675 #define VFP_SREG_D(insn) VFP_SREG(insn, 12, 22)
2676 #define VFP_DREG_D(reg, insn) VFP_DREG(reg, insn, 12, 22)
2677 #define VFP_SREG_N(insn) VFP_SREG(insn, 16, 7)
2678 #define VFP_DREG_N(reg, insn) VFP_DREG(reg, insn, 16, 7)
2679 #define VFP_SREG_M(insn) VFP_SREG(insn, 0, 5)
2680 #define VFP_DREG_M(reg, insn) VFP_DREG(reg, insn, 0, 5)
2682 /* Move between integer and VFP cores. */
2683 static TCGv gen_vfp_mrs(void)
2685 TCGv tmp = new_tmp();
2686 tcg_gen_mov_i32(tmp, cpu_F0s);
2690 static void gen_vfp_msr(TCGv tmp)
2692 tcg_gen_mov_i32(cpu_F0s, tmp);
2697 vfp_enabled(CPUState * env)
2699 return ((env->vfp.xregs[ARM_VFP_FPEXC] & (1 << 30)) != 0);
2702 static void gen_neon_dup_u8(TCGv var, int shift)
2704 TCGv tmp = new_tmp();
2706 tcg_gen_shri_i32(var, var, shift);
2707 tcg_gen_andi_i32(var, var, 0xff);
2708 tcg_gen_shli_i32(tmp, var, 8);
2709 tcg_gen_or_i32(var, var, tmp);
2710 tcg_gen_shli_i32(tmp, var, 16);
2711 tcg_gen_or_i32(var, var, tmp);
2715 static void gen_neon_dup_low16(TCGv var)
2717 TCGv tmp = new_tmp();
2718 tcg_gen_andi_i32(var, var, 0xffff);
2719 tcg_gen_shli_i32(tmp, var, 16);
2720 tcg_gen_or_i32(var, var, tmp);
2724 static void gen_neon_dup_high16(TCGv var)
2726 TCGv tmp = new_tmp();
2727 tcg_gen_andi_i32(var, var, 0xffff0000);
2728 tcg_gen_shri_i32(tmp, var, 16);
2729 tcg_gen_or_i32(var, var, tmp);
2733 /* Disassemble a VFP instruction. Returns nonzero if an error occured
2734 (ie. an undefined instruction). */
2735 static int disas_vfp_insn(CPUState * env, DisasContext *s, uint32_t insn)
2737 uint32_t rd, rn, rm, op, i, n, offset, delta_d, delta_m, bank_mask;
2742 if (!arm_feature(env, ARM_FEATURE_VFP))
2745 if (!vfp_enabled(env)) {
2746 /* VFP disabled. Only allow fmxr/fmrx to/from some control regs. */
2747 if ((insn & 0x0fe00fff) != 0x0ee00a10)
2749 rn = (insn >> 16) & 0xf;
2750 if (rn != ARM_VFP_FPSID && rn != ARM_VFP_FPEXC
2751 && rn != ARM_VFP_MVFR1 && rn != ARM_VFP_MVFR0)
2754 dp = ((insn & 0xf00) == 0xb00);
2755 switch ((insn >> 24) & 0xf) {
2757 if (insn & (1 << 4)) {
2758 /* single register transfer */
2759 rd = (insn >> 12) & 0xf;
2764 VFP_DREG_N(rn, insn);
2767 if (insn & 0x00c00060
2768 && !arm_feature(env, ARM_FEATURE_NEON))
2771 pass = (insn >> 21) & 1;
2772 if (insn & (1 << 22)) {
2774 offset = ((insn >> 5) & 3) * 8;
2775 } else if (insn & (1 << 5)) {
2777 offset = (insn & (1 << 6)) ? 16 : 0;
2782 if (insn & ARM_CP_RW_BIT) {
2784 tmp = neon_load_reg(rn, pass);
2788 tcg_gen_shri_i32(tmp, tmp, offset);
2789 if (insn & (1 << 23))
2795 if (insn & (1 << 23)) {
2797 tcg_gen_shri_i32(tmp, tmp, 16);
2803 tcg_gen_sari_i32(tmp, tmp, 16);
2812 store_reg(s, rd, tmp);
2815 tmp = load_reg(s, rd);
2816 if (insn & (1 << 23)) {
2819 gen_neon_dup_u8(tmp, 0);
2820 } else if (size == 1) {
2821 gen_neon_dup_low16(tmp);
2824 tcg_gen_mov_i32(tmp2, tmp);
2825 neon_store_reg(rn, 0, tmp2);
2826 neon_store_reg(rn, 0, tmp);
2831 tmp2 = neon_load_reg(rn, pass);
2832 gen_bfi(tmp, tmp2, tmp, offset, 0xff);
2836 tmp2 = neon_load_reg(rn, pass);
2837 gen_bfi(tmp, tmp2, tmp, offset, 0xffff);
2843 neon_store_reg(rn, pass, tmp);
2847 if ((insn & 0x6f) != 0x00)
2849 rn = VFP_SREG_N(insn);
2850 if (insn & ARM_CP_RW_BIT) {
2852 if (insn & (1 << 21)) {
2853 /* system register */
2858 /* VFP2 allows access to FSID from userspace.
2859 VFP3 restricts all id registers to privileged
2862 && arm_feature(env, ARM_FEATURE_VFP3))
2864 tmp = load_cpu_field(vfp.xregs[rn]);
2869 tmp = load_cpu_field(vfp.xregs[rn]);
2871 case ARM_VFP_FPINST:
2872 case ARM_VFP_FPINST2:
2873 /* Not present in VFP3. */
2875 || arm_feature(env, ARM_FEATURE_VFP3))
2877 tmp = load_cpu_field(vfp.xregs[rn]);
2881 tmp = load_cpu_field(vfp.xregs[ARM_VFP_FPSCR]);
2882 tcg_gen_andi_i32(tmp, tmp, 0xf0000000);
2885 gen_helper_vfp_get_fpscr(tmp, cpu_env);
2891 || !arm_feature(env, ARM_FEATURE_VFP3))
2893 tmp = load_cpu_field(vfp.xregs[rn]);
2899 gen_mov_F0_vreg(0, rn);
2900 tmp = gen_vfp_mrs();
2903 /* Set the 4 flag bits in the CPSR. */
2907 store_reg(s, rd, tmp);
2911 tmp = load_reg(s, rd);
2912 if (insn & (1 << 21)) {
2914 /* system register */
2919 /* Writes are ignored. */
2922 gen_helper_vfp_set_fpscr(cpu_env, tmp);
2929 store_cpu_field(tmp, vfp.xregs[rn]);
2932 case ARM_VFP_FPINST:
2933 case ARM_VFP_FPINST2:
2934 store_cpu_field(tmp, vfp.xregs[rn]);
2941 gen_mov_vreg_F0(0, rn);
2946 /* data processing */
2947 /* The opcode is in bits 23, 21, 20 and 6. */
2948 op = ((insn >> 20) & 8) | ((insn >> 19) & 6) | ((insn >> 6) & 1);
2952 rn = ((insn >> 15) & 0x1e) | ((insn >> 7) & 1);
2954 /* rn is register number */
2955 VFP_DREG_N(rn, insn);
2958 if (op == 15 && (rn == 15 || rn > 17)) {
2959 /* Integer or single precision destination. */
2960 rd = VFP_SREG_D(insn);
2962 VFP_DREG_D(rd, insn);
2965 if (op == 15 && (rn == 16 || rn == 17)) {
2966 /* Integer source. */
2967 rm = ((insn << 1) & 0x1e) | ((insn >> 5) & 1);
2969 VFP_DREG_M(rm, insn);
2972 rn = VFP_SREG_N(insn);
2973 if (op == 15 && rn == 15) {
2974 /* Double precision destination. */
2975 VFP_DREG_D(rd, insn);
2977 rd = VFP_SREG_D(insn);
2979 rm = VFP_SREG_M(insn);
2982 veclen = env->vfp.vec_len;
2983 if (op == 15 && rn > 3)
2986 /* Shut up compiler warnings. */
2997 /* Figure out what type of vector operation this is. */
2998 if ((rd & bank_mask) == 0) {
3003 delta_d = (env->vfp.vec_stride >> 1) + 1;
3005 delta_d = env->vfp.vec_stride + 1;
3007 if ((rm & bank_mask) == 0) {
3008 /* mixed scalar/vector */
3017 /* Load the initial operands. */
3022 /* Integer source */
3023 gen_mov_F0_vreg(0, rm);
3028 gen_mov_F0_vreg(dp, rd);
3029 gen_mov_F1_vreg(dp, rm);
3033 /* Compare with zero */
3034 gen_mov_F0_vreg(dp, rd);
3041 /* Source and destination the same. */
3042 gen_mov_F0_vreg(dp, rd);
3045 /* One source operand. */
3046 gen_mov_F0_vreg(dp, rm);
3050 /* Two source operands. */
3051 gen_mov_F0_vreg(dp, rn);
3052 gen_mov_F1_vreg(dp, rm);
3056 /* Perform the calculation. */
3058 case 0: /* mac: fd + (fn * fm) */
3060 gen_mov_F1_vreg(dp, rd);
3063 case 1: /* nmac: fd - (fn * fm) */
3066 gen_mov_F1_vreg(dp, rd);
3069 case 2: /* msc: -fd + (fn * fm) */
3071 gen_mov_F1_vreg(dp, rd);
3074 case 3: /* nmsc: -fd - (fn * fm) */
3076 gen_mov_F1_vreg(dp, rd);
3080 case 4: /* mul: fn * fm */
3083 case 5: /* nmul: -(fn * fm) */
3087 case 6: /* add: fn + fm */
3090 case 7: /* sub: fn - fm */
3093 case 8: /* div: fn / fm */
3096 case 14: /* fconst */
3097 if (!arm_feature(env, ARM_FEATURE_VFP3))
3100 n = (insn << 12) & 0x80000000;
3101 i = ((insn >> 12) & 0x70) | (insn & 0xf);
3108 tcg_gen_movi_i64(cpu_F0d, ((uint64_t)n) << 32);
3115 tcg_gen_movi_i32(cpu_F0s, n);
3118 case 15: /* extension space */
3141 case 11: /* cmpez */
3145 case 15: /* single<->double conversion */
3147 gen_helper_vfp_fcvtsd(cpu_F0s, cpu_F0d, cpu_env);
3149 gen_helper_vfp_fcvtds(cpu_F0d, cpu_F0s, cpu_env);
3151 case 16: /* fuito */
3154 case 17: /* fsito */
3157 case 20: /* fshto */
3158 if (!arm_feature(env, ARM_FEATURE_VFP3))
3160 gen_vfp_shto(dp, rm);
3162 case 21: /* fslto */
3163 if (!arm_feature(env, ARM_FEATURE_VFP3))
3165 gen_vfp_slto(dp, rm);
3167 case 22: /* fuhto */
3168 if (!arm_feature(env, ARM_FEATURE_VFP3))
3170 gen_vfp_uhto(dp, rm);
3172 case 23: /* fulto */
3173 if (!arm_feature(env, ARM_FEATURE_VFP3))
3175 gen_vfp_ulto(dp, rm);
3177 case 24: /* ftoui */
3180 case 25: /* ftouiz */
3183 case 26: /* ftosi */
3186 case 27: /* ftosiz */
3189 case 28: /* ftosh */
3190 if (!arm_feature(env, ARM_FEATURE_VFP3))
3192 gen_vfp_tosh(dp, rm);
3194 case 29: /* ftosl */
3195 if (!arm_feature(env, ARM_FEATURE_VFP3))
3197 gen_vfp_tosl(dp, rm);
3199 case 30: /* ftouh */
3200 if (!arm_feature(env, ARM_FEATURE_VFP3))
3202 gen_vfp_touh(dp, rm);
3204 case 31: /* ftoul */
3205 if (!arm_feature(env, ARM_FEATURE_VFP3))
3207 gen_vfp_toul(dp, rm);
3209 default: /* undefined */
3210 printf ("rn:%d\n", rn);
3214 default: /* undefined */
3215 printf ("op:%d\n", op);
3219 /* Write back the result. */
3220 if (op == 15 && (rn >= 8 && rn <= 11))
3221 ; /* Comparison, do nothing. */
3222 else if (op == 15 && rn > 17)
3223 /* Integer result. */
3224 gen_mov_vreg_F0(0, rd);
3225 else if (op == 15 && rn == 15)
3227 gen_mov_vreg_F0(!dp, rd);
3229 gen_mov_vreg_F0(dp, rd);
3231 /* break out of the loop if we have finished */
3235 if (op == 15 && delta_m == 0) {
3236 /* single source one-many */
3238 rd = ((rd + delta_d) & (bank_mask - 1))
3240 gen_mov_vreg_F0(dp, rd);
3244 /* Setup the next operands. */
3246 rd = ((rd + delta_d) & (bank_mask - 1))
3250 /* One source operand. */
3251 rm = ((rm + delta_m) & (bank_mask - 1))
3253 gen_mov_F0_vreg(dp, rm);
3255 /* Two source operands. */
3256 rn = ((rn + delta_d) & (bank_mask - 1))
3258 gen_mov_F0_vreg(dp, rn);
3260 rm = ((rm + delta_m) & (bank_mask - 1))
3262 gen_mov_F1_vreg(dp, rm);
3270 if (dp && (insn & 0x03e00000) == 0x00400000) {
3271 /* two-register transfer */
3272 rn = (insn >> 16) & 0xf;
3273 rd = (insn >> 12) & 0xf;
3275 VFP_DREG_M(rm, insn);
3277 rm = VFP_SREG_M(insn);
3280 if (insn & ARM_CP_RW_BIT) {
3283 gen_mov_F0_vreg(0, rm * 2);
3284 tmp = gen_vfp_mrs();
3285 store_reg(s, rd, tmp);
3286 gen_mov_F0_vreg(0, rm * 2 + 1);
3287 tmp = gen_vfp_mrs();
3288 store_reg(s, rn, tmp);
3290 gen_mov_F0_vreg(0, rm);
3291 tmp = gen_vfp_mrs();
3292 store_reg(s, rn, tmp);
3293 gen_mov_F0_vreg(0, rm + 1);
3294 tmp = gen_vfp_mrs();
3295 store_reg(s, rd, tmp);
3300 tmp = load_reg(s, rd);
3302 gen_mov_vreg_F0(0, rm * 2);
3303 tmp = load_reg(s, rn);
3305 gen_mov_vreg_F0(0, rm * 2 + 1);
3307 tmp = load_reg(s, rn);
3309 gen_mov_vreg_F0(0, rm);
3310 tmp = load_reg(s, rd);
3312 gen_mov_vreg_F0(0, rm + 1);
3317 rn = (insn >> 16) & 0xf;
3319 VFP_DREG_D(rd, insn);
3321 rd = VFP_SREG_D(insn);
3322 if (s->thumb && rn == 15) {
3323 gen_op_movl_T1_im(s->pc & ~2);
3325 gen_movl_T1_reg(s, rn);
3327 if ((insn & 0x01200000) == 0x01000000) {
3328 /* Single load/store */
3329 offset = (insn & 0xff) << 2;
3330 if ((insn & (1 << 23)) == 0)
3332 gen_op_addl_T1_im(offset);
3333 if (insn & (1 << 20)) {
3335 gen_mov_vreg_F0(dp, rd);
3337 gen_mov_F0_vreg(dp, rd);
3341 /* load/store multiple */
3343 n = (insn >> 1) & 0x7f;
3347 if (insn & (1 << 24)) /* pre-decrement */
3348 gen_op_addl_T1_im(-((insn & 0xff) << 2));
3354 for (i = 0; i < n; i++) {
3355 if (insn & ARM_CP_RW_BIT) {
3358 gen_mov_vreg_F0(dp, rd + i);
3361 gen_mov_F0_vreg(dp, rd + i);
3364 gen_op_addl_T1_im(offset);
3366 if (insn & (1 << 21)) {
3368 if (insn & (1 << 24))
3369 offset = -offset * n;
3370 else if (dp && (insn & 1))
3376 gen_op_addl_T1_im(offset);
3377 gen_movl_reg_T1(s, rn);
3383 /* Should never happen. */
3389 static inline void gen_goto_tb(DisasContext *s, int n, uint32_t dest)
3391 TranslationBlock *tb;
3394 if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK)) {
3396 gen_set_pc_im(dest);
3397 tcg_gen_exit_tb((long)tb + n);
3399 gen_set_pc_im(dest);
3404 static inline void gen_jmp (DisasContext *s, uint32_t dest)
3406 if (__builtin_expect(s->singlestep_enabled, 0)) {
3407 /* An indirect jump so that we still trigger the debug exception. */
3412 gen_goto_tb(s, 0, dest);
3413 s->is_jmp = DISAS_TB_JUMP;
3417 static inline void gen_mulxy(TCGv t0, TCGv t1, int x, int y)
3420 tcg_gen_sari_i32(t0, t0, 16);
3424 tcg_gen_sari_i32(t1, t1, 16);
3427 tcg_gen_mul_i32(t0, t0, t1);
3430 /* Return the mask of PSR bits set by a MSR instruction. */
3431 static uint32_t msr_mask(CPUState *env, DisasContext *s, int flags, int spsr) {
3435 if (flags & (1 << 0))
3437 if (flags & (1 << 1))
3439 if (flags & (1 << 2))
3441 if (flags & (1 << 3))
3444 /* Mask out undefined bits. */
3445 mask &= ~CPSR_RESERVED;
3446 if (!arm_feature(env, ARM_FEATURE_V6))
3447 mask &= ~(CPSR_E | CPSR_GE);
3448 if (!arm_feature(env, ARM_FEATURE_THUMB2))
3450 /* Mask out execution state bits. */
3453 /* Mask out privileged bits. */
3459 /* Returns nonzero if access to the PSR is not permitted. */
3460 static int gen_set_psr_T0(DisasContext *s, uint32_t mask, int spsr)
3464 /* ??? This is also undefined in system mode. */
3468 tmp = load_cpu_field(spsr);
3469 tcg_gen_andi_i32(tmp, tmp, ~mask);
3470 tcg_gen_andi_i32(cpu_T[0], cpu_T[0], mask);
3471 tcg_gen_or_i32(tmp, tmp, cpu_T[0]);
3472 store_cpu_field(tmp, spsr);
3474 gen_set_cpsr(cpu_T[0], mask);
3480 /* Generate an old-style exception return. */
3481 static void gen_exception_return(DisasContext *s)
3484 gen_movl_reg_T0(s, 15);
3485 tmp = load_cpu_field(spsr);
3486 gen_set_cpsr(tmp, 0xffffffff);
3488 s->is_jmp = DISAS_UPDATE;
3491 /* Generate a v6 exception return. Marks both values as dead. */
3492 static void gen_rfe(DisasContext *s, TCGv pc, TCGv cpsr)
3494 gen_set_cpsr(cpsr, 0xffffffff);
3496 store_reg(s, 15, pc);
3497 s->is_jmp = DISAS_UPDATE;
3501 gen_set_condexec (DisasContext *s)
3503 if (s->condexec_mask) {
3504 uint32_t val = (s->condexec_cond << 4) | (s->condexec_mask >> 1);
3505 TCGv tmp = new_tmp();
3506 tcg_gen_movi_i32(tmp, val);
3507 store_cpu_field(tmp, condexec_bits);
3511 static void gen_nop_hint(DisasContext *s, int val)
3515 gen_set_pc_im(s->pc);
3516 s->is_jmp = DISAS_WFI;
3520 /* TODO: Implement SEV and WFE. May help SMP performance. */
3526 /* These macros help make the code more readable when migrating from the
3527 old dyngen helpers. They should probably be removed when
3528 T0/T1 are removed. */
3529 #define CPU_T001 cpu_T[0], cpu_T[0], cpu_T[1]
3530 #define CPU_T0E01 cpu_T[0], cpu_env, cpu_T[0], cpu_T[1]
3532 #define CPU_V001 cpu_V0, cpu_V0, cpu_V1
3534 static inline int gen_neon_add(int size)
3537 case 0: gen_helper_neon_add_u8(CPU_T001); break;
3538 case 1: gen_helper_neon_add_u16(CPU_T001); break;
3539 case 2: gen_op_addl_T0_T1(); break;
3545 static inline void gen_neon_rsb(int size)
3548 case 0: gen_helper_neon_sub_u8(cpu_T[0], cpu_T[1], cpu_T[0]); break;
3549 case 1: gen_helper_neon_sub_u16(cpu_T[0], cpu_T[1], cpu_T[0]); break;
3550 case 2: gen_op_rsbl_T0_T1(); break;
3555 /* 32-bit pairwise ops end up the same as the elementwise versions. */
3556 #define gen_helper_neon_pmax_s32 gen_helper_neon_max_s32
3557 #define gen_helper_neon_pmax_u32 gen_helper_neon_max_u32
3558 #define gen_helper_neon_pmin_s32 gen_helper_neon_min_s32
3559 #define gen_helper_neon_pmin_u32 gen_helper_neon_min_u32
3561 /* FIXME: This is wrong. They set the wrong overflow bit. */
3562 #define gen_helper_neon_qadd_s32(a, e, b, c) gen_helper_add_saturate(a, b, c)
3563 #define gen_helper_neon_qadd_u32(a, e, b, c) gen_helper_add_usaturate(a, b, c)
3564 #define gen_helper_neon_qsub_s32(a, e, b, c) gen_helper_sub_saturate(a, b, c)
3565 #define gen_helper_neon_qsub_u32(a, e, b, c) gen_helper_sub_usaturate(a, b, c)
3567 #define GEN_NEON_INTEGER_OP_ENV(name) do { \
3568 switch ((size << 1) | u) { \
3570 gen_helper_neon_##name##_s8(cpu_T[0], cpu_env, cpu_T[0], cpu_T[1]); \
3573 gen_helper_neon_##name##_u8(cpu_T[0], cpu_env, cpu_T[0], cpu_T[1]); \
3576 gen_helper_neon_##name##_s16(cpu_T[0], cpu_env, cpu_T[0], cpu_T[1]); \
3579 gen_helper_neon_##name##_u16(cpu_T[0], cpu_env, cpu_T[0], cpu_T[1]); \
3582 gen_helper_neon_##name##_s32(cpu_T[0], cpu_env, cpu_T[0], cpu_T[1]); \
3585 gen_helper_neon_##name##_u32(cpu_T[0], cpu_env, cpu_T[0], cpu_T[1]); \
3587 default: return 1; \
3590 #define GEN_NEON_INTEGER_OP(name) do { \
3591 switch ((size << 1) | u) { \
3593 gen_helper_neon_##name##_s8(cpu_T[0], cpu_T[0], cpu_T[1]); \
3596 gen_helper_neon_##name##_u8(cpu_T[0], cpu_T[0], cpu_T[1]); \
3599 gen_helper_neon_##name##_s16(cpu_T[0], cpu_T[0], cpu_T[1]); \
3602 gen_helper_neon_##name##_u16(cpu_T[0], cpu_T[0], cpu_T[1]); \
3605 gen_helper_neon_##name##_s32(cpu_T[0], cpu_T[0], cpu_T[1]); \
3608 gen_helper_neon_##name##_u32(cpu_T[0], cpu_T[0], cpu_T[1]); \
3610 default: return 1; \
3614 gen_neon_movl_scratch_T0(int scratch)
3618 offset = offsetof(CPUARMState, vfp.scratch[scratch]);
3619 tcg_gen_st_i32(cpu_T[0], cpu_env, offset);
3623 gen_neon_movl_scratch_T1(int scratch)
3627 offset = offsetof(CPUARMState, vfp.scratch[scratch]);
3628 tcg_gen_st_i32(cpu_T[1], cpu_env, offset);
3632 gen_neon_movl_T0_scratch(int scratch)
3636 offset = offsetof(CPUARMState, vfp.scratch[scratch]);
3637 tcg_gen_ld_i32(cpu_T[0], cpu_env, offset);
3641 gen_neon_movl_T1_scratch(int scratch)
3645 offset = offsetof(CPUARMState, vfp.scratch[scratch]);
3646 tcg_gen_ld_i32(cpu_T[1], cpu_env, offset);
3649 static inline void gen_neon_get_scalar(int size, int reg)
3652 NEON_GET_REG(T0, reg >> 1, reg & 1);
3654 NEON_GET_REG(T0, reg >> 2, (reg >> 1) & 1);
3656 gen_neon_dup_low16(cpu_T[0]);
3658 gen_neon_dup_high16(cpu_T[0]);
3662 static void gen_neon_unzip(int reg, int q, int tmp, int size)
3666 for (n = 0; n < q + 1; n += 2) {
3667 NEON_GET_REG(T0, reg, n);
3668 NEON_GET_REG(T0, reg, n + n);
3670 case 0: gen_helper_neon_unzip_u8(); break;
3671 case 1: gen_helper_neon_zip_u16(); break; /* zip and unzip are the same. */
3672 case 2: /* no-op */; break;
3675 gen_neon_movl_scratch_T0(tmp + n);
3676 gen_neon_movl_scratch_T1(tmp + n + 1);
3684 } neon_ls_element_type[11] = {
3698 /* Translate a NEON load/store element instruction. Return nonzero if the
3699 instruction is invalid. */
3700 static int disas_neon_ls_insn(CPUState * env, DisasContext *s, uint32_t insn)
3716 if (!vfp_enabled(env))
3718 VFP_DREG_D(rd, insn);
3719 rn = (insn >> 16) & 0xf;
3721 load = (insn & (1 << 21)) != 0;
3722 if ((insn & (1 << 23)) == 0) {
3723 /* Load store all elements. */
3724 op = (insn >> 8) & 0xf;
3725 size = (insn >> 6) & 3;
3726 if (op > 10 || size == 3)
3728 nregs = neon_ls_element_type[op].nregs;
3729 interleave = neon_ls_element_type[op].interleave;
3730 gen_movl_T1_reg(s, rn);
3731 stride = (1 << size) * interleave;
3732 for (reg = 0; reg < nregs; reg++) {
3733 if (interleave > 2 || (interleave == 2 && nregs == 2)) {
3734 gen_movl_T1_reg(s, rn);
3735 gen_op_addl_T1_im((1 << size) * reg);
3736 } else if (interleave == 2 && nregs == 4 && reg == 2) {
3737 gen_movl_T1_reg(s, rn);
3738 gen_op_addl_T1_im(1 << size);
3740 for (pass = 0; pass < 2; pass++) {
3743 tmp = gen_ld32(cpu_T[1], IS_USER(s));
3744 neon_store_reg(rd, pass, tmp);
3746 tmp = neon_load_reg(rd, pass);
3747 gen_st32(tmp, cpu_T[1], IS_USER(s));
3749 gen_op_addl_T1_im(stride);
3750 } else if (size == 1) {
3752 tmp = gen_ld16u(cpu_T[1], IS_USER(s));
3753 gen_op_addl_T1_im(stride);
3754 tmp2 = gen_ld16u(cpu_T[1], IS_USER(s));
3755 gen_op_addl_T1_im(stride);
3756 gen_bfi(tmp, tmp, tmp2, 16, 0xffff);
3758 neon_store_reg(rd, pass, tmp);
3760 tmp = neon_load_reg(rd, pass);
3762 tcg_gen_shri_i32(tmp2, tmp, 16);
3763 gen_st16(tmp, cpu_T[1], IS_USER(s));
3764 gen_op_addl_T1_im(stride);
3765 gen_st16(tmp2, cpu_T[1], IS_USER(s));
3766 gen_op_addl_T1_im(stride);
3768 } else /* size == 0 */ {
3770 for (n = 0; n < 4; n++) {
3771 tmp = gen_ld8u(cpu_T[1], IS_USER(s));
3772 gen_op_addl_T1_im(stride);
3776 gen_bfi(tmp2, tmp2, tmp, n * 8, 0xff);
3780 neon_store_reg(rd, pass, tmp2);
3782 tmp2 = neon_load_reg(rd, pass);
3783 for (n = 0; n < 4; n++) {
3786 tcg_gen_mov_i32(tmp, tmp2);
3788 tcg_gen_shri_i32(tmp, tmp2, n * 8);
3790 gen_st8(tmp, cpu_T[1], IS_USER(s));
3791 gen_op_addl_T1_im(stride);
3797 rd += neon_ls_element_type[op].spacing;
3801 size = (insn >> 10) & 3;
3803 /* Load single element to all lanes. */
3806 size = (insn >> 6) & 3;
3807 nregs = ((insn >> 8) & 3) + 1;
3808 stride = (insn & (1 << 5)) ? 2 : 1;
3809 gen_movl_T1_reg(s, rn);
3810 for (reg = 0; reg < nregs; reg++) {
3813 tmp = gen_ld8u(cpu_T[1], IS_USER(s));
3814 gen_neon_dup_u8(tmp, 0);
3817 tmp = gen_ld16u(cpu_T[1], IS_USER(s));
3818 gen_neon_dup_low16(tmp);
3821 tmp = gen_ld32(cpu_T[0], IS_USER(s));
3826 gen_op_addl_T1_im(1 << size);
3828 tcg_gen_mov_i32(tmp2, tmp);
3829 neon_store_reg(rd, 0, tmp2);
3830 neon_store_reg(rd, 0, tmp);
3833 stride = (1 << size) * nregs;
3835 /* Single element. */
3836 pass = (insn >> 7) & 1;
3839 shift = ((insn >> 5) & 3) * 8;
3843 shift = ((insn >> 6) & 1) * 16;
3844 stride = (insn & (1 << 5)) ? 2 : 1;
3848 stride = (insn & (1 << 6)) ? 2 : 1;
3853 nregs = ((insn >> 8) & 3) + 1;
3854 gen_movl_T1_reg(s, rn);
3855 for (reg = 0; reg < nregs; reg++) {
3859 tmp = gen_ld8u(cpu_T[1], IS_USER(s));
3862 tmp = gen_ld16u(cpu_T[1], IS_USER(s));
3865 tmp = gen_ld32(cpu_T[1], IS_USER(s));
3869 tmp2 = neon_load_reg(rd, pass);
3870 gen_bfi(tmp, tmp2, tmp, shift, size ? 0xffff : 0xff);
3873 neon_store_reg(rd, pass, tmp);
3874 } else { /* Store */
3875 tmp = neon_load_reg(rd, pass);
3877 tcg_gen_shri_i32(tmp, tmp, shift);
3880 gen_st8(tmp, cpu_T[1], IS_USER(s));
3883 gen_st16(tmp, cpu_T[1], IS_USER(s));
3886 gen_st32(tmp, cpu_T[1], IS_USER(s));
3891 gen_op_addl_T1_im(1 << size);
3893 stride = nregs * (1 << size);
3899 base = load_reg(s, rn);
3901 tcg_gen_addi_i32(base, base, stride);
3904 index = load_reg(s, rm);
3905 tcg_gen_add_i32(base, base, index);
3908 store_reg(s, rn, base);
3913 /* Bitwise select. dest = c ? t : f. Clobbers T and F. */
3914 static void gen_neon_bsl(TCGv dest, TCGv t, TCGv f, TCGv c)
3916 tcg_gen_and_i32(t, t, c);
3917 tcg_gen_bic_i32(f, f, c);
3918 tcg_gen_or_i32(dest, t, f);
3921 static inline void gen_neon_narrow(int size, TCGv dest, TCGv src)
3924 case 0: gen_helper_neon_narrow_u8(dest, src); break;
3925 case 1: gen_helper_neon_narrow_u16(dest, src); break;
3926 case 2: tcg_gen_trunc_i64_i32(dest, src); break;
3931 static inline void gen_neon_narrow_sats(int size, TCGv dest, TCGv src)
3934 case 0: gen_helper_neon_narrow_sat_s8(dest, cpu_env, src); break;
3935 case 1: gen_helper_neon_narrow_sat_s16(dest, cpu_env, src); break;
3936 case 2: gen_helper_neon_narrow_sat_s32(dest, cpu_env, src); break;
3941 static inline void gen_neon_narrow_satu(int size, TCGv dest, TCGv src)
3944 case 0: gen_helper_neon_narrow_sat_u8(dest, cpu_env, src); break;
3945 case 1: gen_helper_neon_narrow_sat_u16(dest, cpu_env, src); break;
3946 case 2: gen_helper_neon_narrow_sat_u32(dest, cpu_env, src); break;
3951 static inline void gen_neon_shift_narrow(int size, TCGv var, TCGv shift,
3957 case 1: gen_helper_neon_rshl_u16(var, var, shift); break;
3958 case 2: gen_helper_neon_rshl_u32(var, var, shift); break;
3963 case 1: gen_helper_neon_rshl_s16(var, var, shift); break;
3964 case 2: gen_helper_neon_rshl_s32(var, var, shift); break;
3971 case 1: gen_helper_neon_rshl_u16(var, var, shift); break;
3972 case 2: gen_helper_neon_rshl_u32(var, var, shift); break;
3977 case 1: gen_helper_neon_shl_s16(var, var, shift); break;
3978 case 2: gen_helper_neon_shl_s32(var, var, shift); break;
3985 static inline void gen_neon_widen(TCGv dest, TCGv src, int size, int u)
3989 case 0: gen_helper_neon_widen_u8(dest, src); break;
3990 case 1: gen_helper_neon_widen_u16(dest, src); break;
3991 case 2: tcg_gen_extu_i32_i64(dest, src); break;
3996 case 0: gen_helper_neon_widen_s8(dest, src); break;
3997 case 1: gen_helper_neon_widen_s16(dest, src); break;
3998 case 2: tcg_gen_ext_i32_i64(dest, src); break;
4005 static inline void gen_neon_addl(int size)
4008 case 0: gen_helper_neon_addl_u16(CPU_V001); break;
4009 case 1: gen_helper_neon_addl_u32(CPU_V001); break;
4010 case 2: tcg_gen_add_i64(CPU_V001); break;
4015 static inline void gen_neon_subl(int size)
4018 case 0: gen_helper_neon_subl_u16(CPU_V001); break;
4019 case 1: gen_helper_neon_subl_u32(CPU_V001); break;
4020 case 2: tcg_gen_sub_i64(CPU_V001); break;
4025 static inline void gen_neon_negl(TCGv var, int size)
4028 case 0: gen_helper_neon_negl_u16(var, var); break;
4029 case 1: gen_helper_neon_negl_u32(var, var); break;
4030 case 2: gen_helper_neon_negl_u64(var, var); break;
4035 static inline void gen_neon_addl_saturate(TCGv op0, TCGv op1, int size)
4038 case 1: gen_helper_neon_addl_saturate_s32(op0, cpu_env, op0, op1); break;
4039 case 2: gen_helper_neon_addl_saturate_s64(op0, cpu_env, op0, op1); break;
4044 static inline void gen_neon_mull(TCGv dest, TCGv a, TCGv b, int size, int u)
4048 switch ((size << 1) | u) {
4049 case 0: gen_helper_neon_mull_s8(dest, a, b); break;
4050 case 1: gen_helper_neon_mull_u8(dest, a, b); break;
4051 case 2: gen_helper_neon_mull_s16(dest, a, b); break;
4052 case 3: gen_helper_neon_mull_u16(dest, a, b); break;
4054 tmp = gen_muls_i64_i32(a, b);
4055 tcg_gen_mov_i64(dest, tmp);
4058 tmp = gen_mulu_i64_i32(a, b);
4059 tcg_gen_mov_i64(dest, tmp);
4069 /* Translate a NEON data processing instruction. Return nonzero if the
4070 instruction is invalid.
4071 We process data in a mixture of 32-bit and 64-bit chunks.
4072 Mostly we use 32-bit chunks so we can use normal scalar instructions. */
4074 static int disas_neon_data_insn(CPUState * env, DisasContext *s, uint32_t insn)
4091 if (!vfp_enabled(env))
4093 q = (insn & (1 << 6)) != 0;
4094 u = (insn >> 24) & 1;
4095 VFP_DREG_D(rd, insn);
4096 VFP_DREG_N(rn, insn);
4097 VFP_DREG_M(rm, insn);
4098 size = (insn >> 20) & 3;
4099 if ((insn & (1 << 23)) == 0) {
4100 /* Three register same length. */
4101 op = ((insn >> 7) & 0x1e) | ((insn >> 4) & 1);
4102 if (size == 3 && (op == 1 || op == 5 || op == 8 || op == 9
4103 || op == 10 || op == 11 || op == 16)) {
4104 /* 64-bit element instructions. */
4105 for (pass = 0; pass < (q ? 2 : 1); pass++) {
4106 neon_load_reg64(cpu_V0, rn + pass);
4107 neon_load_reg64(cpu_V1, rm + pass);
4111 gen_helper_neon_add_saturate_u64(CPU_V001);
4113 gen_helper_neon_add_saturate_s64(CPU_V001);
4118 gen_helper_neon_sub_saturate_u64(CPU_V001);
4120 gen_helper_neon_sub_saturate_s64(CPU_V001);
4125 gen_helper_neon_shl_u64(cpu_V0, cpu_V1, cpu_V0);
4127 gen_helper_neon_shl_s64(cpu_V0, cpu_V1, cpu_V0);
4132 gen_helper_neon_qshl_u64(cpu_V0, cpu_env,
4135 gen_helper_neon_qshl_s64(cpu_V1, cpu_env,
4139 case 10: /* VRSHL */
4141 gen_helper_neon_rshl_u64(cpu_V0, cpu_V1, cpu_V0);
4143 gen_helper_neon_rshl_s64(cpu_V0, cpu_V1, cpu_V0);
4146 case 11: /* VQRSHL */
4148 gen_helper_neon_qrshl_u64(cpu_V0, cpu_env,
4151 gen_helper_neon_qrshl_s64(cpu_V0, cpu_env,
4157 tcg_gen_sub_i64(CPU_V001);
4159 tcg_gen_add_i64(CPU_V001);
4165 neon_store_reg64(cpu_V0, rd + pass);
4172 case 10: /* VRSHL */
4173 case 11: /* VQRSHL */
4176 /* Shift instruction operands are reversed. */
4183 case 20: /* VPMAX */
4184 case 21: /* VPMIN */
4185 case 23: /* VPADD */
4188 case 26: /* VPADD (float) */
4189 pairwise = (u && size < 2);
4191 case 30: /* VPMIN/VPMAX (float) */
4198 for (pass = 0; pass < (q ? 4 : 2); pass++) {
4207 NEON_GET_REG(T0, rn, n);
4208 NEON_GET_REG(T1, rn, n + 1);
4210 NEON_GET_REG(T0, rm, n);
4211 NEON_GET_REG(T1, rm, n + 1);
4215 NEON_GET_REG(T0, rn, pass);
4216 NEON_GET_REG(T1, rm, pass);
4220 GEN_NEON_INTEGER_OP(hadd);
4223 GEN_NEON_INTEGER_OP_ENV(qadd);
4225 case 2: /* VRHADD */
4226 GEN_NEON_INTEGER_OP(rhadd);
4228 case 3: /* Logic ops. */
4229 switch ((u << 2) | size) {
4231 gen_op_andl_T0_T1();
4234 gen_op_bicl_T0_T1();
4244 gen_op_xorl_T0_T1();
4247 tmp = neon_load_reg(rd, pass);
4248 gen_neon_bsl(cpu_T[0], cpu_T[0], cpu_T[1], tmp);
4252 tmp = neon_load_reg(rd, pass);
4253 gen_neon_bsl(cpu_T[0], cpu_T[0], tmp, cpu_T[1]);
4257 tmp = neon_load_reg(rd, pass);
4258 gen_neon_bsl(cpu_T[0], tmp, cpu_T[0], cpu_T[1]);
4264 GEN_NEON_INTEGER_OP(hsub);
4267 GEN_NEON_INTEGER_OP_ENV(qsub);
4270 GEN_NEON_INTEGER_OP(cgt);
4273 GEN_NEON_INTEGER_OP(cge);
4276 GEN_NEON_INTEGER_OP(shl);
4279 GEN_NEON_INTEGER_OP_ENV(qshl);
4281 case 10: /* VRSHL */
4282 GEN_NEON_INTEGER_OP(rshl);
4284 case 11: /* VQRSHL */
4285 GEN_NEON_INTEGER_OP_ENV(qrshl);
4288 GEN_NEON_INTEGER_OP(max);
4291 GEN_NEON_INTEGER_OP(min);
4294 GEN_NEON_INTEGER_OP(abd);
4297 GEN_NEON_INTEGER_OP(abd);
4298 NEON_GET_REG(T1, rd, pass);
4302 if (!u) { /* VADD */
4303 if (gen_neon_add(size))
4307 case 0: gen_helper_neon_sub_u8(CPU_T001); break;
4308 case 1: gen_helper_neon_sub_u16(CPU_T001); break;
4309 case 2: gen_op_subl_T0_T1(); break;
4315 if (!u) { /* VTST */
4317 case 0: gen_helper_neon_tst_u8(CPU_T001); break;
4318 case 1: gen_helper_neon_tst_u16(CPU_T001); break;
4319 case 2: gen_helper_neon_tst_u32(CPU_T001); break;
4324 case 0: gen_helper_neon_ceq_u8(CPU_T001); break;
4325 case 1: gen_helper_neon_ceq_u16(CPU_T001); break;
4326 case 2: gen_helper_neon_ceq_u32(CPU_T001); break;
4331 case 18: /* Multiply. */
4333 case 0: gen_helper_neon_mul_u8(CPU_T001); break;
4334 case 1: gen_helper_neon_mul_u16(CPU_T001); break;
4335 case 2: gen_op_mul_T0_T1(); break;
4338 NEON_GET_REG(T1, rd, pass);
4346 if (u) { /* polynomial */
4347 gen_helper_neon_mul_p8(CPU_T001);
4348 } else { /* Integer */
4350 case 0: gen_helper_neon_mul_u8(CPU_T001); break;
4351 case 1: gen_helper_neon_mul_u16(CPU_T001); break;
4352 case 2: gen_op_mul_T0_T1(); break;
4357 case 20: /* VPMAX */
4358 GEN_NEON_INTEGER_OP(pmax);
4360 case 21: /* VPMIN */
4361 GEN_NEON_INTEGER_OP(pmin);
4363 case 22: /* Hultiply high. */
4364 if (!u) { /* VQDMULH */
4366 case 1: gen_helper_neon_qdmulh_s16(CPU_T0E01); break;
4367 case 2: gen_helper_neon_qdmulh_s32(CPU_T0E01); break;
4370 } else { /* VQRDHMUL */
4372 case 1: gen_helper_neon_qrdmulh_s16(CPU_T0E01); break;
4373 case 2: gen_helper_neon_qrdmulh_s32(CPU_T0E01); break;
4378 case 23: /* VPADD */
4382 case 0: gen_helper_neon_padd_u8(CPU_T001); break;
4383 case 1: gen_helper_neon_padd_u16(CPU_T001); break;
4384 case 2: gen_op_addl_T0_T1(); break;
4388 case 26: /* Floating point arithnetic. */
4389 switch ((u << 2) | size) {
4391 gen_helper_neon_add_f32(CPU_T001);
4394 gen_helper_neon_sub_f32(CPU_T001);
4397 gen_helper_neon_add_f32(CPU_T001);
4400 gen_helper_neon_abd_f32(CPU_T001);
4406 case 27: /* Float multiply. */
4407 gen_helper_neon_mul_f32(CPU_T001);
4409 NEON_GET_REG(T1, rd, pass);
4411 gen_helper_neon_add_f32(CPU_T001);
4413 gen_helper_neon_sub_f32(cpu_T[0], cpu_T[1], cpu_T[0]);
4417 case 28: /* Float compare. */
4419 gen_helper_neon_ceq_f32(CPU_T001);
4422 gen_helper_neon_cge_f32(CPU_T001);
4424 gen_helper_neon_cgt_f32(CPU_T001);
4427 case 29: /* Float compare absolute. */
4431 gen_helper_neon_acge_f32(CPU_T001);
4433 gen_helper_neon_acgt_f32(CPU_T001);
4435 case 30: /* Float min/max. */
4437 gen_helper_neon_max_f32(CPU_T001);
4439 gen_helper_neon_min_f32(CPU_T001);
4443 gen_helper_recps_f32(cpu_T[0], cpu_T[0], cpu_T[1], cpu_env);
4445 gen_helper_rsqrts_f32(cpu_T[0], cpu_T[0], cpu_T[1], cpu_env);
4450 /* Save the result. For elementwise operations we can put it
4451 straight into the destination register. For pairwise operations
4452 we have to be careful to avoid clobbering the source operands. */
4453 if (pairwise && rd == rm) {
4454 gen_neon_movl_scratch_T0(pass);
4456 NEON_SET_REG(T0, rd, pass);
4460 if (pairwise && rd == rm) {
4461 for (pass = 0; pass < (q ? 4 : 2); pass++) {
4462 gen_neon_movl_T0_scratch(pass);
4463 NEON_SET_REG(T0, rd, pass);
4466 /* End of 3 register same size operations. */
4467 } else if (insn & (1 << 4)) {
4468 if ((insn & 0x00380080) != 0) {
4469 /* Two registers and shift. */
4470 op = (insn >> 8) & 0xf;
4471 if (insn & (1 << 7)) {
4476 while ((insn & (1 << (size + 19))) == 0)
4479 shift = (insn >> 16) & ((1 << (3 + size)) - 1);
4480 /* To avoid excessive dumplication of ops we implement shift
4481 by immediate using the variable shift operations. */
4483 /* Shift by immediate:
4484 VSHR, VSRA, VRSHR, VRSRA, VSRI, VSHL, VQSHL, VQSHLU. */
4485 /* Right shifts are encoded as N - shift, where N is the
4486 element size in bits. */
4488 shift = shift - (1 << (size + 3));
4496 imm = (uint8_t) shift;
4501 imm = (uint16_t) shift;
4512 for (pass = 0; pass < count; pass++) {
4514 neon_load_reg64(cpu_V0, rm + pass);
4515 tcg_gen_movi_i64(cpu_V1, imm);
4520 gen_helper_neon_shl_u64(cpu_V0, cpu_V0, cpu_V1);
4522 gen_helper_neon_shl_s64(cpu_V0, cpu_V0, cpu_V1);
4527 gen_helper_neon_rshl_u64(cpu_V0, cpu_V0, cpu_V1);
4529 gen_helper_neon_rshl_s64(cpu_V0, cpu_V0, cpu_V1);
4534 gen_helper_neon_shl_u64(cpu_V0, cpu_V0, cpu_V1);
4536 case 5: /* VSHL, VSLI */
4537 gen_helper_neon_shl_u64(cpu_V0, cpu_V0, cpu_V1);
4541 gen_helper_neon_qshl_u64(cpu_V0, cpu_env, cpu_V0, cpu_V1);
4543 gen_helper_neon_qshl_s64(cpu_V0, cpu_env, cpu_V0, cpu_V1);
4545 case 7: /* VQSHLU */
4546 gen_helper_neon_qshl_u64(cpu_V0, cpu_env, cpu_V0, cpu_V1);
4549 if (op == 1 || op == 3) {
4551 neon_load_reg64(cpu_V0, rd + pass);
4552 tcg_gen_add_i64(cpu_V0, cpu_V0, cpu_V1);
4553 } else if (op == 4 || (op == 5 && u)) {
4555 cpu_abort(env, "VS[LR]I.64 not implemented");
4557 neon_store_reg64(cpu_V0, rd + pass);
4558 } else { /* size < 3 */
4559 /* Operands in T0 and T1. */
4560 gen_op_movl_T1_im(imm);
4561 NEON_GET_REG(T0, rm, pass);
4565 GEN_NEON_INTEGER_OP(shl);
4569 GEN_NEON_INTEGER_OP(rshl);
4574 GEN_NEON_INTEGER_OP(shl);
4576 case 5: /* VSHL, VSLI */
4578 case 0: gen_helper_neon_shl_u8(CPU_T001); break;
4579 case 1: gen_helper_neon_shl_u16(CPU_T001); break;
4580 case 2: gen_helper_neon_shl_u32(CPU_T001); break;
4585 GEN_NEON_INTEGER_OP_ENV(qshl);
4587 case 7: /* VQSHLU */
4589 case 0: gen_helper_neon_qshl_u8(CPU_T0E01); break;
4590 case 1: gen_helper_neon_qshl_u16(CPU_T0E01); break;
4591 case 2: gen_helper_neon_qshl_u32(CPU_T0E01); break;
4597 if (op == 1 || op == 3) {
4599 NEON_GET_REG(T1, rd, pass);
4601 } else if (op == 4 || (op == 5 && u)) {
4606 imm = 0xff >> -shift;
4608 imm = (uint8_t)(0xff << shift);
4614 imm = 0xffff >> -shift;
4616 imm = (uint16_t)(0xffff << shift);
4621 imm = 0xffffffffu >> -shift;
4623 imm = 0xffffffffu << shift;
4628 tmp = neon_load_reg(rd, pass);
4629 tcg_gen_andi_i32(cpu_T[0], cpu_T[0], imm);
4630 tcg_gen_andi_i32(tmp, tmp, ~imm);
4631 tcg_gen_or_i32(cpu_T[0], cpu_T[0], tmp);
4633 NEON_SET_REG(T0, rd, pass);
4636 } else if (op < 10) {
4637 /* Shift by immediate and narrow:
4638 VSHRN, VRSHRN, VQSHRN, VQRSHRN. */
4639 shift = shift - (1 << (size + 3));
4643 imm = (uint16_t)shift;
4645 tmp2 = tcg_const_i32(imm);
4648 imm = (uint32_t)shift;
4649 tmp2 = tcg_const_i32(imm);
4651 tmp2 = tcg_const_i64(shift);
4657 for (pass = 0; pass < 2; pass++) {
4659 neon_load_reg64(cpu_V0, rm + pass);
4662 gen_helper_neon_rshl_u64(cpu_V0, cpu_V0, tmp2);
4664 gen_helper_neon_rshl_s64(cpu_V0, cpu_V0, tmp2);
4667 gen_helper_neon_shl_u64(cpu_V0, cpu_V0, tmp2);
4669 gen_helper_neon_shl_s64(cpu_V0, cpu_V0, tmp2);
4672 tmp = neon_load_reg(rm + pass, 0);
4673 gen_neon_shift_narrow(size, tmp, tmp2, q, u);
4674 tcg_gen_extu_i32_i64(cpu_V0, tmp);
4676 tmp = neon_load_reg(rm + pass, 1);
4677 gen_neon_shift_narrow(size, tmp, tmp2, q, u);
4678 tcg_gen_extu_i32_i64(cpu_V1, tmp);
4680 tcg_gen_shli_i64(cpu_V1, cpu_V1, 32);
4681 tcg_gen_or_i64(cpu_V0, cpu_V0, cpu_V1);
4684 if (op == 8 && !u) {
4685 gen_neon_narrow(size - 1, tmp, cpu_V0);
4688 gen_neon_narrow_sats(size - 1, tmp, cpu_V0);
4690 gen_neon_narrow_satu(size - 1, tmp, cpu_V0);
4695 neon_store_reg(rd, 0, tmp2);
4696 neon_store_reg(rd, 1, tmp);
4699 } else if (op == 10) {
4703 tmp = neon_load_reg(rm, 0);
4704 tmp2 = neon_load_reg(rm, 1);
4705 for (pass = 0; pass < 2; pass++) {
4709 gen_neon_widen(cpu_V0, tmp, size, u);
4712 /* The shift is less than the width of the source
4713 type, so we can just shift the whole register. */
4714 tcg_gen_shli_i64(cpu_V0, cpu_V0, shift);
4715 if (size < 2 || !u) {
4718 imm = (0xffu >> (8 - shift));
4721 imm = 0xffff >> (16 - shift);
4723 imm64 = imm | (((uint64_t)imm) << 32);
4724 tcg_gen_andi_i64(cpu_V0, cpu_V0, imm64);
4727 neon_store_reg64(cpu_V0, rd + pass);
4729 } else if (op == 15 || op == 16) {
4730 /* VCVT fixed-point. */
4731 for (pass = 0; pass < (q ? 4 : 2); pass++) {
4732 tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, pass));
4735 gen_vfp_ulto(0, shift);
4737 gen_vfp_slto(0, shift);
4740 gen_vfp_toul(0, shift);
4742 gen_vfp_tosl(0, shift);
4744 tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, pass));
4749 } else { /* (insn & 0x00380080) == 0 */
4752 op = (insn >> 8) & 0xf;
4753 /* One register and immediate. */
4754 imm = (u << 7) | ((insn >> 12) & 0x70) | (insn & 0xf);
4755 invert = (insn & (1 << 5)) != 0;
4773 imm = (imm << 8) | (imm << 24);
4776 imm = (imm < 8) | 0xff;
4779 imm = (imm << 16) | 0xffff;
4782 imm |= (imm << 8) | (imm << 16) | (imm << 24);
4787 imm = ((imm & 0x80) << 24) | ((imm & 0x3f) << 19)
4788 | ((imm & 0x40) ? (0x1f << 25) : (1 << 30));
4794 if (op != 14 || !invert)
4795 gen_op_movl_T1_im(imm);
4797 for (pass = 0; pass < (q ? 4 : 2); pass++) {
4798 if (op & 1 && op < 12) {
4799 tmp = neon_load_reg(rd, pass);
4801 /* The immediate value has already been inverted, so
4803 tcg_gen_andi_i32(tmp, tmp, imm);
4805 tcg_gen_ori_i32(tmp, tmp, imm);
4810 if (op == 14 && invert) {
4813 for (n = 0; n < 4; n++) {
4814 if (imm & (1 << (n + (pass & 1) * 4)))
4815 val |= 0xff << (n * 8);
4817 tcg_gen_movi_i32(tmp, val);
4819 tcg_gen_movi_i32(tmp, imm);
4822 neon_store_reg(rd, pass, tmp);
4825 } else { /* (insn & 0x00800010 == 0x00800010) */
4827 op = (insn >> 8) & 0xf;
4828 if ((insn & (1 << 6)) == 0) {
4829 /* Three registers of different lengths. */
4833 /* prewiden, src1_wide, src2_wide */
4834 static const int neon_3reg_wide[16][3] = {
4835 {1, 0, 0}, /* VADDL */
4836 {1, 1, 0}, /* VADDW */
4837 {1, 0, 0}, /* VSUBL */
4838 {1, 1, 0}, /* VSUBW */
4839 {0, 1, 1}, /* VADDHN */
4840 {0, 0, 0}, /* VABAL */
4841 {0, 1, 1}, /* VSUBHN */
4842 {0, 0, 0}, /* VABDL */
4843 {0, 0, 0}, /* VMLAL */
4844 {0, 0, 0}, /* VQDMLAL */
4845 {0, 0, 0}, /* VMLSL */
4846 {0, 0, 0}, /* VQDMLSL */
4847 {0, 0, 0}, /* Integer VMULL */
4848 {0, 0, 0}, /* VQDMULL */
4849 {0, 0, 0} /* Polynomial VMULL */
4852 prewiden = neon_3reg_wide[op][0];
4853 src1_wide = neon_3reg_wide[op][1];
4854 src2_wide = neon_3reg_wide[op][2];
4856 if (size == 0 && (op == 9 || op == 11 || op == 13))
4859 /* Avoid overlapping operands. Wide source operands are
4860 always aligned so will never overlap with wide
4861 destinations in problematic ways. */
4862 if (rd == rm && !src2_wide) {
4863 NEON_GET_REG(T0, rm, 1);
4864 gen_neon_movl_scratch_T0(2);
4865 } else if (rd == rn && !src1_wide) {
4866 NEON_GET_REG(T0, rn, 1);
4867 gen_neon_movl_scratch_T0(2);
4869 for (pass = 0; pass < 2; pass++) {
4871 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);
4887 if (pass == 1 && rd == rm) {
4888 gen_neon_movl_T0_scratch(2);
4890 tcg_gen_mov_i32(tmp2, cpu_T[0]);
4892 tmp2 = neon_load_reg(rm, pass);
4895 gen_neon_widen(cpu_V1, tmp2, size, u);
4899 case 0: case 1: case 4: /* VADDL, VADDW, VADDHN, VRADDHN */
4900 gen_neon_addl(size);
4902 case 2: case 3: case 6: /* VSUBL, VSUBW, VSUBHL, VRSUBHL */
4903 gen_neon_subl(size);
4905 case 5: case 7: /* VABAL, VABDL */
4906 switch ((size << 1) | u) {
4908 gen_helper_neon_abdl_s16(cpu_V0, tmp, tmp2);
4911 gen_helper_neon_abdl_u16(cpu_V0, tmp, tmp2);
4914 gen_helper_neon_abdl_s32(cpu_V0, tmp, tmp2);
4917 gen_helper_neon_abdl_u32(cpu_V0, tmp, tmp2);
4920 gen_helper_neon_abdl_s64(cpu_V0, tmp, tmp2);
4923 gen_helper_neon_abdl_u64(cpu_V0, tmp, tmp2);
4930 case 8: case 9: case 10: case 11: case 12: case 13:
4931 /* VMLAL, VQDMLAL, VMLSL, VQDMLSL, VMULL, VQDMULL */
4932 gen_neon_mull(cpu_V0, tmp, tmp2, size, u);
4934 case 14: /* Polynomial VMULL */
4935 cpu_abort(env, "Polynomial VMULL not implemented");
4937 default: /* 15 is RESERVED. */
4940 if (op == 5 || op == 13 || (op >= 8 && op <= 11)) {
4942 if (op == 10 || op == 11) {
4943 gen_neon_negl(cpu_V0, size);
4947 neon_load_reg64(cpu_V1, rd + pass);
4951 case 5: case 8: case 10: /* VABAL, VMLAL, VMLSL */
4952 gen_neon_addl(size);
4954 case 9: case 11: /* VQDMLAL, VQDMLSL */
4955 gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
4956 gen_neon_addl_saturate(cpu_V0, cpu_V1, size);
4959 case 13: /* VQDMULL */
4960 gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
4965 neon_store_reg64(cpu_V0, rd + pass);
4966 } else if (op == 4 || op == 6) {
4967 /* Narrowing operation. */
4972 gen_helper_neon_narrow_high_u8(tmp, cpu_V0);
4975 gen_helper_neon_narrow_high_u16(tmp, cpu_V0);
4978 tcg_gen_shri_i64(cpu_V0, cpu_V0, 32);
4979 tcg_gen_trunc_i64_i32(tmp, cpu_V0);
4986 gen_helper_neon_narrow_round_high_u8(tmp, cpu_V0);
4989 gen_helper_neon_narrow_round_high_u16(tmp, cpu_V0);
4992 tcg_gen_addi_i64(cpu_V0, cpu_V0, 1u << 31);
4993 tcg_gen_shri_i64(cpu_V0, cpu_V0, 32);
4994 tcg_gen_trunc_i64_i32(tmp, cpu_V0);
5002 neon_store_reg(rd, 0, tmp3);
5003 neon_store_reg(rd, 1, tmp);
5006 /* Write back the result. */
5007 neon_store_reg64(cpu_V0, rd + pass);
5011 /* Two registers and a scalar. */
5013 case 0: /* Integer VMLA scalar */
5014 case 1: /* Float VMLA scalar */
5015 case 4: /* Integer VMLS scalar */
5016 case 5: /* Floating point VMLS scalar */
5017 case 8: /* Integer VMUL scalar */
5018 case 9: /* Floating point VMUL scalar */
5019 case 12: /* VQDMULH scalar */
5020 case 13: /* VQRDMULH scalar */
5021 gen_neon_get_scalar(size, rm);
5022 gen_neon_movl_scratch_T0(0);
5023 for (pass = 0; pass < (u ? 4 : 2); pass++) {
5025 gen_neon_movl_T0_scratch(0);
5026 NEON_GET_REG(T1, rn, pass);
5029 gen_helper_neon_qdmulh_s16(CPU_T0E01);
5031 gen_helper_neon_qdmulh_s32(CPU_T0E01);
5033 } else if (op == 13) {
5035 gen_helper_neon_qrdmulh_s16(CPU_T0E01);
5037 gen_helper_neon_qrdmulh_s32(CPU_T0E01);
5039 } else if (op & 1) {
5040 gen_helper_neon_mul_f32(CPU_T001);
5043 case 0: gen_helper_neon_mul_u8(CPU_T001); break;
5044 case 1: gen_helper_neon_mul_u16(CPU_T001); break;
5045 case 2: gen_op_mul_T0_T1(); break;
5051 NEON_GET_REG(T1, rd, pass);
5057 gen_helper_neon_add_f32(CPU_T001);
5063 gen_helper_neon_sub_f32(cpu_T[0], cpu_T[1], cpu_T[0]);
5069 NEON_SET_REG(T0, rd, pass);
5072 case 2: /* VMLAL sclar */
5073 case 3: /* VQDMLAL scalar */
5074 case 6: /* VMLSL scalar */
5075 case 7: /* VQDMLSL scalar */
5076 case 10: /* VMULL scalar */
5077 case 11: /* VQDMULL scalar */
5078 if (size == 0 && (op == 3 || op == 7 || op == 11))
5081 gen_neon_get_scalar(size, rm);
5082 NEON_GET_REG(T1, rn, 1);
5084 for (pass = 0; pass < 2; pass++) {
5086 tmp = neon_load_reg(rn, 0);
5089 tcg_gen_mov_i32(tmp, cpu_T[1]);
5092 tcg_gen_mov_i32(tmp2, cpu_T[0]);
5093 gen_neon_mull(cpu_V0, tmp, tmp2, size, u);
5094 if (op == 6 || op == 7) {
5095 gen_neon_negl(cpu_V0, size);
5098 neon_load_reg64(cpu_V1, rd + pass);
5102 gen_neon_addl(size);
5105 gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
5106 gen_neon_addl_saturate(cpu_V0, cpu_V1, size);
5112 gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
5117 neon_store_reg64(cpu_V0, rd + pass);
5120 default: /* 14 and 15 are RESERVED */
5124 } else { /* size == 3 */
5127 imm = (insn >> 8) & 0xf;
5134 neon_load_reg64(cpu_V0, rn);
5136 neon_load_reg64(cpu_V1, rn + 1);
5138 } else if (imm == 8) {
5139 neon_load_reg64(cpu_V0, rn + 1);
5141 neon_load_reg64(cpu_V1, rm);
5144 tmp = tcg_temp_new(TCG_TYPE_I64);
5146 neon_load_reg64(cpu_V0, rn);
5147 neon_load_reg64(tmp, rn + 1);
5149 neon_load_reg64(cpu_V0, rn + 1);
5150 neon_load_reg64(tmp, rm);
5152 tcg_gen_shri_i64(cpu_V0, cpu_V0, (imm & 7) * 8);
5153 tcg_gen_shli_i64(cpu_V1, tmp, 64 - ((imm & 7) * 8));
5154 tcg_gen_or_i64(cpu_V0, cpu_V0, cpu_V1);
5156 neon_load_reg64(cpu_V1, rm);
5158 neon_load_reg64(cpu_V1, rm + 1);
5161 tcg_gen_shli_i64(cpu_V1, cpu_V1, 64 - (imm * 8));
5162 tcg_gen_shri_i64(tmp, tmp, imm * 8);
5163 tcg_gen_or_i64(cpu_V1, cpu_V1, tmp);
5165 neon_load_reg64(cpu_V0, rn);
5166 tcg_gen_shri_i32(cpu_V0, cpu_V0, imm * 8);
5167 neon_load_reg64(cpu_V1, rm);
5168 tcg_gen_shli_i32(cpu_V1, cpu_V1, 64 - (imm * 8));
5169 tcg_gen_or_i64(cpu_V0, cpu_V0, cpu_V1);
5171 neon_store_reg64(cpu_V0, rd);
5173 neon_store_reg64(cpu_V1, rd + 1);
5175 } else if ((insn & (1 << 11)) == 0) {
5176 /* Two register misc. */
5177 op = ((insn >> 12) & 0x30) | ((insn >> 7) & 0xf);
5178 size = (insn >> 18) & 3;
5180 case 0: /* VREV64 */
5183 for (pass = 0; pass < (q ? 2 : 1); pass++) {
5184 NEON_GET_REG(T0, rm, pass * 2);
5185 NEON_GET_REG(T1, rm, pass * 2 + 1);
5187 case 0: tcg_gen_bswap_i32(cpu_T[0], cpu_T[0]); break;
5188 case 1: gen_swap_half(cpu_T[0]); break;
5189 case 2: /* no-op */ break;
5192 NEON_SET_REG(T0, rd, pass * 2 + 1);
5194 NEON_SET_REG(T1, rd, pass * 2);
5196 gen_op_movl_T0_T1();
5198 case 0: tcg_gen_bswap_i32(cpu_T[0], cpu_T[0]); break;
5199 case 1: gen_swap_half(cpu_T[0]); break;
5202 NEON_SET_REG(T0, rd, pass * 2);
5206 case 4: case 5: /* VPADDL */
5207 case 12: case 13: /* VPADAL */
5210 for (pass = 0; pass < q + 1; pass++) {
5211 tmp = neon_load_reg(rm, pass * 2);
5212 gen_neon_widen(cpu_V0, tmp, size, op & 1);
5213 tmp = neon_load_reg(rm, pass * 2 + 1);
5214 gen_neon_widen(cpu_V1, tmp, size, op & 1);
5216 case 0: gen_helper_neon_paddl_u16(CPU_V001); break;
5217 case 1: gen_helper_neon_paddl_u32(CPU_V001); break;
5218 case 2: tcg_gen_add_i64(CPU_V001); break;
5223 neon_load_reg64(cpu_V1, rd + pass);
5224 gen_neon_addl(size);
5226 neon_store_reg64(cpu_V0, rd + pass);
5231 for (n = 0; n < (q ? 4 : 2); n += 2) {
5232 NEON_GET_REG(T0, rm, n);
5233 NEON_GET_REG(T1, rd, n + 1);
5234 NEON_SET_REG(T1, rm, n);
5235 NEON_SET_REG(T0, rd, n + 1);
5243 Rd A3 A2 A1 A0 B2 B0 A2 A0
5244 Rm B3 B2 B1 B0 B3 B1 A3 A1
5248 gen_neon_unzip(rd, q, 0, size);
5249 gen_neon_unzip(rm, q, 4, size);
5251 static int unzip_order_q[8] =
5252 {0, 2, 4, 6, 1, 3, 5, 7};
5253 for (n = 0; n < 8; n++) {
5254 int reg = (n < 4) ? rd : rm;
5255 gen_neon_movl_T0_scratch(unzip_order_q[n]);
5256 NEON_SET_REG(T0, reg, n % 4);
5259 static int unzip_order[4] =
5261 for (n = 0; n < 4; n++) {
5262 int reg = (n < 2) ? rd : rm;
5263 gen_neon_movl_T0_scratch(unzip_order[n]);
5264 NEON_SET_REG(T0, reg, n % 2);
5270 Rd A3 A2 A1 A0 B1 A1 B0 A0
5271 Rm B3 B2 B1 B0 B3 A3 B2 A2
5275 count = (q ? 4 : 2);
5276 for (n = 0; n < count; n++) {
5277 NEON_GET_REG(T0, rd, n);
5278 NEON_GET_REG(T1, rd, n);
5280 case 0: gen_helper_neon_zip_u8(); break;
5281 case 1: gen_helper_neon_zip_u16(); break;
5282 case 2: /* no-op */; break;
5285 gen_neon_movl_scratch_T0(n * 2);
5286 gen_neon_movl_scratch_T1(n * 2 + 1);
5288 for (n = 0; n < count * 2; n++) {
5289 int reg = (n < count) ? rd : rm;
5290 gen_neon_movl_T0_scratch(n);
5291 NEON_SET_REG(T0, reg, n % count);
5294 case 36: case 37: /* VMOVN, VQMOVUN, VQMOVN */
5297 for (pass = 0; pass < 2; pass++) {
5298 neon_load_reg64(cpu_V0, rm + pass);
5300 if (op == 36 && q == 0) {
5301 gen_neon_narrow(size, tmp, cpu_V0);
5303 gen_neon_narrow_satu(size, tmp, cpu_V0);
5305 gen_neon_narrow_sats(size, tmp, cpu_V0);
5310 neon_store_reg(rd, 0, tmp2);
5311 neon_store_reg(rd, 1, tmp);
5315 case 38: /* VSHLL */
5318 tmp = neon_load_reg(rm, 0);
5319 tmp2 = neon_load_reg(rm, 1);
5320 for (pass = 0; pass < 2; pass++) {
5323 gen_neon_widen(cpu_V0, tmp, size, 1);
5324 neon_store_reg64(cpu_V0, rd + pass);
5329 for (pass = 0; pass < (q ? 4 : 2); pass++) {
5330 if (op == 30 || op == 31 || op >= 58) {
5331 tcg_gen_ld_f32(cpu_F0s, cpu_env,
5332 neon_reg_offset(rm, pass));
5334 NEON_GET_REG(T0, rm, pass);
5337 case 1: /* VREV32 */
5339 case 0: tcg_gen_bswap_i32(cpu_T[0], cpu_T[0]); break;
5340 case 1: gen_swap_half(cpu_T[0]); break;
5344 case 2: /* VREV16 */
5347 gen_rev16(cpu_T[0]);
5351 case 0: gen_helper_neon_cls_s8(cpu_T[0], cpu_T[0]); break;
5352 case 1: gen_helper_neon_cls_s16(cpu_T[0], cpu_T[0]); break;
5353 case 2: gen_helper_neon_cls_s32(cpu_T[0], cpu_T[0]); break;
5359 case 0: gen_helper_neon_clz_u8(cpu_T[0], cpu_T[0]); break;
5360 case 1: gen_helper_neon_clz_u16(cpu_T[0], cpu_T[0]); break;
5361 case 2: gen_helper_clz(cpu_T[0], cpu_T[0]); break;
5368 gen_helper_neon_cnt_u8(cpu_T[0], cpu_T[0]);
5375 case 14: /* VQABS */
5377 case 0: gen_helper_neon_qabs_s8(cpu_T[0], cpu_env, cpu_T[0]); break;
5378 case 1: gen_helper_neon_qabs_s16(cpu_T[0], cpu_env, cpu_T[0]); break;
5379 case 2: gen_helper_neon_qabs_s32(cpu_T[0], cpu_env, cpu_T[0]); break;
5383 case 15: /* VQNEG */
5385 case 0: gen_helper_neon_qneg_s8(cpu_T[0], cpu_env, cpu_T[0]); break;
5386 case 1: gen_helper_neon_qneg_s16(cpu_T[0], cpu_env, cpu_T[0]); break;
5387 case 2: gen_helper_neon_qneg_s32(cpu_T[0], cpu_env, cpu_T[0]); break;
5391 case 16: case 19: /* VCGT #0, VCLE #0 */
5392 gen_op_movl_T1_im(0);
5394 case 0: gen_helper_neon_cgt_s8(CPU_T001); break;
5395 case 1: gen_helper_neon_cgt_s16(CPU_T001); break;
5396 case 2: gen_helper_neon_cgt_s32(CPU_T001); break;
5402 case 17: case 20: /* VCGE #0, VCLT #0 */
5403 gen_op_movl_T1_im(0);
5405 case 0: gen_helper_neon_cge_s8(CPU_T001); break;
5406 case 1: gen_helper_neon_cge_s16(CPU_T001); break;
5407 case 2: gen_helper_neon_cge_s32(CPU_T001); break;
5413 case 18: /* VCEQ #0 */
5414 gen_op_movl_T1_im(0);
5416 case 0: gen_helper_neon_ceq_u8(CPU_T001); break;
5417 case 1: gen_helper_neon_ceq_u16(CPU_T001); break;
5418 case 2: gen_helper_neon_ceq_u32(CPU_T001); break;
5424 case 0: gen_helper_neon_abs_s8(cpu_T[0], cpu_T[0]); break;
5425 case 1: gen_helper_neon_abs_s16(cpu_T[0], cpu_T[0]); break;
5426 case 2: tcg_gen_abs_i32(cpu_T[0], cpu_T[0]); break;
5431 gen_op_movl_T1_im(0);
5436 case 24: case 27: /* Float VCGT #0, Float VCLE #0 */
5437 gen_op_movl_T1_im(0);
5438 gen_helper_neon_cgt_f32(CPU_T001);
5442 case 25: case 28: /* Float VCGE #0, Float VCLT #0 */
5443 gen_op_movl_T1_im(0);
5444 gen_helper_neon_cge_f32(CPU_T001);
5448 case 26: /* Float VCEQ #0 */
5449 gen_op_movl_T1_im(0);
5450 gen_helper_neon_ceq_f32(CPU_T001);
5452 case 30: /* Float VABS */
5455 case 31: /* Float VNEG */
5459 NEON_GET_REG(T1, rd, pass);
5460 NEON_SET_REG(T1, rm, pass);
5463 NEON_GET_REG(T1, rd, pass);
5465 case 0: gen_helper_neon_trn_u8(); break;
5466 case 1: gen_helper_neon_trn_u16(); break;
5470 NEON_SET_REG(T1, rm, pass);
5472 case 56: /* Integer VRECPE */
5473 gen_helper_recpe_u32(cpu_T[0], cpu_T[0], cpu_env);
5475 case 57: /* Integer VRSQRTE */
5476 gen_helper_rsqrte_u32(cpu_T[0], cpu_T[0], cpu_env);
5478 case 58: /* Float VRECPE */
5479 gen_helper_recpe_f32(cpu_F0s, cpu_F0s, cpu_env);
5481 case 59: /* Float VRSQRTE */
5482 gen_helper_rsqrte_f32(cpu_F0s, cpu_F0s, cpu_env);
5484 case 60: /* VCVT.F32.S32 */
5487 case 61: /* VCVT.F32.U32 */
5490 case 62: /* VCVT.S32.F32 */
5493 case 63: /* VCVT.U32.F32 */
5497 /* Reserved: 21, 29, 39-56 */
5500 if (op == 30 || op == 31 || op >= 58) {
5501 tcg_gen_st_f32(cpu_F0s, cpu_env,
5502 neon_reg_offset(rd, pass));
5504 NEON_SET_REG(T0, rd, pass);
5509 } else if ((insn & (1 << 10)) == 0) {
5511 n = (insn >> 5) & 0x18;
5512 if (insn & (1 << 6)) {
5513 tmp = neon_load_reg(rd, 0);
5516 tcg_gen_movi_i32(tmp, 0);
5518 tmp2 = neon_load_reg(rm, 0);
5519 gen_helper_neon_tbl(tmp2, tmp2, tmp, tcg_const_i32(rn),
5521 if (insn & (1 << 6)) {
5522 tmp = neon_load_reg(rd, 1);
5525 tcg_gen_movi_i32(tmp, 0);
5527 tmp3 = neon_load_reg(rm, 1);
5528 gen_helper_neon_tbl(tmp3, tmp3, tmp, tcg_const_i32(rn),
5530 neon_store_reg(rd, 0, tmp2);
5531 neon_store_reg(rd, 1, tmp2);
5532 } else if ((insn & 0x380) == 0) {
5534 if (insn & (1 << 19)) {
5535 NEON_SET_REG(T0, rm, 1);
5537 NEON_SET_REG(T0, rm, 0);
5539 if (insn & (1 << 16)) {
5540 gen_neon_dup_u8(cpu_T[0], ((insn >> 17) & 3) * 8);
5541 } else if (insn & (1 << 17)) {
5542 if ((insn >> 18) & 1)
5543 gen_neon_dup_high16(cpu_T[0]);
5545 gen_neon_dup_low16(cpu_T[0]);
5547 for (pass = 0; pass < (q ? 4 : 2); pass++) {
5548 NEON_SET_REG(T0, rd, pass);
5558 static int disas_coproc_insn(CPUState * env, DisasContext *s, uint32_t insn)
5562 cpnum = (insn >> 8) & 0xf;
5563 if (arm_feature(env, ARM_FEATURE_XSCALE)
5564 && ((env->cp15.c15_cpar ^ 0x3fff) & (1 << cpnum)))
5570 if (arm_feature(env, ARM_FEATURE_IWMMXT)) {
5571 return disas_iwmmxt_insn(env, s, insn);
5572 } else if (arm_feature(env, ARM_FEATURE_XSCALE)) {
5573 return disas_dsp_insn(env, s, insn);
5578 return disas_vfp_insn (env, s, insn);
5580 return disas_cp15_insn (env, s, insn);
5582 /* Unknown coprocessor. See if the board has hooked it. */
5583 return disas_cp_insn (env, s, insn);
5588 /* Store a 64-bit value to a register pair. Clobbers val. */
5589 static void gen_storeq_reg(DisasContext *s, int rlow, int rhigh, TCGv val)
5593 tcg_gen_trunc_i64_i32(tmp, val);
5594 store_reg(s, rlow, tmp);
5596 tcg_gen_shri_i64(val, val, 32);
5597 tcg_gen_trunc_i64_i32(tmp, val);
5598 store_reg(s, rhigh, tmp);
5601 /* load a 32-bit value from a register and perform a 64-bit accumulate. */
5602 static void gen_addq_lo(DisasContext *s, TCGv val, int rlow)
5607 /* Load 64-bit value rd:rn. */
5608 tmp = tcg_temp_new(TCG_TYPE_I64);
5609 tmp2 = load_reg(s, rlow);
5610 tcg_gen_extu_i32_i64(tmp, tmp2);
5612 tcg_gen_add_i64(val, val, tmp);
5615 /* load and add a 64-bit value from a register pair. */
5616 static void gen_addq(DisasContext *s, TCGv val, int rlow, int rhigh)
5621 /* Load 64-bit value rd:rn. */
5622 tmp = tcg_temp_new(TCG_TYPE_I64);
5623 tmp2 = load_reg(s, rhigh);
5624 tcg_gen_extu_i32_i64(tmp, tmp2);
5626 tcg_gen_shli_i64(tmp, tmp, 32);
5627 tcg_gen_add_i64(val, val, tmp);
5629 tmp2 = load_reg(s, rlow);
5630 tcg_gen_extu_i32_i64(tmp, tmp2);
5632 tcg_gen_add_i64(val, val, tmp);
5635 /* Set N and Z flags from a 64-bit value. */
5636 static void gen_logicq_cc(TCGv val)
5638 TCGv tmp = new_tmp();
5639 gen_helper_logicq_cc(tmp, val);
5644 static void disas_arm_insn(CPUState * env, DisasContext *s)
5646 unsigned int cond, insn, val, op1, i, shift, rm, rs, rn, rd, sh;
5652 insn = ldl_code(s->pc);
5655 /* M variants do not implement ARM mode. */
5660 /* Unconditional instructions. */
5661 if (((insn >> 25) & 7) == 1) {
5662 /* NEON Data processing. */
5663 if (!arm_feature(env, ARM_FEATURE_NEON))
5666 if (disas_neon_data_insn(env, s, insn))
5670 if ((insn & 0x0f100000) == 0x04000000) {
5671 /* NEON load/store. */
5672 if (!arm_feature(env, ARM_FEATURE_NEON))
5675 if (disas_neon_ls_insn(env, s, insn))
5679 if ((insn & 0x0d70f000) == 0x0550f000)
5681 else if ((insn & 0x0ffffdff) == 0x01010000) {
5684 if (insn & (1 << 9)) {
5685 /* BE8 mode not implemented. */
5689 } else if ((insn & 0x0fffff00) == 0x057ff000) {
5690 switch ((insn >> 4) & 0xf) {
5693 gen_helper_clrex(cpu_env);
5699 /* We don't emulate caches so these are a no-op. */
5704 } else if ((insn & 0x0e5fffe0) == 0x084d0500) {
5710 op1 = (insn & 0x1f);
5711 if (op1 == (env->uncached_cpsr & CPSR_M)) {
5712 addr = load_reg(s, 13);
5715 gen_helper_get_r13_banked(addr, cpu_env, tcg_const_i32(op1));
5717 i = (insn >> 23) & 3;
5719 case 0: offset = -4; break; /* DA */
5720 case 1: offset = -8; break; /* DB */
5721 case 2: offset = 0; break; /* IA */
5722 case 3: offset = 4; break; /* IB */
5726 tcg_gen_addi_i32(addr, addr, offset);
5727 tmp = load_reg(s, 14);
5728 gen_st32(tmp, addr, 0);
5730 gen_helper_cpsr_read(tmp);
5731 tcg_gen_addi_i32(addr, addr, 4);
5732 gen_st32(tmp, addr, 0);
5733 if (insn & (1 << 21)) {
5734 /* Base writeback. */
5736 case 0: offset = -8; break;
5737 case 1: offset = -4; break;
5738 case 2: offset = 4; break;
5739 case 3: offset = 0; break;
5743 tcg_gen_addi_i32(addr, tmp, offset);
5744 if (op1 == (env->uncached_cpsr & CPSR_M)) {
5745 gen_movl_reg_T1(s, 13);
5747 gen_helper_set_r13_banked(cpu_env, tcg_const_i32(op1), cpu_T[1]);
5752 } else if ((insn & 0x0e5fffe0) == 0x081d0a00) {
5758 rn = (insn >> 16) & 0xf;
5759 addr = load_reg(s, rn);
5760 i = (insn >> 23) & 3;
5762 case 0: offset = -4; break; /* DA */
5763 case 1: offset = -8; break; /* DB */
5764 case 2: offset = 0; break; /* IA */
5765 case 3: offset = 4; break; /* IB */
5769 tcg_gen_addi_i32(addr, addr, offset);
5770 /* Load PC into tmp and CPSR into tmp2. */
5771 tmp = gen_ld32(addr, 0);
5772 tcg_gen_addi_i32(addr, addr, 4);
5773 tmp2 = gen_ld32(addr, 0);
5774 if (insn & (1 << 21)) {
5775 /* Base writeback. */
5777 case 0: offset = -8; break;
5778 case 1: offset = -4; break;
5779 case 2: offset = 4; break;
5780 case 3: offset = 0; break;
5784 tcg_gen_addi_i32(addr, addr, offset);
5785 store_reg(s, rn, addr);
5789 gen_rfe(s, tmp, tmp2);
5790 } else if ((insn & 0x0e000000) == 0x0a000000) {
5791 /* branch link and change to thumb (blx <offset>) */
5794 val = (uint32_t)s->pc;
5796 tcg_gen_movi_i32(tmp, val);
5797 store_reg(s, 14, tmp);
5798 /* Sign-extend the 24-bit offset */
5799 offset = (((int32_t)insn) << 8) >> 8;
5800 /* offset * 4 + bit24 * 2 + (thumb bit) */
5801 val += (offset << 2) | ((insn >> 23) & 2) | 1;
5802 /* pipeline offset */
5806 } else if ((insn & 0x0e000f00) == 0x0c000100) {
5807 if (arm_feature(env, ARM_FEATURE_IWMMXT)) {
5808 /* iWMMXt register transfer. */
5809 if (env->cp15.c15_cpar & (1 << 1))
5810 if (!disas_iwmmxt_insn(env, s, insn))
5813 } else if ((insn & 0x0fe00000) == 0x0c400000) {
5814 /* Coprocessor double register transfer. */
5815 } else if ((insn & 0x0f000010) == 0x0e000010) {
5816 /* Additional coprocessor register transfer. */
5817 } else if ((insn & 0x0ff10010) == 0x01000000) {
5820 /* cps (privileged) */
5824 if (insn & (1 << 19)) {
5825 if (insn & (1 << 8))
5827 if (insn & (1 << 7))
5829 if (insn & (1 << 6))
5831 if (insn & (1 << 18))
5834 if (insn & (1 << 14)) {
5836 val |= (insn & 0x1f);
5839 gen_op_movl_T0_im(val);
5840 gen_set_psr_T0(s, mask, 0);
5847 /* if not always execute, we generate a conditional jump to
5849 s->condlabel = gen_new_label();
5850 gen_test_cc(cond ^ 1, s->condlabel);
5853 if ((insn & 0x0f900000) == 0x03000000) {
5854 if ((insn & (1 << 21)) == 0) {
5856 rd = (insn >> 12) & 0xf;
5857 val = ((insn >> 4) & 0xf000) | (insn & 0xfff);
5858 if ((insn & (1 << 22)) == 0) {
5861 tcg_gen_movi_i32(tmp, val);
5864 tmp = load_reg(s, rd);
5865 tcg_gen_andi_i32(tmp, tmp, 0xffff);
5866 tcg_gen_ori_i32(tmp, tmp, val << 16);
5868 store_reg(s, rd, tmp);
5870 if (((insn >> 12) & 0xf) != 0xf)
5872 if (((insn >> 16) & 0xf) == 0) {
5873 gen_nop_hint(s, insn & 0xff);
5875 /* CPSR = immediate */
5877 shift = ((insn >> 8) & 0xf) * 2;
5879 val = (val >> shift) | (val << (32 - shift));
5880 gen_op_movl_T0_im(val);
5881 i = ((insn & (1 << 22)) != 0);
5882 if (gen_set_psr_T0(s, msr_mask(env, s, (insn >> 16) & 0xf, i), i))
5886 } else if ((insn & 0x0f900000) == 0x01000000
5887 && (insn & 0x00000090) != 0x00000090) {
5888 /* miscellaneous instructions */
5889 op1 = (insn >> 21) & 3;
5890 sh = (insn >> 4) & 0xf;
5893 case 0x0: /* move program status register */
5896 gen_movl_T0_reg(s, rm);
5897 i = ((op1 & 2) != 0);
5898 if (gen_set_psr_T0(s, msr_mask(env, s, (insn >> 16) & 0xf, i), i))
5902 rd = (insn >> 12) & 0xf;
5906 tmp = load_cpu_field(spsr);
5909 gen_helper_cpsr_read(tmp);
5911 store_reg(s, rd, tmp);
5916 /* branch/exchange thumb (bx). */
5917 tmp = load_reg(s, rm);
5919 } else if (op1 == 3) {
5921 rd = (insn >> 12) & 0xf;
5922 tmp = load_reg(s, rm);
5923 gen_helper_clz(tmp, tmp);
5924 store_reg(s, rd, tmp);
5932 /* Trivial implementation equivalent to bx. */
5933 tmp = load_reg(s, rm);
5943 /* branch link/exchange thumb (blx) */
5944 tmp = load_reg(s, rm);
5946 tcg_gen_movi_i32(tmp2, s->pc);
5947 store_reg(s, 14, tmp2);
5950 case 0x5: /* saturating add/subtract */
5951 rd = (insn >> 12) & 0xf;
5952 rn = (insn >> 16) & 0xf;
5953 tmp = load_reg(s, rn);
5954 tmp2 = load_reg(s, rn);
5956 gen_helper_double_saturate(tmp2, tmp2);
5958 gen_helper_sub_saturate(tmp, tmp, tmp2);
5960 gen_helper_add_saturate(tmp, tmp, tmp2);
5962 store_reg(s, rd, tmp);
5965 gen_set_condexec(s);
5966 gen_set_pc_im(s->pc - 4);
5967 gen_exception(EXCP_BKPT);
5968 s->is_jmp = DISAS_JUMP;
5970 case 0x8: /* signed multiply */
5974 rs = (insn >> 8) & 0xf;
5975 rn = (insn >> 12) & 0xf;
5976 rd = (insn >> 16) & 0xf;
5978 /* (32 * 16) >> 16 */
5979 tmp = load_reg(s, rm);
5980 tmp2 = load_reg(s, rs);
5982 tcg_gen_sari_i32(tmp2, tmp2, 16);
5985 tmp2 = gen_muls_i64_i32(tmp, tmp2);
5986 tcg_gen_shri_i64(tmp2, tmp2, 16);
5988 tcg_gen_trunc_i64_i32(tmp, tmp2);
5989 if ((sh & 2) == 0) {
5990 tmp2 = load_reg(s, rn);
5991 gen_helper_add_setq(tmp, tmp, tmp2);
5994 store_reg(s, rd, tmp);
5997 tmp = load_reg(s, rm);
5998 tmp2 = load_reg(s, rs);
5999 gen_mulxy(tmp, tmp2, sh & 2, sh & 4);
6002 tmp = tcg_temp_new(TCG_TYPE_I64);
6003 tcg_gen_ext_i32_i64(tmp, cpu_T[0]);
6004 gen_addq(s, tmp, rn, rd);
6005 gen_storeq_reg(s, rn, rd, tmp);
6008 tmp2 = load_reg(s, rn);
6009 gen_helper_add_setq(tmp, tmp, tmp2);
6012 store_reg(s, rd, tmp);
6019 } else if (((insn & 0x0e000000) == 0 &&
6020 (insn & 0x00000090) != 0x90) ||
6021 ((insn & 0x0e000000) == (1 << 25))) {
6022 int set_cc, logic_cc, shiftop;
6024 op1 = (insn >> 21) & 0xf;
6025 set_cc = (insn >> 20) & 1;
6026 logic_cc = table_logic_cc[op1] & set_cc;
6028 /* data processing instruction */
6029 if (insn & (1 << 25)) {
6030 /* immediate operand */
6032 shift = ((insn >> 8) & 0xf) * 2;
6034 val = (val >> shift) | (val << (32 - shift));
6035 gen_op_movl_T1_im(val);
6036 if (logic_cc && shift)
6037 gen_set_CF_bit31(cpu_T[1]);
6041 gen_movl_T1_reg(s, rm);
6042 shiftop = (insn >> 5) & 3;
6043 if (!(insn & (1 << 4))) {
6044 shift = (insn >> 7) & 0x1f;
6045 gen_arm_shift_im(cpu_T[1], shiftop, shift, logic_cc);
6047 rs = (insn >> 8) & 0xf;
6048 tmp = load_reg(s, rs);
6049 gen_arm_shift_reg(cpu_T[1], shiftop, tmp, logic_cc);
6052 if (op1 != 0x0f && op1 != 0x0d) {
6053 rn = (insn >> 16) & 0xf;
6054 gen_movl_T0_reg(s, rn);
6056 rd = (insn >> 12) & 0xf;
6059 gen_op_andl_T0_T1();
6060 gen_movl_reg_T0(s, rd);
6062 gen_op_logic_T0_cc();
6065 gen_op_xorl_T0_T1();
6066 gen_movl_reg_T0(s, rd);
6068 gen_op_logic_T0_cc();
6071 if (set_cc && rd == 15) {
6072 /* SUBS r15, ... is used for exception return. */
6075 gen_op_subl_T0_T1_cc();
6076 gen_exception_return(s);
6079 gen_op_subl_T0_T1_cc();
6081 gen_op_subl_T0_T1();
6082 gen_movl_reg_T0(s, rd);
6087 gen_op_rsbl_T0_T1_cc();
6089 gen_op_rsbl_T0_T1();
6090 gen_movl_reg_T0(s, rd);
6094 gen_op_addl_T0_T1_cc();
6096 gen_op_addl_T0_T1();
6097 gen_movl_reg_T0(s, rd);
6101 gen_op_adcl_T0_T1_cc();
6104 gen_movl_reg_T0(s, rd);
6108 gen_op_sbcl_T0_T1_cc();
6111 gen_movl_reg_T0(s, rd);
6115 gen_op_rscl_T0_T1_cc();
6118 gen_movl_reg_T0(s, rd);
6122 gen_op_andl_T0_T1();
6123 gen_op_logic_T0_cc();
6128 gen_op_xorl_T0_T1();
6129 gen_op_logic_T0_cc();
6134 gen_op_subl_T0_T1_cc();
6139 gen_op_addl_T0_T1_cc();
6144 gen_movl_reg_T0(s, rd);
6146 gen_op_logic_T0_cc();
6149 if (logic_cc && rd == 15) {
6150 /* MOVS r15, ... is used for exception return. */
6153 gen_op_movl_T0_T1();
6154 gen_exception_return(s);
6156 gen_movl_reg_T1(s, rd);
6158 gen_op_logic_T1_cc();
6162 gen_op_bicl_T0_T1();
6163 gen_movl_reg_T0(s, rd);
6165 gen_op_logic_T0_cc();
6170 gen_movl_reg_T1(s, rd);
6172 gen_op_logic_T1_cc();
6176 /* other instructions */
6177 op1 = (insn >> 24) & 0xf;
6181 /* multiplies, extra load/stores */
6182 sh = (insn >> 5) & 3;
6185 rd = (insn >> 16) & 0xf;
6186 rn = (insn >> 12) & 0xf;
6187 rs = (insn >> 8) & 0xf;
6189 op1 = (insn >> 20) & 0xf;
6191 case 0: case 1: case 2: case 3: case 6:
6193 tmp = load_reg(s, rs);
6194 tmp2 = load_reg(s, rm);
6195 tcg_gen_mul_i32(tmp, tmp, tmp2);
6197 if (insn & (1 << 22)) {
6198 /* Subtract (mls) */
6200 tmp2 = load_reg(s, rn);
6201 tcg_gen_sub_i32(tmp, tmp2, tmp);
6203 } else if (insn & (1 << 21)) {
6205 tmp2 = load_reg(s, rn);
6206 tcg_gen_add_i32(tmp, tmp, tmp2);
6209 if (insn & (1 << 20))
6211 store_reg(s, rd, tmp);
6215 tmp = load_reg(s, rs);
6216 tmp2 = load_reg(s, rm);
6217 if (insn & (1 << 22))
6218 tmp = gen_muls_i64_i32(tmp, tmp2);
6220 tmp = gen_mulu_i64_i32(tmp, tmp2);
6221 if (insn & (1 << 21)) /* mult accumulate */
6222 gen_addq(s, tmp, rn, rd);
6223 if (!(insn & (1 << 23))) { /* double accumulate */
6225 gen_addq_lo(s, tmp, rn);
6226 gen_addq_lo(s, tmp, rd);
6228 if (insn & (1 << 20))
6230 gen_storeq_reg(s, rn, rd, tmp);
6234 rn = (insn >> 16) & 0xf;
6235 rd = (insn >> 12) & 0xf;
6236 if (insn & (1 << 23)) {
6237 /* load/store exclusive */
6238 gen_movl_T1_reg(s, rn);
6240 if (insn & (1 << 20)) {
6241 gen_helper_mark_exclusive(cpu_env, cpu_T[1]);
6242 tmp = gen_ld32(addr, IS_USER(s));
6243 store_reg(s, rd, tmp);
6245 int label = gen_new_label();
6247 gen_helper_test_exclusive(cpu_T[0], cpu_env, addr);
6248 tcg_gen_brcond_i32(TCG_COND_NE, cpu_T[0],
6249 tcg_const_i32(0), label);
6250 tmp = load_reg(s,rm);
6251 gen_st32(tmp, cpu_T[1], IS_USER(s));
6252 gen_set_label(label);
6253 gen_movl_reg_T0(s, rd);
6256 /* SWP instruction */
6259 /* ??? This is not really atomic. However we know
6260 we never have multiple CPUs running in parallel,
6261 so it is good enough. */
6262 addr = load_reg(s, rn);
6263 tmp = load_reg(s, rm);
6264 if (insn & (1 << 22)) {
6265 tmp2 = gen_ld8u(addr, IS_USER(s));
6266 gen_st8(tmp, addr, IS_USER(s));
6268 tmp2 = gen_ld32(addr, IS_USER(s));
6269 gen_st32(tmp, addr, IS_USER(s));
6272 store_reg(s, rd, tmp2);
6278 /* Misc load/store */
6279 rn = (insn >> 16) & 0xf;
6280 rd = (insn >> 12) & 0xf;
6281 addr = load_reg(s, rn);
6282 if (insn & (1 << 24))
6283 gen_add_datah_offset(s, insn, 0, addr);
6285 if (insn & (1 << 20)) {
6289 tmp = gen_ld16u(addr, IS_USER(s));
6292 tmp = gen_ld8s(addr, IS_USER(s));
6296 tmp = gen_ld16s(addr, IS_USER(s));
6300 } else if (sh & 2) {
6304 tmp = load_reg(s, rd);
6305 gen_st32(tmp, addr, IS_USER(s));
6306 tcg_gen_addi_i32(addr, addr, 4);
6307 tmp = load_reg(s, rd + 1);
6308 gen_st32(tmp, addr, IS_USER(s));
6312 tmp = gen_ld32(addr, IS_USER(s));
6313 store_reg(s, rd, tmp);
6314 tcg_gen_addi_i32(addr, addr, 4);
6315 tmp = gen_ld32(addr, IS_USER(s));
6319 address_offset = -4;
6322 tmp = load_reg(s, rd);
6323 gen_st16(tmp, addr, IS_USER(s));
6326 /* Perform base writeback before the loaded value to
6327 ensure correct behavior with overlapping index registers.
6328 ldrd with base writeback is is undefined if the
6329 destination and index registers overlap. */
6330 if (!(insn & (1 << 24))) {
6331 gen_add_datah_offset(s, insn, address_offset, addr);
6332 store_reg(s, rn, addr);
6333 } else if (insn & (1 << 21)) {
6335 tcg_gen_addi_i32(addr, addr, address_offset);
6336 store_reg(s, rn, addr);
6341 /* Complete the load. */
6342 store_reg(s, rd, tmp);
6351 if (insn & (1 << 4)) {
6353 /* Armv6 Media instructions. */
6355 rn = (insn >> 16) & 0xf;
6356 rd = (insn >> 12) & 0xf;
6357 rs = (insn >> 8) & 0xf;
6358 switch ((insn >> 23) & 3) {
6359 case 0: /* Parallel add/subtract. */
6360 op1 = (insn >> 20) & 7;
6361 tmp = load_reg(s, rn);
6362 tmp2 = load_reg(s, rm);
6363 sh = (insn >> 5) & 7;
6364 if ((op1 & 3) == 0 || sh == 5 || sh == 6)
6366 gen_arm_parallel_addsub(op1, sh, tmp, tmp2);
6368 store_reg(s, rd, tmp);
6371 if ((insn & 0x00700020) == 0) {
6372 /* Halfword pack. */
6373 tmp = load_reg(s, rn);
6374 tmp2 = load_reg(s, rm);
6375 shift = (insn >> 7) & 0x1f;
6377 tcg_gen_shli_i32(tmp2, tmp2, shift);
6378 if (insn & (1 << 6)) {
6380 tcg_gen_andi_i32(tmp, tmp, 0xffff0000);
6381 tcg_gen_andi_i32(tmp2, tmp2, 0xffff);
6384 tcg_gen_andi_i32(tmp, tmp, 0xffff);
6385 tcg_gen_andi_i32(tmp2, tmp2, 0xffff0000);
6387 tcg_gen_or_i32(tmp, tmp, tmp2);
6388 store_reg(s, rd, tmp);
6389 } else if ((insn & 0x00200020) == 0x00200000) {
6391 tmp = load_reg(s, rm);
6392 shift = (insn >> 7) & 0x1f;
6393 if (insn & (1 << 6)) {
6396 tcg_gen_sari_i32(tmp, tmp, shift);
6398 tcg_gen_shli_i32(tmp, tmp, shift);
6400 sh = (insn >> 16) & 0x1f;
6402 if (insn & (1 << 22))
6403 gen_helper_usat(tmp, tmp, tcg_const_i32(sh));
6405 gen_helper_ssat(tmp, tmp, tcg_const_i32(sh));
6407 store_reg(s, rd, tmp);
6408 } else if ((insn & 0x00300fe0) == 0x00200f20) {
6410 tmp = load_reg(s, rm);
6411 sh = (insn >> 16) & 0x1f;
6413 if (insn & (1 << 22))
6414 gen_helper_usat16(tmp, tmp, tcg_const_i32(sh));
6416 gen_helper_ssat16(tmp, tmp, tcg_const_i32(sh));
6418 store_reg(s, rd, tmp);
6419 } else if ((insn & 0x00700fe0) == 0x00000fa0) {
6421 tmp = load_reg(s, rn);
6422 tmp2 = load_reg(s, rm);
6424 tcg_gen_ld_i32(tmp3, cpu_env, offsetof(CPUState, GE));
6425 gen_helper_sel_flags(tmp, tmp3, tmp, tmp2);
6428 store_reg(s, rd, tmp);
6429 } else if ((insn & 0x000003e0) == 0x00000060) {
6430 tmp = load_reg(s, rm);
6431 shift = (insn >> 10) & 3;
6432 /* ??? In many cases it's not neccessary to do a
6433 rotate, a shift is sufficient. */
6435 tcg_gen_rori_i32(tmp, tmp, shift * 8);
6436 op1 = (insn >> 20) & 7;
6438 case 0: gen_sxtb16(tmp); break;
6439 case 2: gen_sxtb(tmp); break;
6440 case 3: gen_sxth(tmp); break;
6441 case 4: gen_uxtb16(tmp); break;
6442 case 6: gen_uxtb(tmp); break;
6443 case 7: gen_uxth(tmp); break;
6444 default: goto illegal_op;
6447 tmp2 = load_reg(s, rn);
6448 if ((op1 & 3) == 0) {
6449 gen_add16(tmp, tmp2);
6451 tcg_gen_add_i32(tmp, tmp, tmp2);
6455 store_reg(s, rd, tmp);
6456 } else if ((insn & 0x003f0f60) == 0x003f0f20) {
6458 tmp = load_reg(s, rm);
6459 if (insn & (1 << 22)) {
6460 if (insn & (1 << 7)) {
6464 gen_helper_rbit(tmp, tmp);
6467 if (insn & (1 << 7))
6470 tcg_gen_bswap_i32(tmp, tmp);
6472 store_reg(s, rd, tmp);
6477 case 2: /* Multiplies (Type 3). */
6478 tmp = load_reg(s, rm);
6479 tmp2 = load_reg(s, rs);
6480 if (insn & (1 << 20)) {
6481 /* Signed multiply most significant [accumulate]. */
6482 tmp2 = gen_muls_i64_i32(tmp, tmp2);
6483 if (insn & (1 << 5))
6484 tcg_gen_addi_i64(tmp2, tmp2, 0x80000000u);
6485 tcg_gen_shri_i64(tmp2, tmp2, 32);
6487 tcg_gen_trunc_i64_i32(tmp, tmp2);
6489 tmp2 = load_reg(s, rn);
6490 if (insn & (1 << 6)) {
6491 tcg_gen_sub_i32(tmp, tmp, tmp2);
6493 tcg_gen_add_i32(tmp, tmp, tmp2);
6497 store_reg(s, rd, tmp);
6499 if (insn & (1 << 5))
6500 gen_swap_half(tmp2);
6501 gen_smul_dual(tmp, tmp2);
6502 /* This addition cannot overflow. */
6503 if (insn & (1 << 6)) {
6504 tcg_gen_sub_i32(tmp, tmp, tmp2);
6506 tcg_gen_add_i32(tmp, tmp, tmp2);
6509 if (insn & (1 << 22)) {
6510 /* smlald, smlsld */
6511 tmp2 = tcg_temp_new(TCG_TYPE_I64);
6512 tcg_gen_ext_i32_i64(tmp2, tmp);
6514 gen_addq(s, tmp2, rn, rd);
6515 gen_storeq_reg(s, rn, rd, tmp2);
6517 /* smuad, smusd, smlad, smlsd */
6520 tmp2 = load_reg(s, rn);
6521 gen_helper_add_setq(tmp, tmp, tmp2);
6524 store_reg(s, rd, tmp);
6529 op1 = ((insn >> 17) & 0x38) | ((insn >> 5) & 7);
6531 case 0: /* Unsigned sum of absolute differences. */
6533 tmp = load_reg(s, rm);
6534 tmp2 = load_reg(s, rs);
6535 gen_helper_usad8(tmp, tmp, tmp2);
6538 tmp2 = load_reg(s, rn);
6539 tcg_gen_add_i32(tmp, tmp, tmp2);
6542 store_reg(s, rd, tmp);
6544 case 0x20: case 0x24: case 0x28: case 0x2c:
6545 /* Bitfield insert/clear. */
6547 shift = (insn >> 7) & 0x1f;
6548 i = (insn >> 16) & 0x1f;
6552 tcg_gen_movi_i32(tmp, 0);
6554 tmp = load_reg(s, rm);
6557 tmp2 = load_reg(s, rd);
6558 gen_bfi(tmp, tmp2, tmp, shift, (1u << i) - 1);
6561 store_reg(s, rd, tmp);
6563 case 0x12: case 0x16: case 0x1a: case 0x1e: /* sbfx */
6564 case 0x32: case 0x36: case 0x3a: case 0x3e: /* ubfx */
6565 tmp = load_reg(s, rm);
6566 shift = (insn >> 7) & 0x1f;
6567 i = ((insn >> 16) & 0x1f) + 1;
6572 gen_ubfx(tmp, shift, (1u << i) - 1);
6574 gen_sbfx(tmp, shift, i);
6577 store_reg(s, rd, tmp);
6587 /* Check for undefined extension instructions
6588 * per the ARM Bible IE:
6589 * xxxx 0111 1111 xxxx xxxx xxxx 1111 xxxx
6591 sh = (0xf << 20) | (0xf << 4);
6592 if (op1 == 0x7 && ((insn & sh) == sh))
6596 /* load/store byte/word */
6597 rn = (insn >> 16) & 0xf;
6598 rd = (insn >> 12) & 0xf;
6599 tmp2 = load_reg(s, rn);
6600 i = (IS_USER(s) || (insn & 0x01200000) == 0x00200000);
6601 if (insn & (1 << 24))
6602 gen_add_data_offset(s, insn, tmp2);
6603 if (insn & (1 << 20)) {
6606 if (insn & (1 << 22)) {
6607 tmp = gen_ld8u(tmp2, i);
6609 tmp = gen_ld32(tmp2, i);
6613 tmp = load_reg(s, rd);
6614 if (insn & (1 << 22))
6615 gen_st8(tmp, tmp2, i);
6617 gen_st32(tmp, tmp2, i);
6619 if (!(insn & (1 << 24))) {
6620 gen_add_data_offset(s, insn, tmp2);
6621 store_reg(s, rn, tmp2);
6622 } else if (insn & (1 << 21)) {
6623 store_reg(s, rn, tmp2);
6627 if (insn & (1 << 20)) {
6628 /* Complete the load. */
6632 store_reg(s, rd, tmp);
6638 int j, n, user, loaded_base;
6640 /* load/store multiple words */
6641 /* XXX: store correct base if write back */
6643 if (insn & (1 << 22)) {
6645 goto illegal_op; /* only usable in supervisor mode */
6647 if ((insn & (1 << 15)) == 0)
6650 rn = (insn >> 16) & 0xf;
6651 addr = load_reg(s, rn);
6653 /* compute total size */
6657 if (insn & (1 << i))
6660 /* XXX: test invalid n == 0 case ? */
6661 if (insn & (1 << 23)) {
6662 if (insn & (1 << 24)) {
6664 tcg_gen_addi_i32(addr, addr, 4);
6666 /* post increment */
6669 if (insn & (1 << 24)) {
6671 tcg_gen_addi_i32(addr, addr, -(n * 4));
6673 /* post decrement */
6675 tcg_gen_addi_i32(addr, addr, -((n - 1) * 4));
6680 if (insn & (1 << i)) {
6681 if (insn & (1 << 20)) {
6683 tmp = gen_ld32(addr, IS_USER(s));
6687 gen_helper_set_user_reg(tcg_const_i32(i), tmp);
6689 } else if (i == rn) {
6693 store_reg(s, i, tmp);
6698 /* special case: r15 = PC + 8 */
6699 val = (long)s->pc + 4;
6701 tcg_gen_movi_i32(tmp, val);
6704 gen_helper_get_user_reg(tmp, tcg_const_i32(i));
6706 tmp = load_reg(s, i);
6708 gen_st32(tmp, addr, IS_USER(s));
6711 /* no need to add after the last transfer */
6713 tcg_gen_addi_i32(addr, addr, 4);
6716 if (insn & (1 << 21)) {
6718 if (insn & (1 << 23)) {
6719 if (insn & (1 << 24)) {
6722 /* post increment */
6723 tcg_gen_addi_i32(addr, addr, 4);
6726 if (insn & (1 << 24)) {
6729 tcg_gen_addi_i32(addr, addr, -((n - 1) * 4));
6731 /* post decrement */
6732 tcg_gen_addi_i32(addr, addr, -(n * 4));
6735 store_reg(s, rn, addr);
6740 store_reg(s, rn, loaded_var);
6742 if ((insn & (1 << 22)) && !user) {
6743 /* Restore CPSR from SPSR. */
6744 tmp = load_cpu_field(spsr);
6745 gen_set_cpsr(tmp, 0xffffffff);
6747 s->is_jmp = DISAS_UPDATE;
6756 /* branch (and link) */
6757 val = (int32_t)s->pc;
6758 if (insn & (1 << 24)) {
6760 tcg_gen_movi_i32(tmp, val);
6761 store_reg(s, 14, tmp);
6763 offset = (((int32_t)insn << 8) >> 8);
6764 val += (offset << 2) + 4;
6772 if (disas_coproc_insn(env, s, insn))
6777 gen_set_pc_im(s->pc);
6778 s->is_jmp = DISAS_SWI;
6782 gen_set_condexec(s);
6783 gen_set_pc_im(s->pc - 4);
6784 gen_exception(EXCP_UDEF);
6785 s->is_jmp = DISAS_JUMP;
6791 /* Return true if this is a Thumb-2 logical op. */
6793 thumb2_logic_op(int op)
6798 /* Generate code for a Thumb-2 data processing operation. If CONDS is nonzero
6799 then set condition code flags based on the result of the operation.
6800 If SHIFTER_OUT is nonzero then set the carry flag for logical operations
6801 to the high bit of T1.
6802 Returns zero if the opcode is valid. */
6805 gen_thumb2_data_op(DisasContext *s, int op, int conds, uint32_t shifter_out)
6812 gen_op_andl_T0_T1();
6816 gen_op_bicl_T0_T1();
6829 gen_op_xorl_T0_T1();
6834 gen_op_addl_T0_T1_cc();
6836 gen_op_addl_T0_T1();
6840 gen_op_adcl_T0_T1_cc();
6846 gen_op_sbcl_T0_T1_cc();
6852 gen_op_subl_T0_T1_cc();
6854 gen_op_subl_T0_T1();
6858 gen_op_rsbl_T0_T1_cc();
6860 gen_op_rsbl_T0_T1();
6862 default: /* 5, 6, 7, 9, 12, 15. */
6866 gen_op_logic_T0_cc();
6868 gen_set_CF_bit31(cpu_T[1]);
6873 /* Translate a 32-bit thumb instruction. Returns nonzero if the instruction
6875 static int disas_thumb2_insn(CPUState *env, DisasContext *s, uint16_t insn_hw1)
6877 uint32_t insn, imm, shift, offset;
6878 uint32_t rd, rn, rm, rs;
6888 if (!(arm_feature(env, ARM_FEATURE_THUMB2)
6889 || arm_feature (env, ARM_FEATURE_M))) {
6890 /* Thumb-1 cores may need to treat bl and blx as a pair of
6891 16-bit instructions to get correct prefetch abort behavior. */
6893 if ((insn & (1 << 12)) == 0) {
6894 /* Second half of blx. */
6895 offset = ((insn & 0x7ff) << 1);
6896 tmp = load_reg(s, 14);
6897 tcg_gen_addi_i32(tmp, tmp, offset);
6898 tcg_gen_andi_i32(tmp, tmp, 0xfffffffc);
6901 tcg_gen_movi_i32(tmp2, s->pc | 1);
6902 store_reg(s, 14, tmp2);
6906 if (insn & (1 << 11)) {
6907 /* Second half of bl. */
6908 offset = ((insn & 0x7ff) << 1) | 1;
6909 tmp = load_reg(s, 14);
6910 tcg_gen_addi_i32(tmp, tmp, offset);
6913 tcg_gen_movi_i32(tmp2, s->pc | 1);
6914 store_reg(s, 14, tmp2);
6918 if ((s->pc & ~TARGET_PAGE_MASK) == 0) {
6919 /* Instruction spans a page boundary. Implement it as two
6920 16-bit instructions in case the second half causes an
6922 offset = ((int32_t)insn << 21) >> 9;
6923 gen_op_movl_T0_im(s->pc + 2 + offset);
6924 gen_movl_reg_T0(s, 14);
6927 /* Fall through to 32-bit decode. */
6930 insn = lduw_code(s->pc);
6932 insn |= (uint32_t)insn_hw1 << 16;
6934 if ((insn & 0xf800e800) != 0xf000e800) {
6938 rn = (insn >> 16) & 0xf;
6939 rs = (insn >> 12) & 0xf;
6940 rd = (insn >> 8) & 0xf;
6942 switch ((insn >> 25) & 0xf) {
6943 case 0: case 1: case 2: case 3:
6944 /* 16-bit instructions. Should never happen. */
6947 if (insn & (1 << 22)) {
6948 /* Other load/store, table branch. */
6949 if (insn & 0x01200000) {
6950 /* Load/store doubleword. */
6953 tcg_gen_movi_i32(addr, s->pc & ~3);
6955 addr = load_reg(s, rn);
6957 offset = (insn & 0xff) * 4;
6958 if ((insn & (1 << 23)) == 0)
6960 if (insn & (1 << 24)) {
6961 tcg_gen_addi_i32(addr, addr, offset);
6964 if (insn & (1 << 20)) {
6966 tmp = gen_ld32(addr, IS_USER(s));
6967 store_reg(s, rs, tmp);
6968 tcg_gen_addi_i32(addr, addr, 4);
6969 tmp = gen_ld32(addr, IS_USER(s));
6970 store_reg(s, rd, tmp);
6973 tmp = load_reg(s, rs);
6974 gen_st32(tmp, addr, IS_USER(s));
6975 tcg_gen_addi_i32(addr, addr, 4);
6976 tmp = load_reg(s, rd);
6977 gen_st32(tmp, addr, IS_USER(s));
6979 if (insn & (1 << 21)) {
6980 /* Base writeback. */
6983 tcg_gen_addi_i32(addr, addr, offset - 4);
6984 store_reg(s, rn, addr);
6988 } else if ((insn & (1 << 23)) == 0) {
6989 /* Load/store exclusive word. */
6990 gen_movl_T1_reg(s, rn);
6992 if (insn & (1 << 20)) {
6993 gen_helper_mark_exclusive(cpu_env, cpu_T[1]);
6994 tmp = gen_ld32(addr, IS_USER(s));
6995 store_reg(s, rd, tmp);
6997 int label = gen_new_label();
6998 gen_helper_test_exclusive(cpu_T[0], cpu_env, addr);
6999 tcg_gen_brcond_i32(TCG_COND_NE, cpu_T[0],
7000 tcg_const_i32(0), label);
7001 tmp = load_reg(s, rs);
7002 gen_st32(tmp, cpu_T[1], IS_USER(s));
7003 gen_set_label(label);
7004 gen_movl_reg_T0(s, rd);
7006 } else if ((insn & (1 << 6)) == 0) {
7010 tcg_gen_movi_i32(addr, s->pc);
7012 addr = load_reg(s, rn);
7014 tmp = load_reg(s, rm);
7015 tcg_gen_add_i32(addr, addr, tmp);
7016 if (insn & (1 << 4)) {
7018 tcg_gen_add_i32(addr, addr, tmp);
7020 tmp = gen_ld16u(addr, IS_USER(s));
7023 tmp = gen_ld8u(addr, IS_USER(s));
7026 tcg_gen_shli_i32(tmp, tmp, 1);
7027 tcg_gen_addi_i32(tmp, tmp, s->pc);
7028 store_reg(s, 15, tmp);
7030 /* Load/store exclusive byte/halfword/doubleword. */
7031 /* ??? These are not really atomic. However we know
7032 we never have multiple CPUs running in parallel,
7033 so it is good enough. */
7034 op = (insn >> 4) & 0x3;
7035 /* Must use a global reg for the address because we have
7036 a conditional branch in the store instruction. */
7037 gen_movl_T1_reg(s, rn);
7039 if (insn & (1 << 20)) {
7040 gen_helper_mark_exclusive(cpu_env, addr);
7043 tmp = gen_ld8u(addr, IS_USER(s));
7046 tmp = gen_ld16u(addr, IS_USER(s));
7049 tmp = gen_ld32(addr, IS_USER(s));
7050 tcg_gen_addi_i32(addr, addr, 4);
7051 tmp2 = gen_ld32(addr, IS_USER(s));
7052 store_reg(s, rd, tmp2);
7057 store_reg(s, rs, tmp);
7059 int label = gen_new_label();
7060 /* Must use a global that is not killed by the branch. */
7061 gen_helper_test_exclusive(cpu_T[0], cpu_env, addr);
7062 tcg_gen_brcond_i32(TCG_COND_NE, cpu_T[0], tcg_const_i32(0),
7064 tmp = load_reg(s, rs);
7067 gen_st8(tmp, addr, IS_USER(s));
7070 gen_st16(tmp, addr, IS_USER(s));
7073 gen_st32(tmp, addr, IS_USER(s));
7074 tcg_gen_addi_i32(addr, addr, 4);
7075 tmp = load_reg(s, rd);
7076 gen_st32(tmp, addr, IS_USER(s));
7081 gen_set_label(label);
7082 gen_movl_reg_T0(s, rm);
7086 /* Load/store multiple, RFE, SRS. */
7087 if (((insn >> 23) & 1) == ((insn >> 24) & 1)) {
7088 /* Not available in user mode. */
7091 if (insn & (1 << 20)) {
7093 addr = load_reg(s, rn);
7094 if ((insn & (1 << 24)) == 0)
7095 tcg_gen_addi_i32(addr, addr, -8);
7096 /* Load PC into tmp and CPSR into tmp2. */
7097 tmp = gen_ld32(addr, 0);
7098 tcg_gen_addi_i32(addr, addr, 4);
7099 tmp2 = gen_ld32(addr, 0);
7100 if (insn & (1 << 21)) {
7101 /* Base writeback. */
7102 if (insn & (1 << 24)) {
7103 tcg_gen_addi_i32(addr, addr, 4);
7105 tcg_gen_addi_i32(addr, addr, -4);
7107 store_reg(s, rn, addr);
7111 gen_rfe(s, tmp, tmp2);
7115 if (op == (env->uncached_cpsr & CPSR_M)) {
7116 addr = load_reg(s, 13);
7119 gen_helper_get_r13_banked(addr, cpu_env, tcg_const_i32(op));
7121 if ((insn & (1 << 24)) == 0) {
7122 tcg_gen_addi_i32(addr, addr, -8);
7124 tmp = load_reg(s, 14);
7125 gen_st32(tmp, addr, 0);
7126 tcg_gen_addi_i32(addr, addr, 4);
7128 gen_helper_cpsr_read(tmp);
7129 gen_st32(tmp, addr, 0);
7130 if (insn & (1 << 21)) {
7131 if ((insn & (1 << 24)) == 0) {
7132 tcg_gen_addi_i32(addr, addr, -4);
7134 tcg_gen_addi_i32(addr, addr, 4);
7136 if (op == (env->uncached_cpsr & CPSR_M)) {
7137 store_reg(s, 13, addr);
7139 gen_helper_set_r13_banked(cpu_env,
7140 tcg_const_i32(op), addr);
7148 /* Load/store multiple. */
7149 addr = load_reg(s, rn);
7151 for (i = 0; i < 16; i++) {
7152 if (insn & (1 << i))
7155 if (insn & (1 << 24)) {
7156 tcg_gen_addi_i32(addr, addr, -offset);
7159 for (i = 0; i < 16; i++) {
7160 if ((insn & (1 << i)) == 0)
7162 if (insn & (1 << 20)) {
7164 tmp = gen_ld32(addr, IS_USER(s));
7168 store_reg(s, i, tmp);
7172 tmp = load_reg(s, i);
7173 gen_st32(tmp, addr, IS_USER(s));
7175 tcg_gen_addi_i32(addr, addr, 4);
7177 if (insn & (1 << 21)) {
7178 /* Base register writeback. */
7179 if (insn & (1 << 24)) {
7180 tcg_gen_addi_i32(addr, addr, -offset);
7182 /* Fault if writeback register is in register list. */
7183 if (insn & (1 << rn))
7185 store_reg(s, rn, addr);
7192 case 5: /* Data processing register constant shift. */
7194 gen_op_movl_T0_im(0);
7196 gen_movl_T0_reg(s, rn);
7197 gen_movl_T1_reg(s, rm);
7198 op = (insn >> 21) & 0xf;
7199 shiftop = (insn >> 4) & 3;
7200 shift = ((insn >> 6) & 3) | ((insn >> 10) & 0x1c);
7201 conds = (insn & (1 << 20)) != 0;
7202 logic_cc = (conds && thumb2_logic_op(op));
7203 gen_arm_shift_im(cpu_T[1], shiftop, shift, logic_cc);
7204 if (gen_thumb2_data_op(s, op, conds, 0))
7207 gen_movl_reg_T0(s, rd);
7209 case 13: /* Misc data processing. */
7210 op = ((insn >> 22) & 6) | ((insn >> 7) & 1);
7211 if (op < 4 && (insn & 0xf000) != 0xf000)
7214 case 0: /* Register controlled shift. */
7215 tmp = load_reg(s, rn);
7216 tmp2 = load_reg(s, rm);
7217 if ((insn & 0x70) != 0)
7219 op = (insn >> 21) & 3;
7220 logic_cc = (insn & (1 << 20)) != 0;
7221 gen_arm_shift_reg(tmp, op, tmp2, logic_cc);
7224 store_reg(s, rd, tmp);
7226 case 1: /* Sign/zero extend. */
7227 tmp = load_reg(s, rm);
7228 shift = (insn >> 4) & 3;
7229 /* ??? In many cases it's not neccessary to do a
7230 rotate, a shift is sufficient. */
7232 tcg_gen_rori_i32(tmp, tmp, shift * 8);
7233 op = (insn >> 20) & 7;
7235 case 0: gen_sxth(tmp); break;
7236 case 1: gen_uxth(tmp); break;
7237 case 2: gen_sxtb16(tmp); break;
7238 case 3: gen_uxtb16(tmp); break;
7239 case 4: gen_sxtb(tmp); break;
7240 case 5: gen_uxtb(tmp); break;
7241 default: goto illegal_op;
7244 tmp2 = load_reg(s, rn);
7245 if ((op >> 1) == 1) {
7246 gen_add16(tmp, tmp2);
7248 tcg_gen_add_i32(tmp, tmp, tmp2);
7252 store_reg(s, rd, tmp);
7254 case 2: /* SIMD add/subtract. */
7255 op = (insn >> 20) & 7;
7256 shift = (insn >> 4) & 7;
7257 if ((op & 3) == 3 || (shift & 3) == 3)
7259 tmp = load_reg(s, rn);
7260 tmp2 = load_reg(s, rm);
7261 gen_thumb2_parallel_addsub(op, shift, tmp, tmp2);
7263 store_reg(s, rd, tmp);
7265 case 3: /* Other data processing. */
7266 op = ((insn >> 17) & 0x38) | ((insn >> 4) & 7);
7268 /* Saturating add/subtract. */
7269 tmp = load_reg(s, rn);
7270 tmp2 = load_reg(s, rm);
7272 gen_helper_double_saturate(tmp, tmp);
7274 gen_helper_sub_saturate(tmp, tmp2, tmp);
7276 gen_helper_add_saturate(tmp, tmp, tmp2);
7279 tmp = load_reg(s, rn);
7281 case 0x0a: /* rbit */
7282 gen_helper_rbit(tmp, tmp);
7284 case 0x08: /* rev */
7285 tcg_gen_bswap_i32(tmp, tmp);
7287 case 0x09: /* rev16 */
7290 case 0x0b: /* revsh */
7293 case 0x10: /* sel */
7294 tmp2 = load_reg(s, rm);
7296 tcg_gen_ld_i32(tmp3, cpu_env, offsetof(CPUState, GE));
7297 gen_helper_sel_flags(tmp, tmp3, tmp, tmp2);
7301 case 0x18: /* clz */
7302 gen_helper_clz(tmp, tmp);
7308 store_reg(s, rd, tmp);
7310 case 4: case 5: /* 32-bit multiply. Sum of absolute differences. */
7311 op = (insn >> 4) & 0xf;
7312 tmp = load_reg(s, rn);
7313 tmp2 = load_reg(s, rm);
7314 switch ((insn >> 20) & 7) {
7315 case 0: /* 32 x 32 -> 32 */
7316 tcg_gen_mul_i32(tmp, tmp, tmp2);
7319 tmp2 = load_reg(s, rs);
7321 tcg_gen_sub_i32(tmp, tmp2, tmp);
7323 tcg_gen_add_i32(tmp, tmp, tmp2);
7327 case 1: /* 16 x 16 -> 32 */
7328 gen_mulxy(tmp, tmp2, op & 2, op & 1);
7331 tmp2 = load_reg(s, rs);
7332 gen_helper_add_setq(tmp, tmp, tmp2);
7336 case 2: /* Dual multiply add. */
7337 case 4: /* Dual multiply subtract. */
7339 gen_swap_half(tmp2);
7340 gen_smul_dual(tmp, tmp2);
7341 /* This addition cannot overflow. */
7342 if (insn & (1 << 22)) {
7343 tcg_gen_sub_i32(tmp, tmp, tmp2);
7345 tcg_gen_add_i32(tmp, tmp, tmp2);
7350 tmp2 = load_reg(s, rs);
7351 gen_helper_add_setq(tmp, tmp, tmp2);
7355 case 3: /* 32 * 16 -> 32msb */
7357 tcg_gen_sari_i32(tmp2, tmp2, 16);
7360 tmp2 = gen_muls_i64_i32(tmp, tmp2);
7361 tcg_gen_shri_i64(tmp2, tmp2, 16);
7363 tcg_gen_trunc_i64_i32(tmp, tmp2);
7366 tmp2 = load_reg(s, rs);
7367 gen_helper_add_setq(tmp, tmp, tmp2);
7371 case 5: case 6: /* 32 * 32 -> 32msb */
7372 gen_imull(tmp, tmp2);
7373 if (insn & (1 << 5)) {
7374 gen_roundqd(tmp, tmp2);
7381 tmp2 = load_reg(s, rs);
7382 if (insn & (1 << 21)) {
7383 tcg_gen_add_i32(tmp, tmp, tmp2);
7385 tcg_gen_sub_i32(tmp, tmp2, tmp);
7390 case 7: /* Unsigned sum of absolute differences. */
7391 gen_helper_usad8(tmp, tmp, tmp2);
7394 tmp2 = load_reg(s, rs);
7395 tcg_gen_add_i32(tmp, tmp, tmp2);
7400 store_reg(s, rd, tmp);
7402 case 6: case 7: /* 64-bit multiply, Divide. */
7403 op = ((insn >> 4) & 0xf) | ((insn >> 16) & 0x70);
7404 tmp = load_reg(s, rn);
7405 tmp2 = load_reg(s, rm);
7406 if ((op & 0x50) == 0x10) {
7408 if (!arm_feature(env, ARM_FEATURE_DIV))
7411 gen_helper_udiv(tmp, tmp, tmp2);
7413 gen_helper_sdiv(tmp, tmp, tmp2);
7415 store_reg(s, rd, tmp);
7416 } else if ((op & 0xe) == 0xc) {
7417 /* Dual multiply accumulate long. */
7419 gen_swap_half(tmp2);
7420 gen_smul_dual(tmp, tmp2);
7422 tcg_gen_sub_i32(tmp, tmp, tmp2);
7424 tcg_gen_add_i32(tmp, tmp, tmp2);
7427 tmp2 = tcg_temp_new(TCG_TYPE_I64);
7428 gen_addq(s, tmp, rs, rd);
7429 gen_storeq_reg(s, rs, rd, tmp);
7432 /* Unsigned 64-bit multiply */
7433 tmp = gen_mulu_i64_i32(tmp, tmp2);
7437 gen_mulxy(tmp, tmp2, op & 2, op & 1);
7439 tmp2 = tcg_temp_new(TCG_TYPE_I64);
7440 tcg_gen_ext_i32_i64(tmp2, tmp);
7444 /* Signed 64-bit multiply */
7445 tmp = gen_muls_i64_i32(tmp, tmp2);
7450 gen_addq_lo(s, tmp, rs);
7451 gen_addq_lo(s, tmp, rd);
7452 } else if (op & 0x40) {
7453 /* 64-bit accumulate. */
7454 gen_addq(s, tmp, rs, rd);
7456 gen_storeq_reg(s, rs, rd, tmp);
7461 case 6: case 7: case 14: case 15:
7463 if (((insn >> 24) & 3) == 3) {
7464 /* Translate into the equivalent ARM encoding. */
7465 insn = (insn & 0xe2ffffff) | ((insn & (1 << 28)) >> 4);
7466 if (disas_neon_data_insn(env, s, insn))
7469 if (insn & (1 << 28))
7471 if (disas_coproc_insn (env, s, insn))
7475 case 8: case 9: case 10: case 11:
7476 if (insn & (1 << 15)) {
7477 /* Branches, misc control. */
7478 if (insn & 0x5000) {
7479 /* Unconditional branch. */
7480 /* signextend(hw1[10:0]) -> offset[:12]. */
7481 offset = ((int32_t)insn << 5) >> 9 & ~(int32_t)0xfff;
7482 /* hw1[10:0] -> offset[11:1]. */
7483 offset |= (insn & 0x7ff) << 1;
7484 /* (~hw2[13, 11] ^ offset[24]) -> offset[23,22]
7485 offset[24:22] already have the same value because of the
7486 sign extension above. */
7487 offset ^= ((~insn) & (1 << 13)) << 10;
7488 offset ^= ((~insn) & (1 << 11)) << 11;
7490 if (insn & (1 << 14)) {
7491 /* Branch and link. */
7492 gen_op_movl_T1_im(s->pc | 1);
7493 gen_movl_reg_T1(s, 14);
7497 if (insn & (1 << 12)) {
7502 offset &= ~(uint32_t)2;
7503 gen_bx_im(s, offset);
7505 } else if (((insn >> 23) & 7) == 7) {
7507 if (insn & (1 << 13))
7510 if (insn & (1 << 26)) {
7511 /* Secure monitor call (v6Z) */
7512 goto illegal_op; /* not implemented. */
7514 op = (insn >> 20) & 7;
7516 case 0: /* msr cpsr. */
7518 tmp = load_reg(s, rn);
7519 addr = tcg_const_i32(insn & 0xff);
7520 gen_helper_v7m_msr(cpu_env, addr, tmp);
7525 case 1: /* msr spsr. */
7528 gen_movl_T0_reg(s, rn);
7529 if (gen_set_psr_T0(s,
7530 msr_mask(env, s, (insn >> 8) & 0xf, op == 1),
7534 case 2: /* cps, nop-hint. */
7535 if (((insn >> 8) & 7) == 0) {
7536 gen_nop_hint(s, insn & 0xff);
7538 /* Implemented as NOP in user mode. */
7543 if (insn & (1 << 10)) {
7544 if (insn & (1 << 7))
7546 if (insn & (1 << 6))
7548 if (insn & (1 << 5))
7550 if (insn & (1 << 9))
7551 imm = CPSR_A | CPSR_I | CPSR_F;
7553 if (insn & (1 << 8)) {
7555 imm |= (insn & 0x1f);
7558 gen_op_movl_T0_im(imm);
7559 gen_set_psr_T0(s, offset, 0);
7562 case 3: /* Special control operations. */
7563 op = (insn >> 4) & 0xf;
7566 gen_helper_clrex(cpu_env);
7571 /* These execute as NOPs. */
7579 /* Trivial implementation equivalent to bx. */
7580 tmp = load_reg(s, rn);
7583 case 5: /* Exception return. */
7584 /* Unpredictable in user mode. */
7586 case 6: /* mrs cpsr. */
7589 addr = tcg_const_i32(insn & 0xff);
7590 gen_helper_v7m_mrs(tmp, cpu_env, addr);
7592 gen_helper_cpsr_read(tmp);
7594 store_reg(s, rd, tmp);
7596 case 7: /* mrs spsr. */
7597 /* Not accessible in user mode. */
7598 if (IS_USER(s) || IS_M(env))
7600 tmp = load_cpu_field(spsr);
7601 store_reg(s, rd, tmp);
7606 /* Conditional branch. */
7607 op = (insn >> 22) & 0xf;
7608 /* Generate a conditional jump to next instruction. */
7609 s->condlabel = gen_new_label();
7610 gen_test_cc(op ^ 1, s->condlabel);
7613 /* offset[11:1] = insn[10:0] */
7614 offset = (insn & 0x7ff) << 1;
7615 /* offset[17:12] = insn[21:16]. */
7616 offset |= (insn & 0x003f0000) >> 4;
7617 /* offset[31:20] = insn[26]. */
7618 offset |= ((int32_t)((insn << 5) & 0x80000000)) >> 11;
7619 /* offset[18] = insn[13]. */
7620 offset |= (insn & (1 << 13)) << 5;
7621 /* offset[19] = insn[11]. */
7622 offset |= (insn & (1 << 11)) << 8;
7624 /* jump to the offset */
7625 gen_jmp(s, s->pc + offset);
7628 /* Data processing immediate. */
7629 if (insn & (1 << 25)) {
7630 if (insn & (1 << 24)) {
7631 if (insn & (1 << 20))
7633 /* Bitfield/Saturate. */
7634 op = (insn >> 21) & 7;
7636 shift = ((insn >> 6) & 3) | ((insn >> 10) & 0x1c);
7639 tcg_gen_movi_i32(tmp, 0);
7641 tmp = load_reg(s, rn);
7644 case 2: /* Signed bitfield extract. */
7646 if (shift + imm > 32)
7649 gen_sbfx(tmp, shift, imm);
7651 case 6: /* Unsigned bitfield extract. */
7653 if (shift + imm > 32)
7656 gen_ubfx(tmp, shift, (1u << imm) - 1);
7658 case 3: /* Bitfield insert/clear. */
7661 imm = imm + 1 - shift;
7663 tmp2 = load_reg(s, rd);
7664 gen_bfi(tmp, tmp2, tmp, shift, (1u << imm) - 1);
7670 default: /* Saturate. */
7673 tcg_gen_sari_i32(tmp, tmp, shift);
7675 tcg_gen_shli_i32(tmp, tmp, shift);
7677 tmp2 = tcg_const_i32(imm);
7680 if ((op & 1) && shift == 0)
7681 gen_helper_usat16(tmp, tmp, tmp2);
7683 gen_helper_usat(tmp, tmp, tmp2);
7686 if ((op & 1) && shift == 0)
7687 gen_helper_ssat16(tmp, tmp, tmp2);
7689 gen_helper_ssat(tmp, tmp, tmp2);
7693 store_reg(s, rd, tmp);
7695 imm = ((insn & 0x04000000) >> 15)
7696 | ((insn & 0x7000) >> 4) | (insn & 0xff);
7697 if (insn & (1 << 22)) {
7698 /* 16-bit immediate. */
7699 imm |= (insn >> 4) & 0xf000;
7700 if (insn & (1 << 23)) {
7702 tmp = load_reg(s, rd);
7703 tcg_gen_andi_i32(tmp, tmp, 0xffff);
7704 tcg_gen_ori_i32(tmp, tmp, imm << 16);
7708 tcg_gen_movi_i32(tmp, imm);
7711 /* Add/sub 12-bit immediate. */
7713 offset = s->pc & ~(uint32_t)3;
7714 if (insn & (1 << 23))
7719 tcg_gen_movi_i32(tmp, offset);
7721 tmp = load_reg(s, rn);
7722 if (insn & (1 << 23))
7723 tcg_gen_subi_i32(tmp, tmp, imm);
7725 tcg_gen_addi_i32(tmp, tmp, imm);
7728 store_reg(s, rd, tmp);
7731 int shifter_out = 0;
7732 /* modified 12-bit immediate. */
7733 shift = ((insn & 0x04000000) >> 23) | ((insn & 0x7000) >> 12);
7734 imm = (insn & 0xff);
7737 /* Nothing to do. */
7739 case 1: /* 00XY00XY */
7742 case 2: /* XY00XY00 */
7746 case 3: /* XYXYXYXY */
7750 default: /* Rotated constant. */
7751 shift = (shift << 1) | (imm >> 7);
7753 imm = imm << (32 - shift);
7757 gen_op_movl_T1_im(imm);
7758 rn = (insn >> 16) & 0xf;
7760 gen_op_movl_T0_im(0);
7762 gen_movl_T0_reg(s, rn);
7763 op = (insn >> 21) & 0xf;
7764 if (gen_thumb2_data_op(s, op, (insn & (1 << 20)) != 0,
7767 rd = (insn >> 8) & 0xf;
7769 gen_movl_reg_T0(s, rd);
7774 case 12: /* Load/store single data item. */
7779 if ((insn & 0x01100000) == 0x01000000) {
7780 if (disas_neon_ls_insn(env, s, insn))
7788 /* s->pc has already been incremented by 4. */
7789 imm = s->pc & 0xfffffffc;
7790 if (insn & (1 << 23))
7791 imm += insn & 0xfff;
7793 imm -= insn & 0xfff;
7794 tcg_gen_movi_i32(addr, imm);
7796 addr = load_reg(s, rn);
7797 if (insn & (1 << 23)) {
7798 /* Positive offset. */
7800 tcg_gen_addi_i32(addr, addr, imm);
7802 op = (insn >> 8) & 7;
7805 case 0: case 8: /* Shifted Register. */
7806 shift = (insn >> 4) & 0xf;
7809 tmp = load_reg(s, rm);
7811 tcg_gen_shli_i32(tmp, tmp, shift);
7812 tcg_gen_add_i32(addr, addr, tmp);
7815 case 4: /* Negative offset. */
7816 tcg_gen_addi_i32(addr, addr, -imm);
7818 case 6: /* User privilege. */
7819 tcg_gen_addi_i32(addr, addr, imm);
7822 case 1: /* Post-decrement. */
7825 case 3: /* Post-increment. */
7829 case 5: /* Pre-decrement. */
7832 case 7: /* Pre-increment. */
7833 tcg_gen_addi_i32(addr, addr, imm);
7841 op = ((insn >> 21) & 3) | ((insn >> 22) & 4);
7842 if (insn & (1 << 20)) {
7844 if (rs == 15 && op != 2) {
7847 /* Memory hint. Implemented as NOP. */
7850 case 0: tmp = gen_ld8u(addr, user); break;
7851 case 4: tmp = gen_ld8s(addr, user); break;
7852 case 1: tmp = gen_ld16u(addr, user); break;
7853 case 5: tmp = gen_ld16s(addr, user); break;
7854 case 2: tmp = gen_ld32(addr, user); break;
7855 default: goto illegal_op;
7860 store_reg(s, rs, tmp);
7867 tmp = load_reg(s, rs);
7869 case 0: gen_st8(tmp, addr, user); break;
7870 case 1: gen_st16(tmp, addr, user); break;
7871 case 2: gen_st32(tmp, addr, user); break;
7872 default: goto illegal_op;
7876 tcg_gen_addi_i32(addr, addr, imm);
7878 store_reg(s, rn, addr);
7892 static void disas_thumb_insn(CPUState *env, DisasContext *s)
7894 uint32_t val, insn, op, rm, rn, rd, shift, cond;
7901 if (s->condexec_mask) {
7902 cond = s->condexec_cond;
7903 s->condlabel = gen_new_label();
7904 gen_test_cc(cond ^ 1, s->condlabel);
7908 insn = lduw_code(s->pc);
7911 switch (insn >> 12) {
7914 op = (insn >> 11) & 3;
7917 rn = (insn >> 3) & 7;
7918 gen_movl_T0_reg(s, rn);
7919 if (insn & (1 << 10)) {
7921 gen_op_movl_T1_im((insn >> 6) & 7);
7924 rm = (insn >> 6) & 7;
7925 gen_movl_T1_reg(s, rm);
7927 if (insn & (1 << 9)) {
7928 if (s->condexec_mask)
7929 gen_op_subl_T0_T1();
7931 gen_op_subl_T0_T1_cc();
7933 if (s->condexec_mask)
7934 gen_op_addl_T0_T1();
7936 gen_op_addl_T0_T1_cc();
7938 gen_movl_reg_T0(s, rd);
7940 /* shift immediate */
7941 rm = (insn >> 3) & 7;
7942 shift = (insn >> 6) & 0x1f;
7943 tmp = load_reg(s, rm);
7944 gen_arm_shift_im(tmp, op, shift, s->condexec_mask == 0);
7945 if (!s->condexec_mask)
7947 store_reg(s, rd, tmp);
7951 /* arithmetic large immediate */
7952 op = (insn >> 11) & 3;
7953 rd = (insn >> 8) & 0x7;
7955 gen_op_movl_T0_im(insn & 0xff);
7957 gen_movl_T0_reg(s, rd);
7958 gen_op_movl_T1_im(insn & 0xff);
7962 if (!s->condexec_mask)
7963 gen_op_logic_T0_cc();
7966 gen_op_subl_T0_T1_cc();
7969 if (s->condexec_mask)
7970 gen_op_addl_T0_T1();
7972 gen_op_addl_T0_T1_cc();
7975 if (s->condexec_mask)
7976 gen_op_subl_T0_T1();
7978 gen_op_subl_T0_T1_cc();
7982 gen_movl_reg_T0(s, rd);
7985 if (insn & (1 << 11)) {
7986 rd = (insn >> 8) & 7;
7987 /* load pc-relative. Bit 1 of PC is ignored. */
7988 val = s->pc + 2 + ((insn & 0xff) * 4);
7989 val &= ~(uint32_t)2;
7991 tcg_gen_movi_i32(addr, val);
7992 tmp = gen_ld32(addr, IS_USER(s));
7994 store_reg(s, rd, tmp);
7997 if (insn & (1 << 10)) {
7998 /* data processing extended or blx */
7999 rd = (insn & 7) | ((insn >> 4) & 8);
8000 rm = (insn >> 3) & 0xf;
8001 op = (insn >> 8) & 3;
8004 gen_movl_T0_reg(s, rd);
8005 gen_movl_T1_reg(s, rm);
8006 gen_op_addl_T0_T1();
8007 gen_movl_reg_T0(s, rd);
8010 gen_movl_T0_reg(s, rd);
8011 gen_movl_T1_reg(s, rm);
8012 gen_op_subl_T0_T1_cc();
8014 case 2: /* mov/cpy */
8015 gen_movl_T0_reg(s, rm);
8016 gen_movl_reg_T0(s, rd);
8018 case 3:/* branch [and link] exchange thumb register */
8019 tmp = load_reg(s, rm);
8020 if (insn & (1 << 7)) {
8021 val = (uint32_t)s->pc | 1;
8023 tcg_gen_movi_i32(tmp2, val);
8024 store_reg(s, 14, tmp2);
8032 /* data processing register */
8034 rm = (insn >> 3) & 7;
8035 op = (insn >> 6) & 0xf;
8036 if (op == 2 || op == 3 || op == 4 || op == 7) {
8037 /* the shift/rotate ops want the operands backwards */
8046 if (op == 9) /* neg */
8047 gen_op_movl_T0_im(0);
8048 else if (op != 0xf) /* mvn doesn't read its first operand */
8049 gen_movl_T0_reg(s, rd);
8051 gen_movl_T1_reg(s, rm);
8054 gen_op_andl_T0_T1();
8055 if (!s->condexec_mask)
8056 gen_op_logic_T0_cc();
8059 gen_op_xorl_T0_T1();
8060 if (!s->condexec_mask)
8061 gen_op_logic_T0_cc();
8064 if (s->condexec_mask) {
8065 gen_helper_shl(cpu_T[1], cpu_T[1], cpu_T[0]);
8067 gen_helper_shl_cc(cpu_T[1], cpu_T[1], cpu_T[0]);
8068 gen_op_logic_T1_cc();
8072 if (s->condexec_mask) {
8073 gen_helper_shr(cpu_T[1], cpu_T[1], cpu_T[0]);
8075 gen_helper_shr_cc(cpu_T[1], cpu_T[1], cpu_T[0]);
8076 gen_op_logic_T1_cc();
8080 if (s->condexec_mask) {
8081 gen_helper_sar(cpu_T[1], cpu_T[1], cpu_T[0]);
8083 gen_helper_sar_cc(cpu_T[1], cpu_T[1], cpu_T[0]);
8084 gen_op_logic_T1_cc();
8088 if (s->condexec_mask)
8091 gen_op_adcl_T0_T1_cc();
8094 if (s->condexec_mask)
8097 gen_op_sbcl_T0_T1_cc();
8100 if (s->condexec_mask) {
8101 gen_helper_ror(cpu_T[1], cpu_T[1], cpu_T[0]);
8103 gen_helper_ror_cc(cpu_T[1], cpu_T[1], cpu_T[0]);
8104 gen_op_logic_T1_cc();
8108 gen_op_andl_T0_T1();
8109 gen_op_logic_T0_cc();
8113 if (s->condexec_mask)
8114 gen_op_subl_T0_T1();
8116 gen_op_subl_T0_T1_cc();
8119 gen_op_subl_T0_T1_cc();
8123 gen_op_addl_T0_T1_cc();
8128 if (!s->condexec_mask)
8129 gen_op_logic_T0_cc();
8132 gen_op_mull_T0_T1();
8133 if (!s->condexec_mask)
8134 gen_op_logic_T0_cc();
8137 gen_op_bicl_T0_T1();
8138 if (!s->condexec_mask)
8139 gen_op_logic_T0_cc();
8143 if (!s->condexec_mask)
8144 gen_op_logic_T1_cc();
8151 gen_movl_reg_T1(s, rm);
8153 gen_movl_reg_T0(s, rd);
8158 /* load/store register offset. */
8160 rn = (insn >> 3) & 7;
8161 rm = (insn >> 6) & 7;
8162 op = (insn >> 9) & 7;
8163 addr = load_reg(s, rn);
8164 tmp = load_reg(s, rm);
8165 tcg_gen_add_i32(addr, addr, tmp);
8168 if (op < 3) /* store */
8169 tmp = load_reg(s, rd);
8173 gen_st32(tmp, addr, IS_USER(s));
8176 gen_st16(tmp, addr, IS_USER(s));
8179 gen_st8(tmp, addr, IS_USER(s));
8182 tmp = gen_ld8s(addr, IS_USER(s));
8185 tmp = gen_ld32(addr, IS_USER(s));
8188 tmp = gen_ld16u(addr, IS_USER(s));
8191 tmp = gen_ld8u(addr, IS_USER(s));
8194 tmp = gen_ld16s(addr, IS_USER(s));
8197 if (op >= 3) /* load */
8198 store_reg(s, rd, tmp);
8203 /* load/store word immediate offset */
8205 rn = (insn >> 3) & 7;
8206 addr = load_reg(s, rn);
8207 val = (insn >> 4) & 0x7c;
8208 tcg_gen_addi_i32(addr, addr, val);
8210 if (insn & (1 << 11)) {
8212 tmp = gen_ld32(addr, IS_USER(s));
8213 store_reg(s, rd, tmp);
8216 tmp = load_reg(s, rd);
8217 gen_st32(tmp, addr, IS_USER(s));
8223 /* load/store byte immediate offset */
8225 rn = (insn >> 3) & 7;
8226 addr = load_reg(s, rn);
8227 val = (insn >> 6) & 0x1f;
8228 tcg_gen_addi_i32(addr, addr, val);
8230 if (insn & (1 << 11)) {
8232 tmp = gen_ld8u(addr, IS_USER(s));
8233 store_reg(s, rd, tmp);
8236 tmp = load_reg(s, rd);
8237 gen_st8(tmp, addr, IS_USER(s));
8243 /* load/store halfword immediate offset */
8245 rn = (insn >> 3) & 7;
8246 addr = load_reg(s, rn);
8247 val = (insn >> 5) & 0x3e;
8248 tcg_gen_addi_i32(addr, addr, val);
8250 if (insn & (1 << 11)) {
8252 tmp = gen_ld16u(addr, IS_USER(s));
8253 store_reg(s, rd, tmp);
8256 tmp = load_reg(s, rd);
8257 gen_st16(tmp, addr, IS_USER(s));
8263 /* load/store from stack */
8264 rd = (insn >> 8) & 7;
8265 addr = load_reg(s, 13);
8266 val = (insn & 0xff) * 4;
8267 tcg_gen_addi_i32(addr, addr, val);
8269 if (insn & (1 << 11)) {
8271 tmp = gen_ld32(addr, IS_USER(s));
8272 store_reg(s, rd, tmp);
8275 tmp = load_reg(s, rd);
8276 gen_st32(tmp, addr, IS_USER(s));
8282 /* add to high reg */
8283 rd = (insn >> 8) & 7;
8284 if (insn & (1 << 11)) {
8286 tmp = load_reg(s, 13);
8288 /* PC. bit 1 is ignored. */
8290 tcg_gen_movi_i32(tmp, (s->pc + 2) & ~(uint32_t)2);
8292 val = (insn & 0xff) * 4;
8293 tcg_gen_addi_i32(tmp, tmp, val);
8294 store_reg(s, rd, tmp);
8299 op = (insn >> 8) & 0xf;
8302 /* adjust stack pointer */
8303 tmp = load_reg(s, 13);
8304 val = (insn & 0x7f) * 4;
8305 if (insn & (1 << 7))
8306 val = -(int32_t)val;
8307 tcg_gen_addi_i32(tmp, tmp, val);
8308 store_reg(s, 13, tmp);
8311 case 2: /* sign/zero extend. */
8314 rm = (insn >> 3) & 7;
8315 tmp = load_reg(s, rm);
8316 switch ((insn >> 6) & 3) {
8317 case 0: gen_sxth(tmp); break;
8318 case 1: gen_sxtb(tmp); break;
8319 case 2: gen_uxth(tmp); break;
8320 case 3: gen_uxtb(tmp); break;
8322 store_reg(s, rd, tmp);
8324 case 4: case 5: case 0xc: case 0xd:
8326 addr = load_reg(s, 13);
8327 if (insn & (1 << 8))
8331 for (i = 0; i < 8; i++) {
8332 if (insn & (1 << i))
8335 if ((insn & (1 << 11)) == 0) {
8336 tcg_gen_addi_i32(addr, addr, -offset);
8338 for (i = 0; i < 8; i++) {
8339 if (insn & (1 << i)) {
8340 if (insn & (1 << 11)) {
8342 tmp = gen_ld32(addr, IS_USER(s));
8343 store_reg(s, i, tmp);
8346 tmp = load_reg(s, i);
8347 gen_st32(tmp, addr, IS_USER(s));
8349 /* advance to the next address. */
8350 tcg_gen_addi_i32(addr, addr, 4);
8353 if (insn & (1 << 8)) {
8354 if (insn & (1 << 11)) {
8356 tmp = gen_ld32(addr, IS_USER(s));
8357 /* don't set the pc until the rest of the instruction
8361 tmp = load_reg(s, 14);
8362 gen_st32(tmp, addr, IS_USER(s));
8364 tcg_gen_addi_i32(addr, addr, 4);
8366 if ((insn & (1 << 11)) == 0) {
8367 tcg_gen_addi_i32(addr, addr, -offset);
8369 /* write back the new stack pointer */
8370 store_reg(s, 13, addr);
8371 /* set the new PC value */
8372 if ((insn & 0x0900) == 0x0900)
8376 case 1: case 3: case 9: case 11: /* czb */
8378 tmp = load_reg(s, rm);
8379 tmp2 = tcg_const_i32(0);
8380 s->condlabel = gen_new_label();
8382 if (insn & (1 << 11))
8383 tcg_gen_brcond_i32(TCG_COND_EQ, tmp, tmp2, s->condlabel);
8385 tcg_gen_brcond_i32(TCG_COND_NE, tmp, tmp2, s->condlabel);
8387 offset = ((insn & 0xf8) >> 2) | (insn & 0x200) >> 3;
8388 val = (uint32_t)s->pc + 2;
8393 case 15: /* IT, nop-hint. */
8394 if ((insn & 0xf) == 0) {
8395 gen_nop_hint(s, (insn >> 4) & 0xf);
8399 s->condexec_cond = (insn >> 4) & 0xe;
8400 s->condexec_mask = insn & 0x1f;
8401 /* No actual code generated for this insn, just setup state. */
8404 case 0xe: /* bkpt */
8405 gen_set_condexec(s);
8406 gen_set_pc_im(s->pc - 2);
8407 gen_exception(EXCP_BKPT);
8408 s->is_jmp = DISAS_JUMP;
8413 rn = (insn >> 3) & 0x7;
8415 tmp = load_reg(s, rn);
8416 switch ((insn >> 6) & 3) {
8417 case 0: tcg_gen_bswap_i32(tmp, tmp); break;
8418 case 1: gen_rev16(tmp); break;
8419 case 3: gen_revsh(tmp); break;
8420 default: goto illegal_op;
8422 store_reg(s, rd, tmp);
8430 tmp = tcg_const_i32((insn & (1 << 4)) != 0);
8433 addr = tcg_const_i32(16);
8434 gen_helper_v7m_msr(cpu_env, addr, tmp);
8438 addr = tcg_const_i32(17);
8439 gen_helper_v7m_msr(cpu_env, addr, tmp);
8443 if (insn & (1 << 4))
8444 shift = CPSR_A | CPSR_I | CPSR_F;
8448 val = ((insn & 7) << 6) & shift;
8449 gen_op_movl_T0_im(val);
8450 gen_set_psr_T0(s, shift, 0);
8460 /* load/store multiple */
8461 rn = (insn >> 8) & 0x7;
8462 addr = load_reg(s, rn);
8463 for (i = 0; i < 8; i++) {
8464 if (insn & (1 << i)) {
8465 if (insn & (1 << 11)) {
8467 tmp = gen_ld32(addr, IS_USER(s));
8468 store_reg(s, i, tmp);
8471 tmp = load_reg(s, i);
8472 gen_st32(tmp, addr, IS_USER(s));
8474 /* advance to the next address */
8475 tcg_gen_addi_i32(addr, addr, 4);
8478 /* Base register writeback. */
8479 if ((insn & (1 << rn)) == 0) {
8480 store_reg(s, rn, addr);
8487 /* conditional branch or swi */
8488 cond = (insn >> 8) & 0xf;
8494 gen_set_condexec(s);
8495 gen_set_pc_im(s->pc);
8496 s->is_jmp = DISAS_SWI;
8499 /* generate a conditional jump to next instruction */
8500 s->condlabel = gen_new_label();
8501 gen_test_cc(cond ^ 1, s->condlabel);
8503 gen_movl_T1_reg(s, 15);
8505 /* jump to the offset */
8506 val = (uint32_t)s->pc + 2;
8507 offset = ((int32_t)insn << 24) >> 24;
8513 if (insn & (1 << 11)) {
8514 if (disas_thumb2_insn(env, s, insn))
8518 /* unconditional branch */
8519 val = (uint32_t)s->pc;
8520 offset = ((int32_t)insn << 21) >> 21;
8521 val += (offset << 1) + 2;
8526 if (disas_thumb2_insn(env, s, insn))
8532 gen_set_condexec(s);
8533 gen_set_pc_im(s->pc - 4);
8534 gen_exception(EXCP_UDEF);
8535 s->is_jmp = DISAS_JUMP;
8539 gen_set_condexec(s);
8540 gen_set_pc_im(s->pc - 2);
8541 gen_exception(EXCP_UDEF);
8542 s->is_jmp = DISAS_JUMP;
8545 /* generate intermediate code in gen_opc_buf and gen_opparam_buf for
8546 basic block 'tb'. If search_pc is TRUE, also generate PC
8547 information for each intermediate instruction. */
8548 static inline int gen_intermediate_code_internal(CPUState *env,
8549 TranslationBlock *tb,
8552 DisasContext dc1, *dc = &dc1;
8553 uint16_t *gen_opc_end;
8555 target_ulong pc_start;
8556 uint32_t next_page_start;
8558 /* generate intermediate code */
8560 memset(temps, 0, sizeof(temps));
8566 gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
8568 dc->is_jmp = DISAS_NEXT;
8570 dc->singlestep_enabled = env->singlestep_enabled;
8572 dc->thumb = env->thumb;
8573 dc->condexec_mask = (env->condexec_bits & 0xf) << 1;
8574 dc->condexec_cond = env->condexec_bits >> 4;
8576 #if !defined(CONFIG_USER_ONLY)
8578 dc->user = ((env->v7m.exception == 0) && (env->v7m.control & 1));
8580 dc->user = (env->uncached_cpsr & 0x1f) == ARM_CPU_MODE_USR;
8583 cpu_F0s = tcg_temp_new(TCG_TYPE_I32);
8584 cpu_F1s = tcg_temp_new(TCG_TYPE_I32);
8585 cpu_F0d = tcg_temp_new(TCG_TYPE_I64);
8586 cpu_F1d = tcg_temp_new(TCG_TYPE_I64);
8589 /* FIXME: cpu_M0 can probably be the same as cpu_V0. */
8590 cpu_M0 = tcg_temp_new(TCG_TYPE_I64);
8591 next_page_start = (pc_start & TARGET_PAGE_MASK) + TARGET_PAGE_SIZE;
8593 /* Reset the conditional execution bits immediately. This avoids
8594 complications trying to do it at the end of the block. */
8595 if (env->condexec_bits)
8597 TCGv tmp = new_tmp();
8598 tcg_gen_movi_i32(tmp, 0);
8599 store_cpu_field(tmp, condexec_bits);
8602 #ifndef CONFIG_USER_ONLY
8603 if (dc->pc >= 0xfffffff0 && IS_M(env)) {
8604 /* We always get here via a jump, so know we are not in a
8605 conditional execution block. */
8606 gen_exception(EXCP_EXCEPTION_EXIT);
8610 if (env->nb_breakpoints > 0) {
8611 for(j = 0; j < env->nb_breakpoints; j++) {
8612 if (env->breakpoints[j] == dc->pc) {
8613 gen_set_condexec(dc);
8614 gen_set_pc_im(dc->pc);
8615 gen_exception(EXCP_DEBUG);
8616 dc->is_jmp = DISAS_JUMP;
8617 /* Advance PC so that clearing the breakpoint will
8618 invalidate this TB. */
8620 goto done_generating;
8626 j = gen_opc_ptr - gen_opc_buf;
8630 gen_opc_instr_start[lj++] = 0;
8632 gen_opc_pc[lj] = dc->pc;
8633 gen_opc_instr_start[lj] = 1;
8637 disas_thumb_insn(env, dc);
8638 if (dc->condexec_mask) {
8639 dc->condexec_cond = (dc->condexec_cond & 0xe)
8640 | ((dc->condexec_mask >> 4) & 1);
8641 dc->condexec_mask = (dc->condexec_mask << 1) & 0x1f;
8642 if (dc->condexec_mask == 0) {
8643 dc->condexec_cond = 0;
8647 disas_arm_insn(env, dc);
8650 fprintf(stderr, "Internal resource leak before %08x\n", dc->pc);
8654 if (dc->condjmp && !dc->is_jmp) {
8655 gen_set_label(dc->condlabel);
8658 /* Terminate the TB on memory ops if watchpoints are present. */
8659 /* FIXME: This should be replacd by the deterministic execution
8660 * IRQ raising bits. */
8661 if (dc->is_mem && env->nb_watchpoints)
8664 /* Translation stops when a conditional branch is enoutered.
8665 * Otherwise the subsequent code could get translated several times.
8666 * Also stop translation when a page boundary is reached. This
8667 * ensures prefech aborts occur at the right place. */
8668 } while (!dc->is_jmp && gen_opc_ptr < gen_opc_end &&
8669 !env->singlestep_enabled &&
8670 dc->pc < next_page_start);
8672 /* At this stage dc->condjmp will only be set when the skipped
8673 instruction was a conditional branch or trap, and the PC has
8674 already been written. */
8675 if (__builtin_expect(env->singlestep_enabled, 0)) {
8676 /* Make sure the pc is updated, and raise a debug exception. */
8678 gen_set_condexec(dc);
8679 if (dc->is_jmp == DISAS_SWI) {
8680 gen_exception(EXCP_SWI);
8682 gen_exception(EXCP_DEBUG);
8684 gen_set_label(dc->condlabel);
8686 if (dc->condjmp || !dc->is_jmp) {
8687 gen_set_pc_im(dc->pc);
8690 gen_set_condexec(dc);
8691 if (dc->is_jmp == DISAS_SWI && !dc->condjmp) {
8692 gen_exception(EXCP_SWI);
8694 /* FIXME: Single stepping a WFI insn will not halt
8696 gen_exception(EXCP_DEBUG);
8699 /* While branches must always occur at the end of an IT block,
8700 there are a few other things that can cause us to terminate
8701 the TB in the middel of an IT block:
8702 - Exception generating instructions (bkpt, swi, undefined).
8704 - Hardware watchpoints.
8705 Hardware breakpoints have already been handled and skip this code.
8707 gen_set_condexec(dc);
8708 switch(dc->is_jmp) {
8710 gen_goto_tb(dc, 1, dc->pc);
8715 /* indicate that the hash table must be used to find the next TB */
8719 /* nothing more to generate */
8725 gen_exception(EXCP_SWI);
8729 gen_set_label(dc->condlabel);
8730 gen_set_condexec(dc);
8731 gen_goto_tb(dc, 1, dc->pc);
8736 *gen_opc_ptr = INDEX_op_end;
8739 if (loglevel & CPU_LOG_TB_IN_ASM) {
8740 fprintf(logfile, "----------------\n");
8741 fprintf(logfile, "IN: %s\n", lookup_symbol(pc_start));
8742 target_disas(logfile, pc_start, dc->pc - pc_start, env->thumb);
8743 fprintf(logfile, "\n");
8747 j = gen_opc_ptr - gen_opc_buf;
8750 gen_opc_instr_start[lj++] = 0;
8752 tb->size = dc->pc - pc_start;
8757 int gen_intermediate_code(CPUState *env, TranslationBlock *tb)
8759 return gen_intermediate_code_internal(env, tb, 0);
8762 int gen_intermediate_code_pc(CPUState *env, TranslationBlock *tb)
8764 return gen_intermediate_code_internal(env, tb, 1);
8767 static const char *cpu_mode_names[16] = {
8768 "usr", "fiq", "irq", "svc", "???", "???", "???", "abt",
8769 "???", "???", "???", "und", "???", "???", "???", "sys"
8772 void cpu_dump_state(CPUState *env, FILE *f,
8773 int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
8782 /* ??? This assumes float64 and double have the same layout.
8783 Oh well, it's only debug dumps. */
8791 cpu_fprintf(f, "R%02d=%08x", i, env->regs[i]);
8793 cpu_fprintf(f, "\n");
8795 cpu_fprintf(f, " ");
8797 psr = cpsr_read(env);
8798 cpu_fprintf(f, "PSR=%08x %c%c%c%c %c %s%d\n",
8800 psr & (1 << 31) ? 'N' : '-',
8801 psr & (1 << 30) ? 'Z' : '-',
8802 psr & (1 << 29) ? 'C' : '-',
8803 psr & (1 << 28) ? 'V' : '-',
8804 psr & CPSR_T ? 'T' : 'A',
8805 cpu_mode_names[psr & 0xf], (psr & 0x10) ? 32 : 26);
8808 for (i = 0; i < 16; i++) {
8809 d.d = env->vfp.regs[i];
8813 cpu_fprintf(f, "s%02d=%08x(%8g) s%02d=%08x(%8g) d%02d=%08x%08x(%8g)\n",
8814 i * 2, (int)s0.i, s0.s,
8815 i * 2 + 1, (int)s1.i, s1.s,
8816 i, (int)(uint32_t)d.l.upper, (int)(uint32_t)d.l.lower,
8819 cpu_fprintf(f, "FPSCR: %08x\n", (int)env->vfp.xregs[ARM_VFP_FPSCR]);