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
37 #define ENABLE_ARCH_5J 0
38 #define ENABLE_ARCH_6 arm_feature(env, ARM_FEATURE_V6)
39 #define ENABLE_ARCH_6K arm_feature(env, ARM_FEATURE_V6K)
40 #define ENABLE_ARCH_6T2 arm_feature(env, ARM_FEATURE_THUMB2)
41 #define ENABLE_ARCH_7 arm_feature(env, ARM_FEATURE_V7)
43 #define ARCH(x) if (!ENABLE_ARCH_##x) goto illegal_op;
45 /* internal defines */
46 typedef struct DisasContext {
49 /* Nonzero if this instruction has been conditionally skipped. */
51 /* The label that will be jumped to when the instruction is skipped. */
53 /* Thumb-2 condtional execution bits. */
56 struct TranslationBlock *tb;
57 int singlestep_enabled;
60 #if !defined(CONFIG_USER_ONLY)
65 #if defined(CONFIG_USER_ONLY)
68 #define IS_USER(s) (s->user)
71 /* These instructions trap after executing, so defer them until after the
72 conditional executions state has been updated. */
77 /* We reuse the same 64-bit temporaries for efficiency. */
78 static TCGv cpu_V0, cpu_V1, cpu_M0;
80 /* FIXME: These should be removed. */
82 static TCGv cpu_F0s, cpu_F1s, cpu_F0d, cpu_F1d;
84 #define ICOUNT_TEMP cpu_T[0]
85 #include "gen-icount.h"
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_ext8u_i32(var, var)
225 #define gen_uxth(var) tcg_gen_ext16u_i32(var, var)
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_ext16s_i32(tmp1, a);
251 tcg_gen_ext16s_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 /* T0 &= ~T1. Clobbers T1. */
455 /* FIXME: Implement bic natively. */
456 static inline void tcg_gen_bic_i32(TCGv dest, TCGv t0, TCGv t1)
458 TCGv tmp = new_tmp();
459 tcg_gen_not_i32(tmp, t1);
460 tcg_gen_and_i32(dest, t0, tmp);
463 static inline void gen_op_bicl_T0_T1(void)
469 /* FIXME: Implement this natively. */
470 #define tcg_gen_abs_i32(t0, t1) gen_helper_abs(t0, t1)
472 /* FIXME: Implement this natively. */
473 static void tcg_gen_rori_i32(TCGv t0, TCGv t1, int i)
481 tcg_gen_shri_i32(tmp, t1, i);
482 tcg_gen_shli_i32(t1, t1, 32 - i);
483 tcg_gen_or_i32(t0, t1, tmp);
487 static void shifter_out_im(TCGv var, int shift)
489 TCGv tmp = new_tmp();
491 tcg_gen_andi_i32(tmp, var, 1);
493 tcg_gen_shri_i32(tmp, var, shift);
495 tcg_gen_andi_i32(tmp, tmp, 1);
501 /* Shift by immediate. Includes special handling for shift == 0. */
502 static inline void gen_arm_shift_im(TCGv var, int shiftop, int shift, int flags)
508 shifter_out_im(var, 32 - shift);
509 tcg_gen_shli_i32(var, var, shift);
515 tcg_gen_shri_i32(var, var, 31);
518 tcg_gen_movi_i32(var, 0);
521 shifter_out_im(var, shift - 1);
522 tcg_gen_shri_i32(var, var, shift);
529 shifter_out_im(var, shift - 1);
532 tcg_gen_sari_i32(var, var, shift);
534 case 3: /* ROR/RRX */
537 shifter_out_im(var, shift - 1);
538 tcg_gen_rori_i32(var, var, shift); break;
540 TCGv tmp = load_cpu_field(CF);
542 shifter_out_im(var, 0);
543 tcg_gen_shri_i32(var, var, 1);
544 tcg_gen_shli_i32(tmp, tmp, 31);
545 tcg_gen_or_i32(var, var, tmp);
551 static inline void gen_arm_shift_reg(TCGv var, int shiftop,
552 TCGv shift, int flags)
556 case 0: gen_helper_shl_cc(var, var, shift); break;
557 case 1: gen_helper_shr_cc(var, var, shift); break;
558 case 2: gen_helper_sar_cc(var, var, shift); break;
559 case 3: gen_helper_ror_cc(var, var, shift); break;
563 case 0: gen_helper_shl(var, var, shift); break;
564 case 1: gen_helper_shr(var, var, shift); break;
565 case 2: gen_helper_sar(var, var, shift); break;
566 case 3: gen_helper_ror(var, var, shift); break;
572 #define PAS_OP(pfx) \
574 case 0: gen_pas_helper(glue(pfx,add16)); break; \
575 case 1: gen_pas_helper(glue(pfx,addsubx)); break; \
576 case 2: gen_pas_helper(glue(pfx,subaddx)); break; \
577 case 3: gen_pas_helper(glue(pfx,sub16)); break; \
578 case 4: gen_pas_helper(glue(pfx,add8)); break; \
579 case 7: gen_pas_helper(glue(pfx,sub8)); break; \
581 static void gen_arm_parallel_addsub(int op1, int op2, TCGv a, TCGv b)
586 #define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b, tmp)
588 tmp = tcg_temp_new(TCG_TYPE_PTR);
589 tcg_gen_addi_ptr(tmp, cpu_env, offsetof(CPUState, GE));
593 tmp = tcg_temp_new(TCG_TYPE_PTR);
594 tcg_gen_addi_ptr(tmp, cpu_env, offsetof(CPUState, GE));
597 #undef gen_pas_helper
598 #define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b)
611 #undef gen_pas_helper
616 /* For unknown reasons Arm and Thumb-2 use arbitrarily different encodings. */
617 #define PAS_OP(pfx) \
619 case 0: gen_pas_helper(glue(pfx,add8)); break; \
620 case 1: gen_pas_helper(glue(pfx,add16)); break; \
621 case 2: gen_pas_helper(glue(pfx,addsubx)); break; \
622 case 4: gen_pas_helper(glue(pfx,sub8)); break; \
623 case 5: gen_pas_helper(glue(pfx,sub16)); break; \
624 case 6: gen_pas_helper(glue(pfx,subaddx)); break; \
626 static void gen_thumb2_parallel_addsub(int op1, int op2, TCGv a, TCGv b)
631 #define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b, tmp)
633 tmp = tcg_temp_new(TCG_TYPE_PTR);
634 tcg_gen_addi_ptr(tmp, cpu_env, offsetof(CPUState, GE));
638 tmp = tcg_temp_new(TCG_TYPE_PTR);
639 tcg_gen_addi_ptr(tmp, cpu_env, offsetof(CPUState, GE));
642 #undef gen_pas_helper
643 #define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b)
656 #undef gen_pas_helper
661 static void gen_test_cc(int cc, int label)
669 tmp = load_cpu_field(ZF);
670 tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 0, label);
673 tmp = load_cpu_field(ZF);
674 tcg_gen_brcondi_i32(TCG_COND_NE, tmp, 0, label);
677 tmp = load_cpu_field(CF);
678 tcg_gen_brcondi_i32(TCG_COND_NE, tmp, 0, label);
681 tmp = load_cpu_field(CF);
682 tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 0, label);
685 tmp = load_cpu_field(NF);
686 tcg_gen_brcondi_i32(TCG_COND_LT, tmp, 0, label);
689 tmp = load_cpu_field(NF);
690 tcg_gen_brcondi_i32(TCG_COND_GE, tmp, 0, label);
693 tmp = load_cpu_field(VF);
694 tcg_gen_brcondi_i32(TCG_COND_LT, tmp, 0, label);
697 tmp = load_cpu_field(VF);
698 tcg_gen_brcondi_i32(TCG_COND_GE, tmp, 0, label);
700 case 8: /* hi: C && !Z */
701 inv = gen_new_label();
702 tmp = load_cpu_field(CF);
703 tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 0, inv);
705 tmp = load_cpu_field(ZF);
706 tcg_gen_brcondi_i32(TCG_COND_NE, tmp, 0, label);
709 case 9: /* ls: !C || Z */
710 tmp = load_cpu_field(CF);
711 tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 0, label);
713 tmp = load_cpu_field(ZF);
714 tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 0, label);
716 case 10: /* ge: N == V -> N ^ V == 0 */
717 tmp = load_cpu_field(VF);
718 tmp2 = load_cpu_field(NF);
719 tcg_gen_xor_i32(tmp, tmp, tmp2);
721 tcg_gen_brcondi_i32(TCG_COND_GE, tmp, 0, label);
723 case 11: /* lt: N != V -> N ^ V != 0 */
724 tmp = load_cpu_field(VF);
725 tmp2 = load_cpu_field(NF);
726 tcg_gen_xor_i32(tmp, tmp, tmp2);
728 tcg_gen_brcondi_i32(TCG_COND_LT, tmp, 0, label);
730 case 12: /* gt: !Z && N == V */
731 inv = gen_new_label();
732 tmp = load_cpu_field(ZF);
733 tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 0, inv);
735 tmp = load_cpu_field(VF);
736 tmp2 = load_cpu_field(NF);
737 tcg_gen_xor_i32(tmp, tmp, tmp2);
739 tcg_gen_brcondi_i32(TCG_COND_GE, tmp, 0, label);
742 case 13: /* le: Z || N != V */
743 tmp = load_cpu_field(ZF);
744 tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 0, label);
746 tmp = load_cpu_field(VF);
747 tmp2 = load_cpu_field(NF);
748 tcg_gen_xor_i32(tmp, tmp, tmp2);
750 tcg_gen_brcondi_i32(TCG_COND_LT, tmp, 0, label);
753 fprintf(stderr, "Bad condition code 0x%x\n", cc);
759 const uint8_t table_logic_cc[16] = {
778 /* Set PC and Thumb state from an immediate address. */
779 static inline void gen_bx_im(DisasContext *s, uint32_t addr)
783 s->is_jmp = DISAS_UPDATE;
785 if (s->thumb != (addr & 1)) {
786 tcg_gen_movi_i32(tmp, addr & 1);
787 tcg_gen_st_i32(tmp, cpu_env, offsetof(CPUState, thumb));
789 tcg_gen_movi_i32(tmp, addr & ~1);
790 tcg_gen_st_i32(tmp, cpu_env, offsetof(CPUState, regs[15]));
794 /* Set PC and Thumb state from var. var is marked as dead. */
795 static inline void gen_bx(DisasContext *s, TCGv var)
799 s->is_jmp = DISAS_UPDATE;
801 tcg_gen_andi_i32(tmp, var, 1);
802 store_cpu_field(tmp, thumb);
803 tcg_gen_andi_i32(var, var, ~1);
804 store_cpu_field(var, regs[15]);
807 /* TODO: This should be removed. Use gen_bx instead. */
808 static inline void gen_bx_T0(DisasContext *s)
810 TCGv tmp = new_tmp();
811 tcg_gen_mov_i32(tmp, cpu_T[0]);
815 #if defined(CONFIG_USER_ONLY)
816 #define gen_ldst(name, s) gen_op_##name##_raw()
818 #define gen_ldst(name, s) do { \
821 gen_op_##name##_user(); \
823 gen_op_##name##_kernel(); \
826 static inline TCGv gen_ld8s(TCGv addr, int index)
828 TCGv tmp = new_tmp();
829 tcg_gen_qemu_ld8s(tmp, addr, index);
832 static inline TCGv gen_ld8u(TCGv addr, int index)
834 TCGv tmp = new_tmp();
835 tcg_gen_qemu_ld8u(tmp, addr, index);
838 static inline TCGv gen_ld16s(TCGv addr, int index)
840 TCGv tmp = new_tmp();
841 tcg_gen_qemu_ld16s(tmp, addr, index);
844 static inline TCGv gen_ld16u(TCGv addr, int index)
846 TCGv tmp = new_tmp();
847 tcg_gen_qemu_ld16u(tmp, addr, index);
850 static inline TCGv gen_ld32(TCGv addr, int index)
852 TCGv tmp = new_tmp();
853 tcg_gen_qemu_ld32u(tmp, addr, index);
856 static inline void gen_st8(TCGv val, TCGv addr, int index)
858 tcg_gen_qemu_st8(val, addr, index);
861 static inline void gen_st16(TCGv val, TCGv addr, int index)
863 tcg_gen_qemu_st16(val, addr, index);
866 static inline void gen_st32(TCGv val, TCGv addr, int index)
868 tcg_gen_qemu_st32(val, addr, index);
872 static inline void gen_movl_T0_reg(DisasContext *s, int reg)
874 load_reg_var(s, cpu_T[0], reg);
877 static inline void gen_movl_T1_reg(DisasContext *s, int reg)
879 load_reg_var(s, cpu_T[1], reg);
882 static inline void gen_movl_T2_reg(DisasContext *s, int reg)
884 load_reg_var(s, cpu_T[2], reg);
887 static inline void gen_set_pc_im(uint32_t val)
889 TCGv tmp = new_tmp();
890 tcg_gen_movi_i32(tmp, val);
891 store_cpu_field(tmp, regs[15]);
894 static inline void gen_movl_reg_TN(DisasContext *s, int reg, int t)
899 tcg_gen_andi_i32(tmp, cpu_T[t], ~1);
903 tcg_gen_st_i32(tmp, cpu_env, offsetof(CPUState, regs[reg]));
906 s->is_jmp = DISAS_JUMP;
910 static inline void gen_movl_reg_T0(DisasContext *s, int reg)
912 gen_movl_reg_TN(s, reg, 0);
915 static inline void gen_movl_reg_T1(DisasContext *s, int reg)
917 gen_movl_reg_TN(s, reg, 1);
920 /* Force a TB lookup after an instruction that changes the CPU state. */
921 static inline void gen_lookup_tb(DisasContext *s)
923 gen_op_movl_T0_im(s->pc);
924 gen_movl_reg_T0(s, 15);
925 s->is_jmp = DISAS_UPDATE;
928 static inline void gen_add_data_offset(DisasContext *s, unsigned int insn,
931 int val, rm, shift, shiftop;
934 if (!(insn & (1 << 25))) {
937 if (!(insn & (1 << 23)))
940 tcg_gen_addi_i32(var, var, val);
944 shift = (insn >> 7) & 0x1f;
945 shiftop = (insn >> 5) & 3;
946 offset = load_reg(s, rm);
947 gen_arm_shift_im(offset, shiftop, shift, 0);
948 if (!(insn & (1 << 23)))
949 tcg_gen_sub_i32(var, var, offset);
951 tcg_gen_add_i32(var, var, offset);
956 static inline void gen_add_datah_offset(DisasContext *s, unsigned int insn,
962 if (insn & (1 << 22)) {
964 val = (insn & 0xf) | ((insn >> 4) & 0xf0);
965 if (!(insn & (1 << 23)))
969 tcg_gen_addi_i32(var, var, val);
973 tcg_gen_addi_i32(var, var, extra);
975 offset = load_reg(s, rm);
976 if (!(insn & (1 << 23)))
977 tcg_gen_sub_i32(var, var, offset);
979 tcg_gen_add_i32(var, var, offset);
984 #define VFP_OP2(name) \
985 static inline void gen_vfp_##name(int dp) \
988 gen_helper_vfp_##name##d(cpu_F0d, cpu_F0d, cpu_F1d, cpu_env); \
990 gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, cpu_F1s, cpu_env); \
993 #define VFP_OP1(name) \
994 static inline void gen_vfp_##name(int dp, int arg) \
997 gen_op_vfp_##name##d(arg); \
999 gen_op_vfp_##name##s(arg); \
1009 static inline void gen_vfp_abs(int dp)
1012 gen_helper_vfp_absd(cpu_F0d, cpu_F0d);
1014 gen_helper_vfp_abss(cpu_F0s, cpu_F0s);
1017 static inline void gen_vfp_neg(int dp)
1020 gen_helper_vfp_negd(cpu_F0d, cpu_F0d);
1022 gen_helper_vfp_negs(cpu_F0s, cpu_F0s);
1025 static inline void gen_vfp_sqrt(int dp)
1028 gen_helper_vfp_sqrtd(cpu_F0d, cpu_F0d, cpu_env);
1030 gen_helper_vfp_sqrts(cpu_F0s, cpu_F0s, cpu_env);
1033 static inline void gen_vfp_cmp(int dp)
1036 gen_helper_vfp_cmpd(cpu_F0d, cpu_F1d, cpu_env);
1038 gen_helper_vfp_cmps(cpu_F0s, cpu_F1s, cpu_env);
1041 static inline void gen_vfp_cmpe(int dp)
1044 gen_helper_vfp_cmped(cpu_F0d, cpu_F1d, cpu_env);
1046 gen_helper_vfp_cmpes(cpu_F0s, cpu_F1s, cpu_env);
1049 static inline void gen_vfp_F1_ld0(int dp)
1052 tcg_gen_movi_i64(cpu_F1d, 0);
1054 tcg_gen_movi_i32(cpu_F1s, 0);
1057 static inline void gen_vfp_uito(int dp)
1060 gen_helper_vfp_uitod(cpu_F0d, cpu_F0s, cpu_env);
1062 gen_helper_vfp_uitos(cpu_F0s, cpu_F0s, cpu_env);
1065 static inline void gen_vfp_sito(int dp)
1068 gen_helper_vfp_sitod(cpu_F0d, cpu_F0s, cpu_env);
1070 gen_helper_vfp_sitos(cpu_F0s, cpu_F0s, cpu_env);
1073 static inline void gen_vfp_toui(int dp)
1076 gen_helper_vfp_touid(cpu_F0s, cpu_F0d, cpu_env);
1078 gen_helper_vfp_touis(cpu_F0s, cpu_F0s, cpu_env);
1081 static inline void gen_vfp_touiz(int dp)
1084 gen_helper_vfp_touizd(cpu_F0s, cpu_F0d, cpu_env);
1086 gen_helper_vfp_touizs(cpu_F0s, cpu_F0s, cpu_env);
1089 static inline void gen_vfp_tosi(int dp)
1092 gen_helper_vfp_tosid(cpu_F0s, cpu_F0d, cpu_env);
1094 gen_helper_vfp_tosis(cpu_F0s, cpu_F0s, cpu_env);
1097 static inline void gen_vfp_tosiz(int dp)
1100 gen_helper_vfp_tosizd(cpu_F0s, cpu_F0d, cpu_env);
1102 gen_helper_vfp_tosizs(cpu_F0s, cpu_F0s, cpu_env);
1105 #define VFP_GEN_FIX(name) \
1106 static inline void gen_vfp_##name(int dp, int shift) \
1109 gen_helper_vfp_##name##d(cpu_F0d, cpu_F0d, tcg_const_i32(shift), cpu_env);\
1111 gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, tcg_const_i32(shift), cpu_env);\
1123 static inline void gen_vfp_ld(DisasContext *s, int dp)
1126 tcg_gen_qemu_ld64(cpu_F0d, cpu_T[1], IS_USER(s));
1128 tcg_gen_qemu_ld32u(cpu_F0s, cpu_T[1], IS_USER(s));
1131 static inline void gen_vfp_st(DisasContext *s, int dp)
1134 tcg_gen_qemu_st64(cpu_F0d, cpu_T[1], IS_USER(s));
1136 tcg_gen_qemu_st32(cpu_F0s, cpu_T[1], IS_USER(s));
1140 vfp_reg_offset (int dp, int reg)
1143 return offsetof(CPUARMState, vfp.regs[reg]);
1145 return offsetof(CPUARMState, vfp.regs[reg >> 1])
1146 + offsetof(CPU_DoubleU, l.upper);
1148 return offsetof(CPUARMState, vfp.regs[reg >> 1])
1149 + offsetof(CPU_DoubleU, l.lower);
1153 /* Return the offset of a 32-bit piece of a NEON register.
1154 zero is the least significant end of the register. */
1156 neon_reg_offset (int reg, int n)
1160 return vfp_reg_offset(0, sreg);
1163 /* FIXME: Remove these. */
1164 #define neon_T0 cpu_T[0]
1165 #define neon_T1 cpu_T[1]
1166 #define NEON_GET_REG(T, reg, n) \
1167 tcg_gen_ld_i32(neon_##T, cpu_env, neon_reg_offset(reg, n))
1168 #define NEON_SET_REG(T, reg, n) \
1169 tcg_gen_st_i32(neon_##T, cpu_env, neon_reg_offset(reg, n))
1171 static TCGv neon_load_reg(int reg, int pass)
1173 TCGv tmp = new_tmp();
1174 tcg_gen_ld_i32(tmp, cpu_env, neon_reg_offset(reg, pass));
1178 static void neon_store_reg(int reg, int pass, TCGv var)
1180 tcg_gen_st_i32(var, cpu_env, neon_reg_offset(reg, pass));
1184 static inline void neon_load_reg64(TCGv var, int reg)
1186 tcg_gen_ld_i64(var, cpu_env, vfp_reg_offset(1, reg));
1189 static inline void neon_store_reg64(TCGv var, int reg)
1191 tcg_gen_st_i64(var, cpu_env, vfp_reg_offset(1, reg));
1194 #define tcg_gen_ld_f32 tcg_gen_ld_i32
1195 #define tcg_gen_ld_f64 tcg_gen_ld_i64
1196 #define tcg_gen_st_f32 tcg_gen_st_i32
1197 #define tcg_gen_st_f64 tcg_gen_st_i64
1199 static inline void gen_mov_F0_vreg(int dp, int reg)
1202 tcg_gen_ld_f64(cpu_F0d, cpu_env, vfp_reg_offset(dp, reg));
1204 tcg_gen_ld_f32(cpu_F0s, cpu_env, vfp_reg_offset(dp, reg));
1207 static inline void gen_mov_F1_vreg(int dp, int reg)
1210 tcg_gen_ld_f64(cpu_F1d, cpu_env, vfp_reg_offset(dp, reg));
1212 tcg_gen_ld_f32(cpu_F1s, cpu_env, vfp_reg_offset(dp, reg));
1215 static inline void gen_mov_vreg_F0(int dp, int reg)
1218 tcg_gen_st_f64(cpu_F0d, cpu_env, vfp_reg_offset(dp, reg));
1220 tcg_gen_st_f32(cpu_F0s, cpu_env, vfp_reg_offset(dp, reg));
1223 #define ARM_CP_RW_BIT (1 << 20)
1225 static inline void iwmmxt_load_reg(TCGv var, int reg)
1227 tcg_gen_ld_i64(var, cpu_env, offsetof(CPUState, iwmmxt.regs[reg]));
1230 static inline void iwmmxt_store_reg(TCGv var, int reg)
1232 tcg_gen_st_i64(var, cpu_env, offsetof(CPUState, iwmmxt.regs[reg]));
1235 static inline void gen_op_iwmmxt_movl_wCx_T0(int reg)
1237 tcg_gen_st_i32(cpu_T[0], cpu_env, offsetof(CPUState, iwmmxt.cregs[reg]));
1240 static inline void gen_op_iwmmxt_movl_T0_wCx(int reg)
1242 tcg_gen_ld_i32(cpu_T[0], cpu_env, offsetof(CPUState, iwmmxt.cregs[reg]));
1245 static inline void gen_op_iwmmxt_movl_T1_wCx(int reg)
1247 tcg_gen_ld_i32(cpu_T[1], cpu_env, offsetof(CPUState, iwmmxt.cregs[reg]));
1250 static inline void gen_op_iwmmxt_movq_wRn_M0(int rn)
1252 iwmmxt_store_reg(cpu_M0, rn);
1255 static inline void gen_op_iwmmxt_movq_M0_wRn(int rn)
1257 iwmmxt_load_reg(cpu_M0, rn);
1260 static inline void gen_op_iwmmxt_orq_M0_wRn(int rn)
1262 iwmmxt_load_reg(cpu_V1, rn);
1263 tcg_gen_or_i64(cpu_M0, cpu_M0, cpu_V1);
1266 static inline void gen_op_iwmmxt_andq_M0_wRn(int rn)
1268 iwmmxt_load_reg(cpu_V1, rn);
1269 tcg_gen_and_i64(cpu_M0, cpu_M0, cpu_V1);
1272 static inline void gen_op_iwmmxt_xorq_M0_wRn(int rn)
1274 iwmmxt_load_reg(cpu_V1, rn);
1275 tcg_gen_xor_i64(cpu_M0, cpu_M0, cpu_V1);
1278 #define IWMMXT_OP(name) \
1279 static inline void gen_op_iwmmxt_##name##_M0_wRn(int rn) \
1281 iwmmxt_load_reg(cpu_V1, rn); \
1282 gen_helper_iwmmxt_##name(cpu_M0, cpu_M0, cpu_V1); \
1285 #define IWMMXT_OP_ENV(name) \
1286 static inline void gen_op_iwmmxt_##name##_M0_wRn(int rn) \
1288 iwmmxt_load_reg(cpu_V1, rn); \
1289 gen_helper_iwmmxt_##name(cpu_M0, cpu_env, cpu_M0, cpu_V1); \
1292 #define IWMMXT_OP_ENV_SIZE(name) \
1293 IWMMXT_OP_ENV(name##b) \
1294 IWMMXT_OP_ENV(name##w) \
1295 IWMMXT_OP_ENV(name##l)
1297 #define IWMMXT_OP_ENV1(name) \
1298 static inline void gen_op_iwmmxt_##name##_M0(void) \
1300 gen_helper_iwmmxt_##name(cpu_M0, cpu_env, cpu_M0); \
1314 IWMMXT_OP_ENV_SIZE(unpackl)
1315 IWMMXT_OP_ENV_SIZE(unpackh)
1317 IWMMXT_OP_ENV1(unpacklub)
1318 IWMMXT_OP_ENV1(unpackluw)
1319 IWMMXT_OP_ENV1(unpacklul)
1320 IWMMXT_OP_ENV1(unpackhub)
1321 IWMMXT_OP_ENV1(unpackhuw)
1322 IWMMXT_OP_ENV1(unpackhul)
1323 IWMMXT_OP_ENV1(unpacklsb)
1324 IWMMXT_OP_ENV1(unpacklsw)
1325 IWMMXT_OP_ENV1(unpacklsl)
1326 IWMMXT_OP_ENV1(unpackhsb)
1327 IWMMXT_OP_ENV1(unpackhsw)
1328 IWMMXT_OP_ENV1(unpackhsl)
1330 IWMMXT_OP_ENV_SIZE(cmpeq)
1331 IWMMXT_OP_ENV_SIZE(cmpgtu)
1332 IWMMXT_OP_ENV_SIZE(cmpgts)
1334 IWMMXT_OP_ENV_SIZE(mins)
1335 IWMMXT_OP_ENV_SIZE(minu)
1336 IWMMXT_OP_ENV_SIZE(maxs)
1337 IWMMXT_OP_ENV_SIZE(maxu)
1339 IWMMXT_OP_ENV_SIZE(subn)
1340 IWMMXT_OP_ENV_SIZE(addn)
1341 IWMMXT_OP_ENV_SIZE(subu)
1342 IWMMXT_OP_ENV_SIZE(addu)
1343 IWMMXT_OP_ENV_SIZE(subs)
1344 IWMMXT_OP_ENV_SIZE(adds)
1346 IWMMXT_OP_ENV(avgb0)
1347 IWMMXT_OP_ENV(avgb1)
1348 IWMMXT_OP_ENV(avgw0)
1349 IWMMXT_OP_ENV(avgw1)
1353 IWMMXT_OP_ENV(packuw)
1354 IWMMXT_OP_ENV(packul)
1355 IWMMXT_OP_ENV(packuq)
1356 IWMMXT_OP_ENV(packsw)
1357 IWMMXT_OP_ENV(packsl)
1358 IWMMXT_OP_ENV(packsq)
1360 static inline void gen_op_iwmmxt_muladdsl_M0_T0_T1(void)
1362 gen_helper_iwmmxt_muladdsl(cpu_M0, cpu_M0, cpu_T[0], cpu_T[1]);
1365 static inline void gen_op_iwmmxt_muladdsw_M0_T0_T1(void)
1367 gen_helper_iwmmxt_muladdsw(cpu_M0, cpu_M0, cpu_T[0], cpu_T[1]);
1370 static inline void gen_op_iwmmxt_muladdswl_M0_T0_T1(void)
1372 gen_helper_iwmmxt_muladdswl(cpu_M0, cpu_M0, cpu_T[0], cpu_T[1]);
1375 static inline void gen_op_iwmmxt_align_M0_T0_wRn(int rn)
1377 iwmmxt_load_reg(cpu_V1, rn);
1378 gen_helper_iwmmxt_align(cpu_M0, cpu_M0, cpu_V1, cpu_T[0]);
1381 static inline void gen_op_iwmmxt_insr_M0_T0_T1(int shift)
1383 TCGv tmp = tcg_const_i32(shift);
1384 gen_helper_iwmmxt_insr(cpu_M0, cpu_M0, cpu_T[0], cpu_T[1], tmp);
1387 static inline void gen_op_iwmmxt_extrsb_T0_M0(int shift)
1389 tcg_gen_shri_i64(cpu_M0, cpu_M0, shift);
1390 tcg_gen_trunc_i64_i32(cpu_T[0], cpu_M0);
1391 tcg_gen_ext8s_i32(cpu_T[0], cpu_T[0]);
1394 static inline void gen_op_iwmmxt_extrsw_T0_M0(int shift)
1396 tcg_gen_shri_i64(cpu_M0, cpu_M0, shift);
1397 tcg_gen_trunc_i64_i32(cpu_T[0], cpu_M0);
1398 tcg_gen_ext16s_i32(cpu_T[0], cpu_T[0]);
1401 static inline void gen_op_iwmmxt_extru_T0_M0(int shift, uint32_t mask)
1403 tcg_gen_shri_i64(cpu_M0, cpu_M0, shift);
1404 tcg_gen_trunc_i64_i32(cpu_T[0], cpu_M0);
1406 tcg_gen_andi_i32(cpu_T[0], cpu_T[0], mask);
1409 static void gen_op_iwmmxt_set_mup(void)
1412 tmp = load_cpu_field(iwmmxt.cregs[ARM_IWMMXT_wCon]);
1413 tcg_gen_ori_i32(tmp, tmp, 2);
1414 store_cpu_field(tmp, iwmmxt.cregs[ARM_IWMMXT_wCon]);
1417 static void gen_op_iwmmxt_set_cup(void)
1420 tmp = load_cpu_field(iwmmxt.cregs[ARM_IWMMXT_wCon]);
1421 tcg_gen_ori_i32(tmp, tmp, 1);
1422 store_cpu_field(tmp, iwmmxt.cregs[ARM_IWMMXT_wCon]);
1425 static void gen_op_iwmmxt_setpsr_nz(void)
1427 TCGv tmp = new_tmp();
1428 gen_helper_iwmmxt_setpsr_nz(tmp, cpu_M0);
1429 store_cpu_field(tmp, iwmmxt.cregs[ARM_IWMMXT_wCASF]);
1432 static inline void gen_op_iwmmxt_addl_M0_wRn(int rn)
1434 iwmmxt_load_reg(cpu_V1, rn);
1435 tcg_gen_ext32u_i64(cpu_V1, cpu_V1);
1436 tcg_gen_add_i64(cpu_M0, cpu_M0, cpu_V1);
1440 static void gen_iwmmxt_movl_T0_T1_wRn(int rn)
1442 iwmmxt_load_reg(cpu_V0, rn);
1443 tcg_gen_trunc_i64_i32(cpu_T[0], cpu_V0);
1444 tcg_gen_shri_i64(cpu_V0, cpu_V0, 32);
1445 tcg_gen_trunc_i64_i32(cpu_T[1], cpu_V0);
1448 static void gen_iwmmxt_movl_wRn_T0_T1(int rn)
1450 tcg_gen_extu_i32_i64(cpu_V0, cpu_T[0]);
1451 tcg_gen_extu_i32_i64(cpu_V1, cpu_T[0]);
1452 tcg_gen_shli_i64(cpu_V1, cpu_V1, 32);
1453 tcg_gen_or_i64(cpu_V0, cpu_V0, cpu_V1);
1454 iwmmxt_store_reg(cpu_V0, rn);
1457 static inline int gen_iwmmxt_address(DisasContext *s, uint32_t insn)
1462 rd = (insn >> 16) & 0xf;
1463 gen_movl_T1_reg(s, rd);
1465 offset = (insn & 0xff) << ((insn >> 7) & 2);
1466 if (insn & (1 << 24)) {
1468 if (insn & (1 << 23))
1469 gen_op_addl_T1_im(offset);
1471 gen_op_addl_T1_im(-offset);
1473 if (insn & (1 << 21))
1474 gen_movl_reg_T1(s, rd);
1475 } else if (insn & (1 << 21)) {
1477 if (insn & (1 << 23))
1478 gen_op_movl_T0_im(offset);
1480 gen_op_movl_T0_im(- offset);
1481 gen_op_addl_T0_T1();
1482 gen_movl_reg_T0(s, rd);
1483 } else if (!(insn & (1 << 23)))
1488 static inline int gen_iwmmxt_shift(uint32_t insn, uint32_t mask)
1490 int rd = (insn >> 0) & 0xf;
1492 if (insn & (1 << 8))
1493 if (rd < ARM_IWMMXT_wCGR0 || rd > ARM_IWMMXT_wCGR3)
1496 gen_op_iwmmxt_movl_T0_wCx(rd);
1498 gen_iwmmxt_movl_T0_T1_wRn(rd);
1500 gen_op_movl_T1_im(mask);
1501 gen_op_andl_T0_T1();
1505 /* Disassemble an iwMMXt instruction. Returns nonzero if an error occured
1506 (ie. an undefined instruction). */
1507 static int disas_iwmmxt_insn(CPUState *env, DisasContext *s, uint32_t insn)
1510 int rdhi, rdlo, rd0, rd1, i;
1513 if ((insn & 0x0e000e00) == 0x0c000000) {
1514 if ((insn & 0x0fe00ff0) == 0x0c400000) {
1516 rdlo = (insn >> 12) & 0xf;
1517 rdhi = (insn >> 16) & 0xf;
1518 if (insn & ARM_CP_RW_BIT) { /* TMRRC */
1519 gen_iwmmxt_movl_T0_T1_wRn(wrd);
1520 gen_movl_reg_T0(s, rdlo);
1521 gen_movl_reg_T1(s, rdhi);
1522 } else { /* TMCRR */
1523 gen_movl_T0_reg(s, rdlo);
1524 gen_movl_T1_reg(s, rdhi);
1525 gen_iwmmxt_movl_wRn_T0_T1(wrd);
1526 gen_op_iwmmxt_set_mup();
1531 wrd = (insn >> 12) & 0xf;
1532 if (gen_iwmmxt_address(s, insn))
1534 if (insn & ARM_CP_RW_BIT) {
1535 if ((insn >> 28) == 0xf) { /* WLDRW wCx */
1536 tmp = gen_ld32(cpu_T[1], IS_USER(s));
1537 tcg_gen_mov_i32(cpu_T[0], tmp);
1539 gen_op_iwmmxt_movl_wCx_T0(wrd);
1542 if (insn & (1 << 8)) {
1543 if (insn & (1 << 22)) { /* WLDRD */
1544 tcg_gen_qemu_ld64(cpu_M0, cpu_T[1], IS_USER(s));
1546 } else { /* WLDRW wRd */
1547 tmp = gen_ld32(cpu_T[1], IS_USER(s));
1550 if (insn & (1 << 22)) { /* WLDRH */
1551 tmp = gen_ld16u(cpu_T[1], IS_USER(s));
1552 } else { /* WLDRB */
1553 tmp = gen_ld8u(cpu_T[1], IS_USER(s));
1557 tcg_gen_extu_i32_i64(cpu_M0, tmp);
1560 gen_op_iwmmxt_movq_wRn_M0(wrd);
1563 if ((insn >> 28) == 0xf) { /* WSTRW wCx */
1564 gen_op_iwmmxt_movl_T0_wCx(wrd);
1566 tcg_gen_mov_i32(tmp, cpu_T[0]);
1567 gen_st32(tmp, cpu_T[1], IS_USER(s));
1569 gen_op_iwmmxt_movq_M0_wRn(wrd);
1571 if (insn & (1 << 8)) {
1572 if (insn & (1 << 22)) { /* WSTRD */
1574 tcg_gen_qemu_st64(cpu_M0, cpu_T[1], IS_USER(s));
1575 } else { /* WSTRW wRd */
1576 tcg_gen_trunc_i64_i32(tmp, cpu_M0);
1577 gen_st32(tmp, cpu_T[1], IS_USER(s));
1580 if (insn & (1 << 22)) { /* WSTRH */
1581 tcg_gen_trunc_i64_i32(tmp, cpu_M0);
1582 gen_st16(tmp, cpu_T[1], IS_USER(s));
1583 } else { /* WSTRB */
1584 tcg_gen_trunc_i64_i32(tmp, cpu_M0);
1585 gen_st8(tmp, cpu_T[1], IS_USER(s));
1593 if ((insn & 0x0f000000) != 0x0e000000)
1596 switch (((insn >> 12) & 0xf00) | ((insn >> 4) & 0xff)) {
1597 case 0x000: /* WOR */
1598 wrd = (insn >> 12) & 0xf;
1599 rd0 = (insn >> 0) & 0xf;
1600 rd1 = (insn >> 16) & 0xf;
1601 gen_op_iwmmxt_movq_M0_wRn(rd0);
1602 gen_op_iwmmxt_orq_M0_wRn(rd1);
1603 gen_op_iwmmxt_setpsr_nz();
1604 gen_op_iwmmxt_movq_wRn_M0(wrd);
1605 gen_op_iwmmxt_set_mup();
1606 gen_op_iwmmxt_set_cup();
1608 case 0x011: /* TMCR */
1611 rd = (insn >> 12) & 0xf;
1612 wrd = (insn >> 16) & 0xf;
1614 case ARM_IWMMXT_wCID:
1615 case ARM_IWMMXT_wCASF:
1617 case ARM_IWMMXT_wCon:
1618 gen_op_iwmmxt_set_cup();
1620 case ARM_IWMMXT_wCSSF:
1621 gen_op_iwmmxt_movl_T0_wCx(wrd);
1622 gen_movl_T1_reg(s, rd);
1623 gen_op_bicl_T0_T1();
1624 gen_op_iwmmxt_movl_wCx_T0(wrd);
1626 case ARM_IWMMXT_wCGR0:
1627 case ARM_IWMMXT_wCGR1:
1628 case ARM_IWMMXT_wCGR2:
1629 case ARM_IWMMXT_wCGR3:
1630 gen_op_iwmmxt_set_cup();
1631 gen_movl_reg_T0(s, rd);
1632 gen_op_iwmmxt_movl_wCx_T0(wrd);
1638 case 0x100: /* WXOR */
1639 wrd = (insn >> 12) & 0xf;
1640 rd0 = (insn >> 0) & 0xf;
1641 rd1 = (insn >> 16) & 0xf;
1642 gen_op_iwmmxt_movq_M0_wRn(rd0);
1643 gen_op_iwmmxt_xorq_M0_wRn(rd1);
1644 gen_op_iwmmxt_setpsr_nz();
1645 gen_op_iwmmxt_movq_wRn_M0(wrd);
1646 gen_op_iwmmxt_set_mup();
1647 gen_op_iwmmxt_set_cup();
1649 case 0x111: /* TMRC */
1652 rd = (insn >> 12) & 0xf;
1653 wrd = (insn >> 16) & 0xf;
1654 gen_op_iwmmxt_movl_T0_wCx(wrd);
1655 gen_movl_reg_T0(s, rd);
1657 case 0x300: /* WANDN */
1658 wrd = (insn >> 12) & 0xf;
1659 rd0 = (insn >> 0) & 0xf;
1660 rd1 = (insn >> 16) & 0xf;
1661 gen_op_iwmmxt_movq_M0_wRn(rd0);
1662 tcg_gen_neg_i64(cpu_M0, cpu_M0);
1663 gen_op_iwmmxt_andq_M0_wRn(rd1);
1664 gen_op_iwmmxt_setpsr_nz();
1665 gen_op_iwmmxt_movq_wRn_M0(wrd);
1666 gen_op_iwmmxt_set_mup();
1667 gen_op_iwmmxt_set_cup();
1669 case 0x200: /* WAND */
1670 wrd = (insn >> 12) & 0xf;
1671 rd0 = (insn >> 0) & 0xf;
1672 rd1 = (insn >> 16) & 0xf;
1673 gen_op_iwmmxt_movq_M0_wRn(rd0);
1674 gen_op_iwmmxt_andq_M0_wRn(rd1);
1675 gen_op_iwmmxt_setpsr_nz();
1676 gen_op_iwmmxt_movq_wRn_M0(wrd);
1677 gen_op_iwmmxt_set_mup();
1678 gen_op_iwmmxt_set_cup();
1680 case 0x810: case 0xa10: /* WMADD */
1681 wrd = (insn >> 12) & 0xf;
1682 rd0 = (insn >> 0) & 0xf;
1683 rd1 = (insn >> 16) & 0xf;
1684 gen_op_iwmmxt_movq_M0_wRn(rd0);
1685 if (insn & (1 << 21))
1686 gen_op_iwmmxt_maddsq_M0_wRn(rd1);
1688 gen_op_iwmmxt_madduq_M0_wRn(rd1);
1689 gen_op_iwmmxt_movq_wRn_M0(wrd);
1690 gen_op_iwmmxt_set_mup();
1692 case 0x10e: case 0x50e: case 0x90e: case 0xd0e: /* WUNPCKIL */
1693 wrd = (insn >> 12) & 0xf;
1694 rd0 = (insn >> 16) & 0xf;
1695 rd1 = (insn >> 0) & 0xf;
1696 gen_op_iwmmxt_movq_M0_wRn(rd0);
1697 switch ((insn >> 22) & 3) {
1699 gen_op_iwmmxt_unpacklb_M0_wRn(rd1);
1702 gen_op_iwmmxt_unpacklw_M0_wRn(rd1);
1705 gen_op_iwmmxt_unpackll_M0_wRn(rd1);
1710 gen_op_iwmmxt_movq_wRn_M0(wrd);
1711 gen_op_iwmmxt_set_mup();
1712 gen_op_iwmmxt_set_cup();
1714 case 0x10c: case 0x50c: case 0x90c: case 0xd0c: /* WUNPCKIH */
1715 wrd = (insn >> 12) & 0xf;
1716 rd0 = (insn >> 16) & 0xf;
1717 rd1 = (insn >> 0) & 0xf;
1718 gen_op_iwmmxt_movq_M0_wRn(rd0);
1719 switch ((insn >> 22) & 3) {
1721 gen_op_iwmmxt_unpackhb_M0_wRn(rd1);
1724 gen_op_iwmmxt_unpackhw_M0_wRn(rd1);
1727 gen_op_iwmmxt_unpackhl_M0_wRn(rd1);
1732 gen_op_iwmmxt_movq_wRn_M0(wrd);
1733 gen_op_iwmmxt_set_mup();
1734 gen_op_iwmmxt_set_cup();
1736 case 0x012: case 0x112: case 0x412: case 0x512: /* WSAD */
1737 wrd = (insn >> 12) & 0xf;
1738 rd0 = (insn >> 16) & 0xf;
1739 rd1 = (insn >> 0) & 0xf;
1740 gen_op_iwmmxt_movq_M0_wRn(rd0);
1741 if (insn & (1 << 22))
1742 gen_op_iwmmxt_sadw_M0_wRn(rd1);
1744 gen_op_iwmmxt_sadb_M0_wRn(rd1);
1745 if (!(insn & (1 << 20)))
1746 gen_op_iwmmxt_addl_M0_wRn(wrd);
1747 gen_op_iwmmxt_movq_wRn_M0(wrd);
1748 gen_op_iwmmxt_set_mup();
1750 case 0x010: case 0x110: case 0x210: case 0x310: /* WMUL */
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 << 21)) {
1756 if (insn & (1 << 20))
1757 gen_op_iwmmxt_mulshw_M0_wRn(rd1);
1759 gen_op_iwmmxt_mulslw_M0_wRn(rd1);
1761 if (insn & (1 << 20))
1762 gen_op_iwmmxt_muluhw_M0_wRn(rd1);
1764 gen_op_iwmmxt_mululw_M0_wRn(rd1);
1766 gen_op_iwmmxt_movq_wRn_M0(wrd);
1767 gen_op_iwmmxt_set_mup();
1769 case 0x410: case 0x510: case 0x610: case 0x710: /* WMAC */
1770 wrd = (insn >> 12) & 0xf;
1771 rd0 = (insn >> 16) & 0xf;
1772 rd1 = (insn >> 0) & 0xf;
1773 gen_op_iwmmxt_movq_M0_wRn(rd0);
1774 if (insn & (1 << 21))
1775 gen_op_iwmmxt_macsw_M0_wRn(rd1);
1777 gen_op_iwmmxt_macuw_M0_wRn(rd1);
1778 if (!(insn & (1 << 20))) {
1779 iwmmxt_load_reg(cpu_V1, wrd);
1780 tcg_gen_add_i64(cpu_M0, cpu_M0, cpu_V1);
1782 gen_op_iwmmxt_movq_wRn_M0(wrd);
1783 gen_op_iwmmxt_set_mup();
1785 case 0x006: case 0x406: case 0x806: case 0xc06: /* WCMPEQ */
1786 wrd = (insn >> 12) & 0xf;
1787 rd0 = (insn >> 16) & 0xf;
1788 rd1 = (insn >> 0) & 0xf;
1789 gen_op_iwmmxt_movq_M0_wRn(rd0);
1790 switch ((insn >> 22) & 3) {
1792 gen_op_iwmmxt_cmpeqb_M0_wRn(rd1);
1795 gen_op_iwmmxt_cmpeqw_M0_wRn(rd1);
1798 gen_op_iwmmxt_cmpeql_M0_wRn(rd1);
1803 gen_op_iwmmxt_movq_wRn_M0(wrd);
1804 gen_op_iwmmxt_set_mup();
1805 gen_op_iwmmxt_set_cup();
1807 case 0x800: case 0x900: case 0xc00: case 0xd00: /* WAVG2 */
1808 wrd = (insn >> 12) & 0xf;
1809 rd0 = (insn >> 16) & 0xf;
1810 rd1 = (insn >> 0) & 0xf;
1811 gen_op_iwmmxt_movq_M0_wRn(rd0);
1812 if (insn & (1 << 22)) {
1813 if (insn & (1 << 20))
1814 gen_op_iwmmxt_avgw1_M0_wRn(rd1);
1816 gen_op_iwmmxt_avgw0_M0_wRn(rd1);
1818 if (insn & (1 << 20))
1819 gen_op_iwmmxt_avgb1_M0_wRn(rd1);
1821 gen_op_iwmmxt_avgb0_M0_wRn(rd1);
1823 gen_op_iwmmxt_movq_wRn_M0(wrd);
1824 gen_op_iwmmxt_set_mup();
1825 gen_op_iwmmxt_set_cup();
1827 case 0x802: case 0x902: case 0xa02: case 0xb02: /* WALIGNR */
1828 wrd = (insn >> 12) & 0xf;
1829 rd0 = (insn >> 16) & 0xf;
1830 rd1 = (insn >> 0) & 0xf;
1831 gen_op_iwmmxt_movq_M0_wRn(rd0);
1832 gen_op_iwmmxt_movl_T0_wCx(ARM_IWMMXT_wCGR0 + ((insn >> 20) & 3));
1833 gen_op_movl_T1_im(7);
1834 gen_op_andl_T0_T1();
1835 gen_op_iwmmxt_align_M0_T0_wRn(rd1);
1836 gen_op_iwmmxt_movq_wRn_M0(wrd);
1837 gen_op_iwmmxt_set_mup();
1839 case 0x601: case 0x605: case 0x609: case 0x60d: /* TINSR */
1840 rd = (insn >> 12) & 0xf;
1841 wrd = (insn >> 16) & 0xf;
1842 gen_movl_T0_reg(s, rd);
1843 gen_op_iwmmxt_movq_M0_wRn(wrd);
1844 switch ((insn >> 6) & 3) {
1846 gen_op_movl_T1_im(0xff);
1847 gen_op_iwmmxt_insr_M0_T0_T1((insn & 7) << 3);
1850 gen_op_movl_T1_im(0xffff);
1851 gen_op_iwmmxt_insr_M0_T0_T1((insn & 3) << 4);
1854 gen_op_movl_T1_im(0xffffffff);
1855 gen_op_iwmmxt_insr_M0_T0_T1((insn & 1) << 5);
1860 gen_op_iwmmxt_movq_wRn_M0(wrd);
1861 gen_op_iwmmxt_set_mup();
1863 case 0x107: case 0x507: case 0x907: case 0xd07: /* TEXTRM */
1864 rd = (insn >> 12) & 0xf;
1865 wrd = (insn >> 16) & 0xf;
1868 gen_op_iwmmxt_movq_M0_wRn(wrd);
1869 switch ((insn >> 22) & 3) {
1872 gen_op_iwmmxt_extrsb_T0_M0((insn & 7) << 3);
1874 gen_op_iwmmxt_extru_T0_M0((insn & 7) << 3, 0xff);
1879 gen_op_iwmmxt_extrsw_T0_M0((insn & 3) << 4);
1881 gen_op_iwmmxt_extru_T0_M0((insn & 3) << 4, 0xffff);
1885 gen_op_iwmmxt_extru_T0_M0((insn & 1) << 5, ~0u);
1890 gen_movl_reg_T0(s, rd);
1892 case 0x117: case 0x517: case 0x917: case 0xd17: /* TEXTRC */
1893 if ((insn & 0x000ff008) != 0x0003f000)
1895 gen_op_iwmmxt_movl_T1_wCx(ARM_IWMMXT_wCASF);
1896 switch ((insn >> 22) & 3) {
1898 gen_op_shrl_T1_im(((insn & 7) << 2) + 0);
1901 gen_op_shrl_T1_im(((insn & 3) << 3) + 4);
1904 gen_op_shrl_T1_im(((insn & 1) << 4) + 12);
1909 gen_op_shll_T1_im(28);
1910 gen_set_nzcv(cpu_T[1]);
1912 case 0x401: case 0x405: case 0x409: case 0x40d: /* TBCST */
1913 rd = (insn >> 12) & 0xf;
1914 wrd = (insn >> 16) & 0xf;
1915 gen_movl_T0_reg(s, rd);
1916 switch ((insn >> 6) & 3) {
1918 gen_helper_iwmmxt_bcstb(cpu_M0, cpu_T[0]);
1921 gen_helper_iwmmxt_bcstw(cpu_M0, cpu_T[0]);
1924 gen_helper_iwmmxt_bcstl(cpu_M0, cpu_T[0]);
1929 gen_op_iwmmxt_movq_wRn_M0(wrd);
1930 gen_op_iwmmxt_set_mup();
1932 case 0x113: case 0x513: case 0x913: case 0xd13: /* TANDC */
1933 if ((insn & 0x000ff00f) != 0x0003f000)
1935 gen_op_iwmmxt_movl_T1_wCx(ARM_IWMMXT_wCASF);
1936 switch ((insn >> 22) & 3) {
1938 for (i = 0; i < 7; i ++) {
1939 gen_op_shll_T1_im(4);
1940 gen_op_andl_T0_T1();
1944 for (i = 0; i < 3; i ++) {
1945 gen_op_shll_T1_im(8);
1946 gen_op_andl_T0_T1();
1950 gen_op_shll_T1_im(16);
1951 gen_op_andl_T0_T1();
1956 gen_set_nzcv(cpu_T[0]);
1958 case 0x01c: case 0x41c: case 0x81c: case 0xc1c: /* WACC */
1959 wrd = (insn >> 12) & 0xf;
1960 rd0 = (insn >> 16) & 0xf;
1961 gen_op_iwmmxt_movq_M0_wRn(rd0);
1962 switch ((insn >> 22) & 3) {
1964 gen_helper_iwmmxt_addcb(cpu_M0, cpu_M0);
1967 gen_helper_iwmmxt_addcw(cpu_M0, cpu_M0);
1970 gen_helper_iwmmxt_addcl(cpu_M0, cpu_M0);
1975 gen_op_iwmmxt_movq_wRn_M0(wrd);
1976 gen_op_iwmmxt_set_mup();
1978 case 0x115: case 0x515: case 0x915: case 0xd15: /* TORC */
1979 if ((insn & 0x000ff00f) != 0x0003f000)
1981 gen_op_iwmmxt_movl_T1_wCx(ARM_IWMMXT_wCASF);
1982 switch ((insn >> 22) & 3) {
1984 for (i = 0; i < 7; i ++) {
1985 gen_op_shll_T1_im(4);
1990 for (i = 0; i < 3; i ++) {
1991 gen_op_shll_T1_im(8);
1996 gen_op_shll_T1_im(16);
2002 gen_set_nzcv(cpu_T[0]);
2004 case 0x103: case 0x503: case 0x903: case 0xd03: /* TMOVMSK */
2005 rd = (insn >> 12) & 0xf;
2006 rd0 = (insn >> 16) & 0xf;
2007 if ((insn & 0xf) != 0)
2009 gen_op_iwmmxt_movq_M0_wRn(rd0);
2010 switch ((insn >> 22) & 3) {
2012 gen_helper_iwmmxt_msbb(cpu_T[0], cpu_M0);
2015 gen_helper_iwmmxt_msbw(cpu_T[0], cpu_M0);
2018 gen_helper_iwmmxt_msbl(cpu_T[0], cpu_M0);
2023 gen_movl_reg_T0(s, rd);
2025 case 0x106: case 0x306: case 0x506: case 0x706: /* WCMPGT */
2026 case 0x906: case 0xb06: case 0xd06: case 0xf06:
2027 wrd = (insn >> 12) & 0xf;
2028 rd0 = (insn >> 16) & 0xf;
2029 rd1 = (insn >> 0) & 0xf;
2030 gen_op_iwmmxt_movq_M0_wRn(rd0);
2031 switch ((insn >> 22) & 3) {
2033 if (insn & (1 << 21))
2034 gen_op_iwmmxt_cmpgtsb_M0_wRn(rd1);
2036 gen_op_iwmmxt_cmpgtub_M0_wRn(rd1);
2039 if (insn & (1 << 21))
2040 gen_op_iwmmxt_cmpgtsw_M0_wRn(rd1);
2042 gen_op_iwmmxt_cmpgtuw_M0_wRn(rd1);
2045 if (insn & (1 << 21))
2046 gen_op_iwmmxt_cmpgtsl_M0_wRn(rd1);
2048 gen_op_iwmmxt_cmpgtul_M0_wRn(rd1);
2053 gen_op_iwmmxt_movq_wRn_M0(wrd);
2054 gen_op_iwmmxt_set_mup();
2055 gen_op_iwmmxt_set_cup();
2057 case 0x00e: case 0x20e: case 0x40e: case 0x60e: /* WUNPCKEL */
2058 case 0x80e: case 0xa0e: case 0xc0e: case 0xe0e:
2059 wrd = (insn >> 12) & 0xf;
2060 rd0 = (insn >> 16) & 0xf;
2061 gen_op_iwmmxt_movq_M0_wRn(rd0);
2062 switch ((insn >> 22) & 3) {
2064 if (insn & (1 << 21))
2065 gen_op_iwmmxt_unpacklsb_M0();
2067 gen_op_iwmmxt_unpacklub_M0();
2070 if (insn & (1 << 21))
2071 gen_op_iwmmxt_unpacklsw_M0();
2073 gen_op_iwmmxt_unpackluw_M0();
2076 if (insn & (1 << 21))
2077 gen_op_iwmmxt_unpacklsl_M0();
2079 gen_op_iwmmxt_unpacklul_M0();
2084 gen_op_iwmmxt_movq_wRn_M0(wrd);
2085 gen_op_iwmmxt_set_mup();
2086 gen_op_iwmmxt_set_cup();
2088 case 0x00c: case 0x20c: case 0x40c: case 0x60c: /* WUNPCKEH */
2089 case 0x80c: case 0xa0c: case 0xc0c: case 0xe0c:
2090 wrd = (insn >> 12) & 0xf;
2091 rd0 = (insn >> 16) & 0xf;
2092 gen_op_iwmmxt_movq_M0_wRn(rd0);
2093 switch ((insn >> 22) & 3) {
2095 if (insn & (1 << 21))
2096 gen_op_iwmmxt_unpackhsb_M0();
2098 gen_op_iwmmxt_unpackhub_M0();
2101 if (insn & (1 << 21))
2102 gen_op_iwmmxt_unpackhsw_M0();
2104 gen_op_iwmmxt_unpackhuw_M0();
2107 if (insn & (1 << 21))
2108 gen_op_iwmmxt_unpackhsl_M0();
2110 gen_op_iwmmxt_unpackhul_M0();
2115 gen_op_iwmmxt_movq_wRn_M0(wrd);
2116 gen_op_iwmmxt_set_mup();
2117 gen_op_iwmmxt_set_cup();
2119 case 0x204: case 0x604: case 0xa04: case 0xe04: /* WSRL */
2120 case 0x214: case 0x614: case 0xa14: case 0xe14:
2121 wrd = (insn >> 12) & 0xf;
2122 rd0 = (insn >> 16) & 0xf;
2123 gen_op_iwmmxt_movq_M0_wRn(rd0);
2124 if (gen_iwmmxt_shift(insn, 0xff))
2126 switch ((insn >> 22) & 3) {
2130 gen_helper_iwmmxt_srlw(cpu_M0, cpu_env, cpu_M0, cpu_T[0]);
2133 gen_helper_iwmmxt_srll(cpu_M0, cpu_env, cpu_M0, cpu_T[0]);
2136 gen_helper_iwmmxt_srlq(cpu_M0, cpu_env, cpu_M0, cpu_T[0]);
2139 gen_op_iwmmxt_movq_wRn_M0(wrd);
2140 gen_op_iwmmxt_set_mup();
2141 gen_op_iwmmxt_set_cup();
2143 case 0x004: case 0x404: case 0x804: case 0xc04: /* WSRA */
2144 case 0x014: case 0x414: case 0x814: case 0xc14:
2145 wrd = (insn >> 12) & 0xf;
2146 rd0 = (insn >> 16) & 0xf;
2147 gen_op_iwmmxt_movq_M0_wRn(rd0);
2148 if (gen_iwmmxt_shift(insn, 0xff))
2150 switch ((insn >> 22) & 3) {
2154 gen_helper_iwmmxt_sraw(cpu_M0, cpu_env, cpu_M0, cpu_T[0]);
2157 gen_helper_iwmmxt_sral(cpu_M0, cpu_env, cpu_M0, cpu_T[0]);
2160 gen_helper_iwmmxt_sraq(cpu_M0, cpu_env, cpu_M0, cpu_T[0]);
2163 gen_op_iwmmxt_movq_wRn_M0(wrd);
2164 gen_op_iwmmxt_set_mup();
2165 gen_op_iwmmxt_set_cup();
2167 case 0x104: case 0x504: case 0x904: case 0xd04: /* WSLL */
2168 case 0x114: case 0x514: case 0x914: case 0xd14:
2169 wrd = (insn >> 12) & 0xf;
2170 rd0 = (insn >> 16) & 0xf;
2171 gen_op_iwmmxt_movq_M0_wRn(rd0);
2172 if (gen_iwmmxt_shift(insn, 0xff))
2174 switch ((insn >> 22) & 3) {
2178 gen_helper_iwmmxt_sllw(cpu_M0, cpu_env, cpu_M0, cpu_T[0]);
2181 gen_helper_iwmmxt_slll(cpu_M0, cpu_env, cpu_M0, cpu_T[0]);
2184 gen_helper_iwmmxt_sllq(cpu_M0, cpu_env, cpu_M0, cpu_T[0]);
2187 gen_op_iwmmxt_movq_wRn_M0(wrd);
2188 gen_op_iwmmxt_set_mup();
2189 gen_op_iwmmxt_set_cup();
2191 case 0x304: case 0x704: case 0xb04: case 0xf04: /* WROR */
2192 case 0x314: case 0x714: case 0xb14: case 0xf14:
2193 wrd = (insn >> 12) & 0xf;
2194 rd0 = (insn >> 16) & 0xf;
2195 gen_op_iwmmxt_movq_M0_wRn(rd0);
2196 switch ((insn >> 22) & 3) {
2200 if (gen_iwmmxt_shift(insn, 0xf))
2202 gen_helper_iwmmxt_rorw(cpu_M0, cpu_env, cpu_M0, cpu_T[0]);
2205 if (gen_iwmmxt_shift(insn, 0x1f))
2207 gen_helper_iwmmxt_rorl(cpu_M0, cpu_env, cpu_M0, cpu_T[0]);
2210 if (gen_iwmmxt_shift(insn, 0x3f))
2212 gen_helper_iwmmxt_rorq(cpu_M0, cpu_env, cpu_M0, cpu_T[0]);
2215 gen_op_iwmmxt_movq_wRn_M0(wrd);
2216 gen_op_iwmmxt_set_mup();
2217 gen_op_iwmmxt_set_cup();
2219 case 0x116: case 0x316: case 0x516: case 0x716: /* WMIN */
2220 case 0x916: case 0xb16: case 0xd16: case 0xf16:
2221 wrd = (insn >> 12) & 0xf;
2222 rd0 = (insn >> 16) & 0xf;
2223 rd1 = (insn >> 0) & 0xf;
2224 gen_op_iwmmxt_movq_M0_wRn(rd0);
2225 switch ((insn >> 22) & 3) {
2227 if (insn & (1 << 21))
2228 gen_op_iwmmxt_minsb_M0_wRn(rd1);
2230 gen_op_iwmmxt_minub_M0_wRn(rd1);
2233 if (insn & (1 << 21))
2234 gen_op_iwmmxt_minsw_M0_wRn(rd1);
2236 gen_op_iwmmxt_minuw_M0_wRn(rd1);
2239 if (insn & (1 << 21))
2240 gen_op_iwmmxt_minsl_M0_wRn(rd1);
2242 gen_op_iwmmxt_minul_M0_wRn(rd1);
2247 gen_op_iwmmxt_movq_wRn_M0(wrd);
2248 gen_op_iwmmxt_set_mup();
2250 case 0x016: case 0x216: case 0x416: case 0x616: /* WMAX */
2251 case 0x816: case 0xa16: case 0xc16: case 0xe16:
2252 wrd = (insn >> 12) & 0xf;
2253 rd0 = (insn >> 16) & 0xf;
2254 rd1 = (insn >> 0) & 0xf;
2255 gen_op_iwmmxt_movq_M0_wRn(rd0);
2256 switch ((insn >> 22) & 3) {
2258 if (insn & (1 << 21))
2259 gen_op_iwmmxt_maxsb_M0_wRn(rd1);
2261 gen_op_iwmmxt_maxub_M0_wRn(rd1);
2264 if (insn & (1 << 21))
2265 gen_op_iwmmxt_maxsw_M0_wRn(rd1);
2267 gen_op_iwmmxt_maxuw_M0_wRn(rd1);
2270 if (insn & (1 << 21))
2271 gen_op_iwmmxt_maxsl_M0_wRn(rd1);
2273 gen_op_iwmmxt_maxul_M0_wRn(rd1);
2278 gen_op_iwmmxt_movq_wRn_M0(wrd);
2279 gen_op_iwmmxt_set_mup();
2281 case 0x002: case 0x102: case 0x202: case 0x302: /* WALIGNI */
2282 case 0x402: case 0x502: case 0x602: case 0x702:
2283 wrd = (insn >> 12) & 0xf;
2284 rd0 = (insn >> 16) & 0xf;
2285 rd1 = (insn >> 0) & 0xf;
2286 gen_op_iwmmxt_movq_M0_wRn(rd0);
2287 gen_op_movl_T0_im((insn >> 20) & 3);
2288 gen_op_iwmmxt_align_M0_T0_wRn(rd1);
2289 gen_op_iwmmxt_movq_wRn_M0(wrd);
2290 gen_op_iwmmxt_set_mup();
2292 case 0x01a: case 0x11a: case 0x21a: case 0x31a: /* WSUB */
2293 case 0x41a: case 0x51a: case 0x61a: case 0x71a:
2294 case 0x81a: case 0x91a: case 0xa1a: case 0xb1a:
2295 case 0xc1a: case 0xd1a: case 0xe1a: case 0xf1a:
2296 wrd = (insn >> 12) & 0xf;
2297 rd0 = (insn >> 16) & 0xf;
2298 rd1 = (insn >> 0) & 0xf;
2299 gen_op_iwmmxt_movq_M0_wRn(rd0);
2300 switch ((insn >> 20) & 0xf) {
2302 gen_op_iwmmxt_subnb_M0_wRn(rd1);
2305 gen_op_iwmmxt_subub_M0_wRn(rd1);
2308 gen_op_iwmmxt_subsb_M0_wRn(rd1);
2311 gen_op_iwmmxt_subnw_M0_wRn(rd1);
2314 gen_op_iwmmxt_subuw_M0_wRn(rd1);
2317 gen_op_iwmmxt_subsw_M0_wRn(rd1);
2320 gen_op_iwmmxt_subnl_M0_wRn(rd1);
2323 gen_op_iwmmxt_subul_M0_wRn(rd1);
2326 gen_op_iwmmxt_subsl_M0_wRn(rd1);
2331 gen_op_iwmmxt_movq_wRn_M0(wrd);
2332 gen_op_iwmmxt_set_mup();
2333 gen_op_iwmmxt_set_cup();
2335 case 0x01e: case 0x11e: case 0x21e: case 0x31e: /* WSHUFH */
2336 case 0x41e: case 0x51e: case 0x61e: case 0x71e:
2337 case 0x81e: case 0x91e: case 0xa1e: case 0xb1e:
2338 case 0xc1e: case 0xd1e: case 0xe1e: case 0xf1e:
2339 wrd = (insn >> 12) & 0xf;
2340 rd0 = (insn >> 16) & 0xf;
2341 gen_op_iwmmxt_movq_M0_wRn(rd0);
2342 gen_op_movl_T0_im(((insn >> 16) & 0xf0) | (insn & 0x0f));
2343 gen_helper_iwmmxt_shufh(cpu_M0, cpu_env, cpu_M0, cpu_T[0]);
2344 gen_op_iwmmxt_movq_wRn_M0(wrd);
2345 gen_op_iwmmxt_set_mup();
2346 gen_op_iwmmxt_set_cup();
2348 case 0x018: case 0x118: case 0x218: case 0x318: /* WADD */
2349 case 0x418: case 0x518: case 0x618: case 0x718:
2350 case 0x818: case 0x918: case 0xa18: case 0xb18:
2351 case 0xc18: case 0xd18: case 0xe18: case 0xf18:
2352 wrd = (insn >> 12) & 0xf;
2353 rd0 = (insn >> 16) & 0xf;
2354 rd1 = (insn >> 0) & 0xf;
2355 gen_op_iwmmxt_movq_M0_wRn(rd0);
2356 switch ((insn >> 20) & 0xf) {
2358 gen_op_iwmmxt_addnb_M0_wRn(rd1);
2361 gen_op_iwmmxt_addub_M0_wRn(rd1);
2364 gen_op_iwmmxt_addsb_M0_wRn(rd1);
2367 gen_op_iwmmxt_addnw_M0_wRn(rd1);
2370 gen_op_iwmmxt_adduw_M0_wRn(rd1);
2373 gen_op_iwmmxt_addsw_M0_wRn(rd1);
2376 gen_op_iwmmxt_addnl_M0_wRn(rd1);
2379 gen_op_iwmmxt_addul_M0_wRn(rd1);
2382 gen_op_iwmmxt_addsl_M0_wRn(rd1);
2387 gen_op_iwmmxt_movq_wRn_M0(wrd);
2388 gen_op_iwmmxt_set_mup();
2389 gen_op_iwmmxt_set_cup();
2391 case 0x008: case 0x108: case 0x208: case 0x308: /* WPACK */
2392 case 0x408: case 0x508: case 0x608: case 0x708:
2393 case 0x808: case 0x908: case 0xa08: case 0xb08:
2394 case 0xc08: case 0xd08: case 0xe08: case 0xf08:
2395 wrd = (insn >> 12) & 0xf;
2396 rd0 = (insn >> 16) & 0xf;
2397 rd1 = (insn >> 0) & 0xf;
2398 gen_op_iwmmxt_movq_M0_wRn(rd0);
2399 if (!(insn & (1 << 20)))
2401 switch ((insn >> 22) & 3) {
2405 if (insn & (1 << 21))
2406 gen_op_iwmmxt_packsw_M0_wRn(rd1);
2408 gen_op_iwmmxt_packuw_M0_wRn(rd1);
2411 if (insn & (1 << 21))
2412 gen_op_iwmmxt_packsl_M0_wRn(rd1);
2414 gen_op_iwmmxt_packul_M0_wRn(rd1);
2417 if (insn & (1 << 21))
2418 gen_op_iwmmxt_packsq_M0_wRn(rd1);
2420 gen_op_iwmmxt_packuq_M0_wRn(rd1);
2423 gen_op_iwmmxt_movq_wRn_M0(wrd);
2424 gen_op_iwmmxt_set_mup();
2425 gen_op_iwmmxt_set_cup();
2427 case 0x201: case 0x203: case 0x205: case 0x207:
2428 case 0x209: case 0x20b: case 0x20d: case 0x20f:
2429 case 0x211: case 0x213: case 0x215: case 0x217:
2430 case 0x219: case 0x21b: case 0x21d: case 0x21f:
2431 wrd = (insn >> 5) & 0xf;
2432 rd0 = (insn >> 12) & 0xf;
2433 rd1 = (insn >> 0) & 0xf;
2434 if (rd0 == 0xf || rd1 == 0xf)
2436 gen_op_iwmmxt_movq_M0_wRn(wrd);
2437 switch ((insn >> 16) & 0xf) {
2438 case 0x0: /* TMIA */
2439 gen_movl_T0_reg(s, rd0);
2440 gen_movl_T1_reg(s, rd1);
2441 gen_op_iwmmxt_muladdsl_M0_T0_T1();
2443 case 0x8: /* TMIAPH */
2444 gen_movl_T0_reg(s, rd0);
2445 gen_movl_T1_reg(s, rd1);
2446 gen_op_iwmmxt_muladdsw_M0_T0_T1();
2448 case 0xc: case 0xd: case 0xe: case 0xf: /* TMIAxy */
2449 gen_movl_T1_reg(s, rd0);
2450 if (insn & (1 << 16))
2451 gen_op_shrl_T1_im(16);
2452 gen_op_movl_T0_T1();
2453 gen_movl_T1_reg(s, rd1);
2454 if (insn & (1 << 17))
2455 gen_op_shrl_T1_im(16);
2456 gen_op_iwmmxt_muladdswl_M0_T0_T1();
2461 gen_op_iwmmxt_movq_wRn_M0(wrd);
2462 gen_op_iwmmxt_set_mup();
2471 /* Disassemble an XScale DSP instruction. Returns nonzero if an error occured
2472 (ie. an undefined instruction). */
2473 static int disas_dsp_insn(CPUState *env, DisasContext *s, uint32_t insn)
2475 int acc, rd0, rd1, rdhi, rdlo;
2477 if ((insn & 0x0ff00f10) == 0x0e200010) {
2478 /* Multiply with Internal Accumulate Format */
2479 rd0 = (insn >> 12) & 0xf;
2481 acc = (insn >> 5) & 7;
2486 switch ((insn >> 16) & 0xf) {
2488 gen_movl_T0_reg(s, rd0);
2489 gen_movl_T1_reg(s, rd1);
2490 gen_op_iwmmxt_muladdsl_M0_T0_T1();
2492 case 0x8: /* MIAPH */
2493 gen_movl_T0_reg(s, rd0);
2494 gen_movl_T1_reg(s, rd1);
2495 gen_op_iwmmxt_muladdsw_M0_T0_T1();
2497 case 0xc: /* MIABB */
2498 case 0xd: /* MIABT */
2499 case 0xe: /* MIATB */
2500 case 0xf: /* MIATT */
2501 gen_movl_T1_reg(s, rd0);
2502 if (insn & (1 << 16))
2503 gen_op_shrl_T1_im(16);
2504 gen_op_movl_T0_T1();
2505 gen_movl_T1_reg(s, rd1);
2506 if (insn & (1 << 17))
2507 gen_op_shrl_T1_im(16);
2508 gen_op_iwmmxt_muladdswl_M0_T0_T1();
2514 gen_op_iwmmxt_movq_wRn_M0(acc);
2518 if ((insn & 0x0fe00ff8) == 0x0c400000) {
2519 /* Internal Accumulator Access Format */
2520 rdhi = (insn >> 16) & 0xf;
2521 rdlo = (insn >> 12) & 0xf;
2527 if (insn & ARM_CP_RW_BIT) { /* MRA */
2528 gen_iwmmxt_movl_T0_T1_wRn(acc);
2529 gen_movl_reg_T0(s, rdlo);
2530 gen_op_movl_T0_im((1 << (40 - 32)) - 1);
2531 gen_op_andl_T0_T1();
2532 gen_movl_reg_T0(s, rdhi);
2534 gen_movl_T0_reg(s, rdlo);
2535 gen_movl_T1_reg(s, rdhi);
2536 gen_iwmmxt_movl_wRn_T0_T1(acc);
2544 /* Disassemble system coprocessor instruction. Return nonzero if
2545 instruction is not defined. */
2546 static int disas_cp_insn(CPUState *env, DisasContext *s, uint32_t insn)
2549 uint32_t rd = (insn >> 12) & 0xf;
2550 uint32_t cp = (insn >> 8) & 0xf;
2555 if (insn & ARM_CP_RW_BIT) {
2556 if (!env->cp[cp].cp_read)
2558 gen_set_pc_im(s->pc);
2560 gen_helper_get_cp(tmp, cpu_env, tcg_const_i32(insn));
2561 store_reg(s, rd, tmp);
2563 if (!env->cp[cp].cp_write)
2565 gen_set_pc_im(s->pc);
2566 tmp = load_reg(s, rd);
2567 gen_helper_set_cp(cpu_env, tcg_const_i32(insn), tmp);
2573 static int cp15_user_ok(uint32_t insn)
2575 int cpn = (insn >> 16) & 0xf;
2576 int cpm = insn & 0xf;
2577 int op = ((insn >> 5) & 7) | ((insn >> 18) & 0x38);
2579 if (cpn == 13 && cpm == 0) {
2581 if (op == 2 || (op == 3 && (insn & ARM_CP_RW_BIT)))
2585 /* ISB, DSB, DMB. */
2586 if ((cpm == 5 && op == 4)
2587 || (cpm == 10 && (op == 4 || op == 5)))
2593 /* Disassemble system coprocessor (cp15) instruction. Return nonzero if
2594 instruction is not defined. */
2595 static int disas_cp15_insn(CPUState *env, DisasContext *s, uint32_t insn)
2600 /* M profile cores use memory mapped registers instead of cp15. */
2601 if (arm_feature(env, ARM_FEATURE_M))
2604 if ((insn & (1 << 25)) == 0) {
2605 if (insn & (1 << 20)) {
2609 /* mcrr. Used for block cache operations, so implement as no-op. */
2612 if ((insn & (1 << 4)) == 0) {
2616 if (IS_USER(s) && !cp15_user_ok(insn)) {
2619 if ((insn & 0x0fff0fff) == 0x0e070f90
2620 || (insn & 0x0fff0fff) == 0x0e070f58) {
2621 /* Wait for interrupt. */
2622 gen_set_pc_im(s->pc);
2623 s->is_jmp = DISAS_WFI;
2626 rd = (insn >> 12) & 0xf;
2627 if (insn & ARM_CP_RW_BIT) {
2629 gen_helper_get_cp15(tmp, cpu_env, tcg_const_i32(insn));
2630 /* If the destination register is r15 then sets condition codes. */
2632 store_reg(s, rd, tmp);
2636 tmp = load_reg(s, rd);
2637 gen_helper_set_cp15(cpu_env, tcg_const_i32(insn), tmp);
2639 /* Normally we would always end the TB here, but Linux
2640 * arch/arm/mach-pxa/sleep.S expects two instructions following
2641 * an MMU enable to execute from cache. Imitate this behaviour. */
2642 if (!arm_feature(env, ARM_FEATURE_XSCALE) ||
2643 (insn & 0x0fff0fff) != 0x0e010f10)
2649 #define VFP_REG_SHR(x, n) (((n) > 0) ? (x) >> (n) : (x) << -(n))
2650 #define VFP_SREG(insn, bigbit, smallbit) \
2651 ((VFP_REG_SHR(insn, bigbit - 1) & 0x1e) | (((insn) >> (smallbit)) & 1))
2652 #define VFP_DREG(reg, insn, bigbit, smallbit) do { \
2653 if (arm_feature(env, ARM_FEATURE_VFP3)) { \
2654 reg = (((insn) >> (bigbit)) & 0x0f) \
2655 | (((insn) >> ((smallbit) - 4)) & 0x10); \
2657 if (insn & (1 << (smallbit))) \
2659 reg = ((insn) >> (bigbit)) & 0x0f; \
2662 #define VFP_SREG_D(insn) VFP_SREG(insn, 12, 22)
2663 #define VFP_DREG_D(reg, insn) VFP_DREG(reg, insn, 12, 22)
2664 #define VFP_SREG_N(insn) VFP_SREG(insn, 16, 7)
2665 #define VFP_DREG_N(reg, insn) VFP_DREG(reg, insn, 16, 7)
2666 #define VFP_SREG_M(insn) VFP_SREG(insn, 0, 5)
2667 #define VFP_DREG_M(reg, insn) VFP_DREG(reg, insn, 0, 5)
2669 /* Move between integer and VFP cores. */
2670 static TCGv gen_vfp_mrs(void)
2672 TCGv tmp = new_tmp();
2673 tcg_gen_mov_i32(tmp, cpu_F0s);
2677 static void gen_vfp_msr(TCGv tmp)
2679 tcg_gen_mov_i32(cpu_F0s, tmp);
2684 vfp_enabled(CPUState * env)
2686 return ((env->vfp.xregs[ARM_VFP_FPEXC] & (1 << 30)) != 0);
2689 static void gen_neon_dup_u8(TCGv var, int shift)
2691 TCGv tmp = new_tmp();
2693 tcg_gen_shri_i32(var, var, shift);
2694 tcg_gen_ext8u_i32(var, var);
2695 tcg_gen_shli_i32(tmp, var, 8);
2696 tcg_gen_or_i32(var, var, tmp);
2697 tcg_gen_shli_i32(tmp, var, 16);
2698 tcg_gen_or_i32(var, var, tmp);
2702 static void gen_neon_dup_low16(TCGv var)
2704 TCGv tmp = new_tmp();
2705 tcg_gen_ext16u_i32(var, var);
2706 tcg_gen_shli_i32(tmp, var, 16);
2707 tcg_gen_or_i32(var, var, tmp);
2711 static void gen_neon_dup_high16(TCGv var)
2713 TCGv tmp = new_tmp();
2714 tcg_gen_andi_i32(var, var, 0xffff0000);
2715 tcg_gen_shri_i32(tmp, var, 16);
2716 tcg_gen_or_i32(var, var, tmp);
2720 /* Disassemble a VFP instruction. Returns nonzero if an error occured
2721 (ie. an undefined instruction). */
2722 static int disas_vfp_insn(CPUState * env, DisasContext *s, uint32_t insn)
2724 uint32_t rd, rn, rm, op, i, n, offset, delta_d, delta_m, bank_mask;
2729 if (!arm_feature(env, ARM_FEATURE_VFP))
2732 if (!vfp_enabled(env)) {
2733 /* VFP disabled. Only allow fmxr/fmrx to/from some control regs. */
2734 if ((insn & 0x0fe00fff) != 0x0ee00a10)
2736 rn = (insn >> 16) & 0xf;
2737 if (rn != ARM_VFP_FPSID && rn != ARM_VFP_FPEXC
2738 && rn != ARM_VFP_MVFR1 && rn != ARM_VFP_MVFR0)
2741 dp = ((insn & 0xf00) == 0xb00);
2742 switch ((insn >> 24) & 0xf) {
2744 if (insn & (1 << 4)) {
2745 /* single register transfer */
2746 rd = (insn >> 12) & 0xf;
2751 VFP_DREG_N(rn, insn);
2754 if (insn & 0x00c00060
2755 && !arm_feature(env, ARM_FEATURE_NEON))
2758 pass = (insn >> 21) & 1;
2759 if (insn & (1 << 22)) {
2761 offset = ((insn >> 5) & 3) * 8;
2762 } else if (insn & (1 << 5)) {
2764 offset = (insn & (1 << 6)) ? 16 : 0;
2769 if (insn & ARM_CP_RW_BIT) {
2771 tmp = neon_load_reg(rn, pass);
2775 tcg_gen_shri_i32(tmp, tmp, offset);
2776 if (insn & (1 << 23))
2782 if (insn & (1 << 23)) {
2784 tcg_gen_shri_i32(tmp, tmp, 16);
2790 tcg_gen_sari_i32(tmp, tmp, 16);
2799 store_reg(s, rd, tmp);
2802 tmp = load_reg(s, rd);
2803 if (insn & (1 << 23)) {
2806 gen_neon_dup_u8(tmp, 0);
2807 } else if (size == 1) {
2808 gen_neon_dup_low16(tmp);
2811 tcg_gen_mov_i32(tmp2, tmp);
2812 neon_store_reg(rn, 0, tmp2);
2813 neon_store_reg(rn, 0, tmp);
2818 tmp2 = neon_load_reg(rn, pass);
2819 gen_bfi(tmp, tmp2, tmp, offset, 0xff);
2823 tmp2 = neon_load_reg(rn, pass);
2824 gen_bfi(tmp, tmp2, tmp, offset, 0xffff);
2830 neon_store_reg(rn, pass, tmp);
2834 if ((insn & 0x6f) != 0x00)
2836 rn = VFP_SREG_N(insn);
2837 if (insn & ARM_CP_RW_BIT) {
2839 if (insn & (1 << 21)) {
2840 /* system register */
2845 /* VFP2 allows access to FSID from userspace.
2846 VFP3 restricts all id registers to privileged
2849 && arm_feature(env, ARM_FEATURE_VFP3))
2851 tmp = load_cpu_field(vfp.xregs[rn]);
2856 tmp = load_cpu_field(vfp.xregs[rn]);
2858 case ARM_VFP_FPINST:
2859 case ARM_VFP_FPINST2:
2860 /* Not present in VFP3. */
2862 || arm_feature(env, ARM_FEATURE_VFP3))
2864 tmp = load_cpu_field(vfp.xregs[rn]);
2868 tmp = load_cpu_field(vfp.xregs[ARM_VFP_FPSCR]);
2869 tcg_gen_andi_i32(tmp, tmp, 0xf0000000);
2872 gen_helper_vfp_get_fpscr(tmp, cpu_env);
2878 || !arm_feature(env, ARM_FEATURE_VFP3))
2880 tmp = load_cpu_field(vfp.xregs[rn]);
2886 gen_mov_F0_vreg(0, rn);
2887 tmp = gen_vfp_mrs();
2890 /* Set the 4 flag bits in the CPSR. */
2894 store_reg(s, rd, tmp);
2898 tmp = load_reg(s, rd);
2899 if (insn & (1 << 21)) {
2901 /* system register */
2906 /* Writes are ignored. */
2909 gen_helper_vfp_set_fpscr(cpu_env, tmp);
2916 store_cpu_field(tmp, vfp.xregs[rn]);
2919 case ARM_VFP_FPINST:
2920 case ARM_VFP_FPINST2:
2921 store_cpu_field(tmp, vfp.xregs[rn]);
2928 gen_mov_vreg_F0(0, rn);
2933 /* data processing */
2934 /* The opcode is in bits 23, 21, 20 and 6. */
2935 op = ((insn >> 20) & 8) | ((insn >> 19) & 6) | ((insn >> 6) & 1);
2939 rn = ((insn >> 15) & 0x1e) | ((insn >> 7) & 1);
2941 /* rn is register number */
2942 VFP_DREG_N(rn, insn);
2945 if (op == 15 && (rn == 15 || rn > 17)) {
2946 /* Integer or single precision destination. */
2947 rd = VFP_SREG_D(insn);
2949 VFP_DREG_D(rd, insn);
2952 if (op == 15 && (rn == 16 || rn == 17)) {
2953 /* Integer source. */
2954 rm = ((insn << 1) & 0x1e) | ((insn >> 5) & 1);
2956 VFP_DREG_M(rm, insn);
2959 rn = VFP_SREG_N(insn);
2960 if (op == 15 && rn == 15) {
2961 /* Double precision destination. */
2962 VFP_DREG_D(rd, insn);
2964 rd = VFP_SREG_D(insn);
2966 rm = VFP_SREG_M(insn);
2969 veclen = env->vfp.vec_len;
2970 if (op == 15 && rn > 3)
2973 /* Shut up compiler warnings. */
2984 /* Figure out what type of vector operation this is. */
2985 if ((rd & bank_mask) == 0) {
2990 delta_d = (env->vfp.vec_stride >> 1) + 1;
2992 delta_d = env->vfp.vec_stride + 1;
2994 if ((rm & bank_mask) == 0) {
2995 /* mixed scalar/vector */
3004 /* Load the initial operands. */
3009 /* Integer source */
3010 gen_mov_F0_vreg(0, rm);
3015 gen_mov_F0_vreg(dp, rd);
3016 gen_mov_F1_vreg(dp, rm);
3020 /* Compare with zero */
3021 gen_mov_F0_vreg(dp, rd);
3028 /* Source and destination the same. */
3029 gen_mov_F0_vreg(dp, rd);
3032 /* One source operand. */
3033 gen_mov_F0_vreg(dp, rm);
3037 /* Two source operands. */
3038 gen_mov_F0_vreg(dp, rn);
3039 gen_mov_F1_vreg(dp, rm);
3043 /* Perform the calculation. */
3045 case 0: /* mac: fd + (fn * fm) */
3047 gen_mov_F1_vreg(dp, rd);
3050 case 1: /* nmac: fd - (fn * fm) */
3053 gen_mov_F1_vreg(dp, rd);
3056 case 2: /* msc: -fd + (fn * fm) */
3058 gen_mov_F1_vreg(dp, rd);
3061 case 3: /* nmsc: -fd - (fn * fm) */
3063 gen_mov_F1_vreg(dp, rd);
3067 case 4: /* mul: fn * fm */
3070 case 5: /* nmul: -(fn * fm) */
3074 case 6: /* add: fn + fm */
3077 case 7: /* sub: fn - fm */
3080 case 8: /* div: fn / fm */
3083 case 14: /* fconst */
3084 if (!arm_feature(env, ARM_FEATURE_VFP3))
3087 n = (insn << 12) & 0x80000000;
3088 i = ((insn >> 12) & 0x70) | (insn & 0xf);
3095 tcg_gen_movi_i64(cpu_F0d, ((uint64_t)n) << 32);
3102 tcg_gen_movi_i32(cpu_F0s, n);
3105 case 15: /* extension space */
3128 case 11: /* cmpez */
3132 case 15: /* single<->double conversion */
3134 gen_helper_vfp_fcvtsd(cpu_F0s, cpu_F0d, cpu_env);
3136 gen_helper_vfp_fcvtds(cpu_F0d, cpu_F0s, cpu_env);
3138 case 16: /* fuito */
3141 case 17: /* fsito */
3144 case 20: /* fshto */
3145 if (!arm_feature(env, ARM_FEATURE_VFP3))
3147 gen_vfp_shto(dp, rm);
3149 case 21: /* fslto */
3150 if (!arm_feature(env, ARM_FEATURE_VFP3))
3152 gen_vfp_slto(dp, rm);
3154 case 22: /* fuhto */
3155 if (!arm_feature(env, ARM_FEATURE_VFP3))
3157 gen_vfp_uhto(dp, rm);
3159 case 23: /* fulto */
3160 if (!arm_feature(env, ARM_FEATURE_VFP3))
3162 gen_vfp_ulto(dp, rm);
3164 case 24: /* ftoui */
3167 case 25: /* ftouiz */
3170 case 26: /* ftosi */
3173 case 27: /* ftosiz */
3176 case 28: /* ftosh */
3177 if (!arm_feature(env, ARM_FEATURE_VFP3))
3179 gen_vfp_tosh(dp, rm);
3181 case 29: /* ftosl */
3182 if (!arm_feature(env, ARM_FEATURE_VFP3))
3184 gen_vfp_tosl(dp, rm);
3186 case 30: /* ftouh */
3187 if (!arm_feature(env, ARM_FEATURE_VFP3))
3189 gen_vfp_touh(dp, rm);
3191 case 31: /* ftoul */
3192 if (!arm_feature(env, ARM_FEATURE_VFP3))
3194 gen_vfp_toul(dp, rm);
3196 default: /* undefined */
3197 printf ("rn:%d\n", rn);
3201 default: /* undefined */
3202 printf ("op:%d\n", op);
3206 /* Write back the result. */
3207 if (op == 15 && (rn >= 8 && rn <= 11))
3208 ; /* Comparison, do nothing. */
3209 else if (op == 15 && rn > 17)
3210 /* Integer result. */
3211 gen_mov_vreg_F0(0, rd);
3212 else if (op == 15 && rn == 15)
3214 gen_mov_vreg_F0(!dp, rd);
3216 gen_mov_vreg_F0(dp, rd);
3218 /* break out of the loop if we have finished */
3222 if (op == 15 && delta_m == 0) {
3223 /* single source one-many */
3225 rd = ((rd + delta_d) & (bank_mask - 1))
3227 gen_mov_vreg_F0(dp, rd);
3231 /* Setup the next operands. */
3233 rd = ((rd + delta_d) & (bank_mask - 1))
3237 /* One source operand. */
3238 rm = ((rm + delta_m) & (bank_mask - 1))
3240 gen_mov_F0_vreg(dp, rm);
3242 /* Two source operands. */
3243 rn = ((rn + delta_d) & (bank_mask - 1))
3245 gen_mov_F0_vreg(dp, rn);
3247 rm = ((rm + delta_m) & (bank_mask - 1))
3249 gen_mov_F1_vreg(dp, rm);
3257 if (dp && (insn & 0x03e00000) == 0x00400000) {
3258 /* two-register transfer */
3259 rn = (insn >> 16) & 0xf;
3260 rd = (insn >> 12) & 0xf;
3262 VFP_DREG_M(rm, insn);
3264 rm = VFP_SREG_M(insn);
3267 if (insn & ARM_CP_RW_BIT) {
3270 gen_mov_F0_vreg(0, rm * 2);
3271 tmp = gen_vfp_mrs();
3272 store_reg(s, rd, tmp);
3273 gen_mov_F0_vreg(0, rm * 2 + 1);
3274 tmp = gen_vfp_mrs();
3275 store_reg(s, rn, tmp);
3277 gen_mov_F0_vreg(0, rm);
3278 tmp = gen_vfp_mrs();
3279 store_reg(s, rn, tmp);
3280 gen_mov_F0_vreg(0, rm + 1);
3281 tmp = gen_vfp_mrs();
3282 store_reg(s, rd, tmp);
3287 tmp = load_reg(s, rd);
3289 gen_mov_vreg_F0(0, rm * 2);
3290 tmp = load_reg(s, rn);
3292 gen_mov_vreg_F0(0, rm * 2 + 1);
3294 tmp = load_reg(s, rn);
3296 gen_mov_vreg_F0(0, rm);
3297 tmp = load_reg(s, rd);
3299 gen_mov_vreg_F0(0, rm + 1);
3304 rn = (insn >> 16) & 0xf;
3306 VFP_DREG_D(rd, insn);
3308 rd = VFP_SREG_D(insn);
3309 if (s->thumb && rn == 15) {
3310 gen_op_movl_T1_im(s->pc & ~2);
3312 gen_movl_T1_reg(s, rn);
3314 if ((insn & 0x01200000) == 0x01000000) {
3315 /* Single load/store */
3316 offset = (insn & 0xff) << 2;
3317 if ((insn & (1 << 23)) == 0)
3319 gen_op_addl_T1_im(offset);
3320 if (insn & (1 << 20)) {
3322 gen_mov_vreg_F0(dp, rd);
3324 gen_mov_F0_vreg(dp, rd);
3328 /* load/store multiple */
3330 n = (insn >> 1) & 0x7f;
3334 if (insn & (1 << 24)) /* pre-decrement */
3335 gen_op_addl_T1_im(-((insn & 0xff) << 2));
3341 for (i = 0; i < n; i++) {
3342 if (insn & ARM_CP_RW_BIT) {
3345 gen_mov_vreg_F0(dp, rd + i);
3348 gen_mov_F0_vreg(dp, rd + i);
3351 gen_op_addl_T1_im(offset);
3353 if (insn & (1 << 21)) {
3355 if (insn & (1 << 24))
3356 offset = -offset * n;
3357 else if (dp && (insn & 1))
3363 gen_op_addl_T1_im(offset);
3364 gen_movl_reg_T1(s, rn);
3370 /* Should never happen. */
3376 static inline void gen_goto_tb(DisasContext *s, int n, uint32_t dest)
3378 TranslationBlock *tb;
3381 if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK)) {
3383 gen_set_pc_im(dest);
3384 tcg_gen_exit_tb((long)tb + n);
3386 gen_set_pc_im(dest);
3391 static inline void gen_jmp (DisasContext *s, uint32_t dest)
3393 if (unlikely(s->singlestep_enabled)) {
3394 /* An indirect jump so that we still trigger the debug exception. */
3399 gen_goto_tb(s, 0, dest);
3400 s->is_jmp = DISAS_TB_JUMP;
3404 static inline void gen_mulxy(TCGv t0, TCGv t1, int x, int y)
3407 tcg_gen_sari_i32(t0, t0, 16);
3411 tcg_gen_sari_i32(t1, t1, 16);
3414 tcg_gen_mul_i32(t0, t0, t1);
3417 /* Return the mask of PSR bits set by a MSR instruction. */
3418 static uint32_t msr_mask(CPUState *env, DisasContext *s, int flags, int spsr) {
3422 if (flags & (1 << 0))
3424 if (flags & (1 << 1))
3426 if (flags & (1 << 2))
3428 if (flags & (1 << 3))
3431 /* Mask out undefined bits. */
3432 mask &= ~CPSR_RESERVED;
3433 if (!arm_feature(env, ARM_FEATURE_V6))
3434 mask &= ~(CPSR_E | CPSR_GE);
3435 if (!arm_feature(env, ARM_FEATURE_THUMB2))
3437 /* Mask out execution state bits. */
3440 /* Mask out privileged bits. */
3446 /* Returns nonzero if access to the PSR is not permitted. */
3447 static int gen_set_psr_T0(DisasContext *s, uint32_t mask, int spsr)
3451 /* ??? This is also undefined in system mode. */
3455 tmp = load_cpu_field(spsr);
3456 tcg_gen_andi_i32(tmp, tmp, ~mask);
3457 tcg_gen_andi_i32(cpu_T[0], cpu_T[0], mask);
3458 tcg_gen_or_i32(tmp, tmp, cpu_T[0]);
3459 store_cpu_field(tmp, spsr);
3461 gen_set_cpsr(cpu_T[0], mask);
3467 /* Generate an old-style exception return. */
3468 static void gen_exception_return(DisasContext *s)
3471 gen_movl_reg_T0(s, 15);
3472 tmp = load_cpu_field(spsr);
3473 gen_set_cpsr(tmp, 0xffffffff);
3475 s->is_jmp = DISAS_UPDATE;
3478 /* Generate a v6 exception return. Marks both values as dead. */
3479 static void gen_rfe(DisasContext *s, TCGv pc, TCGv cpsr)
3481 gen_set_cpsr(cpsr, 0xffffffff);
3483 store_reg(s, 15, pc);
3484 s->is_jmp = DISAS_UPDATE;
3488 gen_set_condexec (DisasContext *s)
3490 if (s->condexec_mask) {
3491 uint32_t val = (s->condexec_cond << 4) | (s->condexec_mask >> 1);
3492 TCGv tmp = new_tmp();
3493 tcg_gen_movi_i32(tmp, val);
3494 store_cpu_field(tmp, condexec_bits);
3498 static void gen_nop_hint(DisasContext *s, int val)
3502 gen_set_pc_im(s->pc);
3503 s->is_jmp = DISAS_WFI;
3507 /* TODO: Implement SEV and WFE. May help SMP performance. */
3513 /* These macros help make the code more readable when migrating from the
3514 old dyngen helpers. They should probably be removed when
3515 T0/T1 are removed. */
3516 #define CPU_T001 cpu_T[0], cpu_T[0], cpu_T[1]
3517 #define CPU_T0E01 cpu_T[0], cpu_env, cpu_T[0], cpu_T[1]
3519 #define CPU_V001 cpu_V0, cpu_V0, cpu_V1
3521 static inline int gen_neon_add(int size)
3524 case 0: gen_helper_neon_add_u8(CPU_T001); break;
3525 case 1: gen_helper_neon_add_u16(CPU_T001); break;
3526 case 2: gen_op_addl_T0_T1(); break;
3532 static inline void gen_neon_rsb(int size)
3535 case 0: gen_helper_neon_sub_u8(cpu_T[0], cpu_T[1], cpu_T[0]); break;
3536 case 1: gen_helper_neon_sub_u16(cpu_T[0], cpu_T[1], cpu_T[0]); break;
3537 case 2: gen_op_rsbl_T0_T1(); break;
3542 /* 32-bit pairwise ops end up the same as the elementwise versions. */
3543 #define gen_helper_neon_pmax_s32 gen_helper_neon_max_s32
3544 #define gen_helper_neon_pmax_u32 gen_helper_neon_max_u32
3545 #define gen_helper_neon_pmin_s32 gen_helper_neon_min_s32
3546 #define gen_helper_neon_pmin_u32 gen_helper_neon_min_u32
3548 /* FIXME: This is wrong. They set the wrong overflow bit. */
3549 #define gen_helper_neon_qadd_s32(a, e, b, c) gen_helper_add_saturate(a, b, c)
3550 #define gen_helper_neon_qadd_u32(a, e, b, c) gen_helper_add_usaturate(a, b, c)
3551 #define gen_helper_neon_qsub_s32(a, e, b, c) gen_helper_sub_saturate(a, b, c)
3552 #define gen_helper_neon_qsub_u32(a, e, b, c) gen_helper_sub_usaturate(a, b, c)
3554 #define GEN_NEON_INTEGER_OP_ENV(name) do { \
3555 switch ((size << 1) | u) { \
3557 gen_helper_neon_##name##_s8(cpu_T[0], cpu_env, cpu_T[0], cpu_T[1]); \
3560 gen_helper_neon_##name##_u8(cpu_T[0], cpu_env, cpu_T[0], cpu_T[1]); \
3563 gen_helper_neon_##name##_s16(cpu_T[0], cpu_env, cpu_T[0], cpu_T[1]); \
3566 gen_helper_neon_##name##_u16(cpu_T[0], cpu_env, cpu_T[0], cpu_T[1]); \
3569 gen_helper_neon_##name##_s32(cpu_T[0], cpu_env, cpu_T[0], cpu_T[1]); \
3572 gen_helper_neon_##name##_u32(cpu_T[0], cpu_env, cpu_T[0], cpu_T[1]); \
3574 default: return 1; \
3577 #define GEN_NEON_INTEGER_OP(name) do { \
3578 switch ((size << 1) | u) { \
3580 gen_helper_neon_##name##_s8(cpu_T[0], cpu_T[0], cpu_T[1]); \
3583 gen_helper_neon_##name##_u8(cpu_T[0], cpu_T[0], cpu_T[1]); \
3586 gen_helper_neon_##name##_s16(cpu_T[0], cpu_T[0], cpu_T[1]); \
3589 gen_helper_neon_##name##_u16(cpu_T[0], cpu_T[0], cpu_T[1]); \
3592 gen_helper_neon_##name##_s32(cpu_T[0], cpu_T[0], cpu_T[1]); \
3595 gen_helper_neon_##name##_u32(cpu_T[0], cpu_T[0], cpu_T[1]); \
3597 default: return 1; \
3601 gen_neon_movl_scratch_T0(int scratch)
3605 offset = offsetof(CPUARMState, vfp.scratch[scratch]);
3606 tcg_gen_st_i32(cpu_T[0], cpu_env, offset);
3610 gen_neon_movl_scratch_T1(int scratch)
3614 offset = offsetof(CPUARMState, vfp.scratch[scratch]);
3615 tcg_gen_st_i32(cpu_T[1], cpu_env, offset);
3619 gen_neon_movl_T0_scratch(int scratch)
3623 offset = offsetof(CPUARMState, vfp.scratch[scratch]);
3624 tcg_gen_ld_i32(cpu_T[0], cpu_env, offset);
3628 gen_neon_movl_T1_scratch(int scratch)
3632 offset = offsetof(CPUARMState, vfp.scratch[scratch]);
3633 tcg_gen_ld_i32(cpu_T[1], cpu_env, offset);
3636 static inline void gen_neon_get_scalar(int size, int reg)
3639 NEON_GET_REG(T0, reg >> 1, reg & 1);
3641 NEON_GET_REG(T0, reg >> 2, (reg >> 1) & 1);
3643 gen_neon_dup_low16(cpu_T[0]);
3645 gen_neon_dup_high16(cpu_T[0]);
3649 static void gen_neon_unzip(int reg, int q, int tmp, int size)
3653 for (n = 0; n < q + 1; n += 2) {
3654 NEON_GET_REG(T0, reg, n);
3655 NEON_GET_REG(T0, reg, n + n);
3657 case 0: gen_helper_neon_unzip_u8(); break;
3658 case 1: gen_helper_neon_zip_u16(); break; /* zip and unzip are the same. */
3659 case 2: /* no-op */; break;
3662 gen_neon_movl_scratch_T0(tmp + n);
3663 gen_neon_movl_scratch_T1(tmp + n + 1);
3671 } neon_ls_element_type[11] = {
3685 /* Translate a NEON load/store element instruction. Return nonzero if the
3686 instruction is invalid. */
3687 static int disas_neon_ls_insn(CPUState * env, DisasContext *s, uint32_t insn)
3703 if (!vfp_enabled(env))
3705 VFP_DREG_D(rd, insn);
3706 rn = (insn >> 16) & 0xf;
3708 load = (insn & (1 << 21)) != 0;
3709 if ((insn & (1 << 23)) == 0) {
3710 /* Load store all elements. */
3711 op = (insn >> 8) & 0xf;
3712 size = (insn >> 6) & 3;
3713 if (op > 10 || size == 3)
3715 nregs = neon_ls_element_type[op].nregs;
3716 interleave = neon_ls_element_type[op].interleave;
3717 gen_movl_T1_reg(s, rn);
3718 stride = (1 << size) * interleave;
3719 for (reg = 0; reg < nregs; reg++) {
3720 if (interleave > 2 || (interleave == 2 && nregs == 2)) {
3721 gen_movl_T1_reg(s, rn);
3722 gen_op_addl_T1_im((1 << size) * reg);
3723 } else if (interleave == 2 && nregs == 4 && reg == 2) {
3724 gen_movl_T1_reg(s, rn);
3725 gen_op_addl_T1_im(1 << size);
3727 for (pass = 0; pass < 2; pass++) {
3730 tmp = gen_ld32(cpu_T[1], IS_USER(s));
3731 neon_store_reg(rd, pass, tmp);
3733 tmp = neon_load_reg(rd, pass);
3734 gen_st32(tmp, cpu_T[1], IS_USER(s));
3736 gen_op_addl_T1_im(stride);
3737 } else if (size == 1) {
3739 tmp = gen_ld16u(cpu_T[1], IS_USER(s));
3740 gen_op_addl_T1_im(stride);
3741 tmp2 = gen_ld16u(cpu_T[1], IS_USER(s));
3742 gen_op_addl_T1_im(stride);
3743 gen_bfi(tmp, tmp, tmp2, 16, 0xffff);
3745 neon_store_reg(rd, pass, tmp);
3747 tmp = neon_load_reg(rd, pass);
3749 tcg_gen_shri_i32(tmp2, tmp, 16);
3750 gen_st16(tmp, cpu_T[1], IS_USER(s));
3751 gen_op_addl_T1_im(stride);
3752 gen_st16(tmp2, cpu_T[1], IS_USER(s));
3753 gen_op_addl_T1_im(stride);
3755 } else /* size == 0 */ {
3758 for (n = 0; n < 4; n++) {
3759 tmp = gen_ld8u(cpu_T[1], IS_USER(s));
3760 gen_op_addl_T1_im(stride);
3764 gen_bfi(tmp2, tmp2, tmp, n * 8, 0xff);
3768 neon_store_reg(rd, pass, tmp2);
3770 tmp2 = neon_load_reg(rd, pass);
3771 for (n = 0; n < 4; n++) {
3774 tcg_gen_mov_i32(tmp, tmp2);
3776 tcg_gen_shri_i32(tmp, tmp2, n * 8);
3778 gen_st8(tmp, cpu_T[1], IS_USER(s));
3779 gen_op_addl_T1_im(stride);
3785 rd += neon_ls_element_type[op].spacing;
3789 size = (insn >> 10) & 3;
3791 /* Load single element to all lanes. */
3794 size = (insn >> 6) & 3;
3795 nregs = ((insn >> 8) & 3) + 1;
3796 stride = (insn & (1 << 5)) ? 2 : 1;
3797 gen_movl_T1_reg(s, rn);
3798 for (reg = 0; reg < nregs; reg++) {
3801 tmp = gen_ld8u(cpu_T[1], IS_USER(s));
3802 gen_neon_dup_u8(tmp, 0);
3805 tmp = gen_ld16u(cpu_T[1], IS_USER(s));
3806 gen_neon_dup_low16(tmp);
3809 tmp = gen_ld32(cpu_T[0], IS_USER(s));
3813 default: /* Avoid compiler warnings. */
3816 gen_op_addl_T1_im(1 << size);
3818 tcg_gen_mov_i32(tmp2, tmp);
3819 neon_store_reg(rd, 0, tmp2);
3820 neon_store_reg(rd, 0, tmp);
3823 stride = (1 << size) * nregs;
3825 /* Single element. */
3826 pass = (insn >> 7) & 1;
3829 shift = ((insn >> 5) & 3) * 8;
3833 shift = ((insn >> 6) & 1) * 16;
3834 stride = (insn & (1 << 5)) ? 2 : 1;
3838 stride = (insn & (1 << 6)) ? 2 : 1;
3843 nregs = ((insn >> 8) & 3) + 1;
3844 gen_movl_T1_reg(s, rn);
3845 for (reg = 0; reg < nregs; reg++) {
3849 tmp = gen_ld8u(cpu_T[1], IS_USER(s));
3852 tmp = gen_ld16u(cpu_T[1], IS_USER(s));
3855 tmp = gen_ld32(cpu_T[1], IS_USER(s));
3857 default: /* Avoid compiler warnings. */
3861 tmp2 = neon_load_reg(rd, pass);
3862 gen_bfi(tmp, tmp2, tmp, shift, size ? 0xffff : 0xff);
3865 neon_store_reg(rd, pass, tmp);
3866 } else { /* Store */
3867 tmp = neon_load_reg(rd, pass);
3869 tcg_gen_shri_i32(tmp, tmp, shift);
3872 gen_st8(tmp, cpu_T[1], IS_USER(s));
3875 gen_st16(tmp, cpu_T[1], IS_USER(s));
3878 gen_st32(tmp, cpu_T[1], IS_USER(s));
3883 gen_op_addl_T1_im(1 << size);
3885 stride = nregs * (1 << size);
3891 base = load_reg(s, rn);
3893 tcg_gen_addi_i32(base, base, stride);
3896 index = load_reg(s, rm);
3897 tcg_gen_add_i32(base, base, index);
3900 store_reg(s, rn, base);
3905 /* Bitwise select. dest = c ? t : f. Clobbers T and F. */
3906 static void gen_neon_bsl(TCGv dest, TCGv t, TCGv f, TCGv c)
3908 tcg_gen_and_i32(t, t, c);
3909 tcg_gen_bic_i32(f, f, c);
3910 tcg_gen_or_i32(dest, t, f);
3913 static inline void gen_neon_narrow(int size, TCGv dest, TCGv src)
3916 case 0: gen_helper_neon_narrow_u8(dest, src); break;
3917 case 1: gen_helper_neon_narrow_u16(dest, src); break;
3918 case 2: tcg_gen_trunc_i64_i32(dest, src); break;
3923 static inline void gen_neon_narrow_sats(int size, TCGv dest, TCGv src)
3926 case 0: gen_helper_neon_narrow_sat_s8(dest, cpu_env, src); break;
3927 case 1: gen_helper_neon_narrow_sat_s16(dest, cpu_env, src); break;
3928 case 2: gen_helper_neon_narrow_sat_s32(dest, cpu_env, src); break;
3933 static inline void gen_neon_narrow_satu(int size, TCGv dest, TCGv src)
3936 case 0: gen_helper_neon_narrow_sat_u8(dest, cpu_env, src); break;
3937 case 1: gen_helper_neon_narrow_sat_u16(dest, cpu_env, src); break;
3938 case 2: gen_helper_neon_narrow_sat_u32(dest, cpu_env, src); break;
3943 static inline void gen_neon_shift_narrow(int size, TCGv var, TCGv shift,
3949 case 1: gen_helper_neon_rshl_u16(var, var, shift); break;
3950 case 2: gen_helper_neon_rshl_u32(var, var, shift); break;
3955 case 1: gen_helper_neon_rshl_s16(var, var, shift); break;
3956 case 2: gen_helper_neon_rshl_s32(var, var, shift); break;
3963 case 1: gen_helper_neon_rshl_u16(var, var, shift); break;
3964 case 2: gen_helper_neon_rshl_u32(var, var, shift); break;
3969 case 1: gen_helper_neon_shl_s16(var, var, shift); break;
3970 case 2: gen_helper_neon_shl_s32(var, var, shift); break;
3977 static inline void gen_neon_widen(TCGv dest, TCGv src, int size, int u)
3981 case 0: gen_helper_neon_widen_u8(dest, src); break;
3982 case 1: gen_helper_neon_widen_u16(dest, src); break;
3983 case 2: tcg_gen_extu_i32_i64(dest, src); break;
3988 case 0: gen_helper_neon_widen_s8(dest, src); break;
3989 case 1: gen_helper_neon_widen_s16(dest, src); break;
3990 case 2: tcg_gen_ext_i32_i64(dest, src); break;
3997 static inline void gen_neon_addl(int size)
4000 case 0: gen_helper_neon_addl_u16(CPU_V001); break;
4001 case 1: gen_helper_neon_addl_u32(CPU_V001); break;
4002 case 2: tcg_gen_add_i64(CPU_V001); break;
4007 static inline void gen_neon_subl(int size)
4010 case 0: gen_helper_neon_subl_u16(CPU_V001); break;
4011 case 1: gen_helper_neon_subl_u32(CPU_V001); break;
4012 case 2: tcg_gen_sub_i64(CPU_V001); break;
4017 static inline void gen_neon_negl(TCGv var, int size)
4020 case 0: gen_helper_neon_negl_u16(var, var); break;
4021 case 1: gen_helper_neon_negl_u32(var, var); break;
4022 case 2: gen_helper_neon_negl_u64(var, var); break;
4027 static inline void gen_neon_addl_saturate(TCGv op0, TCGv op1, int size)
4030 case 1: gen_helper_neon_addl_saturate_s32(op0, cpu_env, op0, op1); break;
4031 case 2: gen_helper_neon_addl_saturate_s64(op0, cpu_env, op0, op1); break;
4036 static inline void gen_neon_mull(TCGv dest, TCGv a, TCGv b, int size, int u)
4040 switch ((size << 1) | u) {
4041 case 0: gen_helper_neon_mull_s8(dest, a, b); break;
4042 case 1: gen_helper_neon_mull_u8(dest, a, b); break;
4043 case 2: gen_helper_neon_mull_s16(dest, a, b); break;
4044 case 3: gen_helper_neon_mull_u16(dest, a, b); break;
4046 tmp = gen_muls_i64_i32(a, b);
4047 tcg_gen_mov_i64(dest, tmp);
4050 tmp = gen_mulu_i64_i32(a, b);
4051 tcg_gen_mov_i64(dest, tmp);
4061 /* Translate a NEON data processing instruction. Return nonzero if the
4062 instruction is invalid.
4063 We process data in a mixture of 32-bit and 64-bit chunks.
4064 Mostly we use 32-bit chunks so we can use normal scalar instructions. */
4066 static int disas_neon_data_insn(CPUState * env, DisasContext *s, uint32_t insn)
4083 if (!vfp_enabled(env))
4085 q = (insn & (1 << 6)) != 0;
4086 u = (insn >> 24) & 1;
4087 VFP_DREG_D(rd, insn);
4088 VFP_DREG_N(rn, insn);
4089 VFP_DREG_M(rm, insn);
4090 size = (insn >> 20) & 3;
4091 if ((insn & (1 << 23)) == 0) {
4092 /* Three register same length. */
4093 op = ((insn >> 7) & 0x1e) | ((insn >> 4) & 1);
4094 if (size == 3 && (op == 1 || op == 5 || op == 8 || op == 9
4095 || op == 10 || op == 11 || op == 16)) {
4096 /* 64-bit element instructions. */
4097 for (pass = 0; pass < (q ? 2 : 1); pass++) {
4098 neon_load_reg64(cpu_V0, rn + pass);
4099 neon_load_reg64(cpu_V1, rm + pass);
4103 gen_helper_neon_add_saturate_u64(CPU_V001);
4105 gen_helper_neon_add_saturate_s64(CPU_V001);
4110 gen_helper_neon_sub_saturate_u64(CPU_V001);
4112 gen_helper_neon_sub_saturate_s64(CPU_V001);
4117 gen_helper_neon_shl_u64(cpu_V0, cpu_V1, cpu_V0);
4119 gen_helper_neon_shl_s64(cpu_V0, cpu_V1, cpu_V0);
4124 gen_helper_neon_qshl_u64(cpu_V0, cpu_env,
4127 gen_helper_neon_qshl_s64(cpu_V1, cpu_env,
4131 case 10: /* VRSHL */
4133 gen_helper_neon_rshl_u64(cpu_V0, cpu_V1, cpu_V0);
4135 gen_helper_neon_rshl_s64(cpu_V0, cpu_V1, cpu_V0);
4138 case 11: /* VQRSHL */
4140 gen_helper_neon_qrshl_u64(cpu_V0, cpu_env,
4143 gen_helper_neon_qrshl_s64(cpu_V0, cpu_env,
4149 tcg_gen_sub_i64(CPU_V001);
4151 tcg_gen_add_i64(CPU_V001);
4157 neon_store_reg64(cpu_V0, rd + pass);
4164 case 10: /* VRSHL */
4165 case 11: /* VQRSHL */
4168 /* Shift instruction operands are reversed. */
4175 case 20: /* VPMAX */
4176 case 21: /* VPMIN */
4177 case 23: /* VPADD */
4180 case 26: /* VPADD (float) */
4181 pairwise = (u && size < 2);
4183 case 30: /* VPMIN/VPMAX (float) */
4190 for (pass = 0; pass < (q ? 4 : 2); pass++) {
4199 NEON_GET_REG(T0, rn, n);
4200 NEON_GET_REG(T1, rn, n + 1);
4202 NEON_GET_REG(T0, rm, n);
4203 NEON_GET_REG(T1, rm, n + 1);
4207 NEON_GET_REG(T0, rn, pass);
4208 NEON_GET_REG(T1, rm, pass);
4212 GEN_NEON_INTEGER_OP(hadd);
4215 GEN_NEON_INTEGER_OP_ENV(qadd);
4217 case 2: /* VRHADD */
4218 GEN_NEON_INTEGER_OP(rhadd);
4220 case 3: /* Logic ops. */
4221 switch ((u << 2) | size) {
4223 gen_op_andl_T0_T1();
4226 gen_op_bicl_T0_T1();
4236 gen_op_xorl_T0_T1();
4239 tmp = neon_load_reg(rd, pass);
4240 gen_neon_bsl(cpu_T[0], cpu_T[0], cpu_T[1], tmp);
4244 tmp = neon_load_reg(rd, pass);
4245 gen_neon_bsl(cpu_T[0], cpu_T[0], tmp, cpu_T[1]);
4249 tmp = neon_load_reg(rd, pass);
4250 gen_neon_bsl(cpu_T[0], tmp, cpu_T[0], cpu_T[1]);
4256 GEN_NEON_INTEGER_OP(hsub);
4259 GEN_NEON_INTEGER_OP_ENV(qsub);
4262 GEN_NEON_INTEGER_OP(cgt);
4265 GEN_NEON_INTEGER_OP(cge);
4268 GEN_NEON_INTEGER_OP(shl);
4271 GEN_NEON_INTEGER_OP_ENV(qshl);
4273 case 10: /* VRSHL */
4274 GEN_NEON_INTEGER_OP(rshl);
4276 case 11: /* VQRSHL */
4277 GEN_NEON_INTEGER_OP_ENV(qrshl);
4280 GEN_NEON_INTEGER_OP(max);
4283 GEN_NEON_INTEGER_OP(min);
4286 GEN_NEON_INTEGER_OP(abd);
4289 GEN_NEON_INTEGER_OP(abd);
4290 NEON_GET_REG(T1, rd, pass);
4294 if (!u) { /* VADD */
4295 if (gen_neon_add(size))
4299 case 0: gen_helper_neon_sub_u8(CPU_T001); break;
4300 case 1: gen_helper_neon_sub_u16(CPU_T001); break;
4301 case 2: gen_op_subl_T0_T1(); break;
4307 if (!u) { /* VTST */
4309 case 0: gen_helper_neon_tst_u8(CPU_T001); break;
4310 case 1: gen_helper_neon_tst_u16(CPU_T001); break;
4311 case 2: gen_helper_neon_tst_u32(CPU_T001); break;
4316 case 0: gen_helper_neon_ceq_u8(CPU_T001); break;
4317 case 1: gen_helper_neon_ceq_u16(CPU_T001); break;
4318 case 2: gen_helper_neon_ceq_u32(CPU_T001); break;
4323 case 18: /* Multiply. */
4325 case 0: gen_helper_neon_mul_u8(CPU_T001); break;
4326 case 1: gen_helper_neon_mul_u16(CPU_T001); break;
4327 case 2: gen_op_mul_T0_T1(); break;
4330 NEON_GET_REG(T1, rd, pass);
4338 if (u) { /* polynomial */
4339 gen_helper_neon_mul_p8(CPU_T001);
4340 } else { /* Integer */
4342 case 0: gen_helper_neon_mul_u8(CPU_T001); break;
4343 case 1: gen_helper_neon_mul_u16(CPU_T001); break;
4344 case 2: gen_op_mul_T0_T1(); break;
4349 case 20: /* VPMAX */
4350 GEN_NEON_INTEGER_OP(pmax);
4352 case 21: /* VPMIN */
4353 GEN_NEON_INTEGER_OP(pmin);
4355 case 22: /* Hultiply high. */
4356 if (!u) { /* VQDMULH */
4358 case 1: gen_helper_neon_qdmulh_s16(CPU_T0E01); break;
4359 case 2: gen_helper_neon_qdmulh_s32(CPU_T0E01); break;
4362 } else { /* VQRDHMUL */
4364 case 1: gen_helper_neon_qrdmulh_s16(CPU_T0E01); break;
4365 case 2: gen_helper_neon_qrdmulh_s32(CPU_T0E01); break;
4370 case 23: /* VPADD */
4374 case 0: gen_helper_neon_padd_u8(CPU_T001); break;
4375 case 1: gen_helper_neon_padd_u16(CPU_T001); break;
4376 case 2: gen_op_addl_T0_T1(); break;
4380 case 26: /* Floating point arithnetic. */
4381 switch ((u << 2) | size) {
4383 gen_helper_neon_add_f32(CPU_T001);
4386 gen_helper_neon_sub_f32(CPU_T001);
4389 gen_helper_neon_add_f32(CPU_T001);
4392 gen_helper_neon_abd_f32(CPU_T001);
4398 case 27: /* Float multiply. */
4399 gen_helper_neon_mul_f32(CPU_T001);
4401 NEON_GET_REG(T1, rd, pass);
4403 gen_helper_neon_add_f32(CPU_T001);
4405 gen_helper_neon_sub_f32(cpu_T[0], cpu_T[1], cpu_T[0]);
4409 case 28: /* Float compare. */
4411 gen_helper_neon_ceq_f32(CPU_T001);
4414 gen_helper_neon_cge_f32(CPU_T001);
4416 gen_helper_neon_cgt_f32(CPU_T001);
4419 case 29: /* Float compare absolute. */
4423 gen_helper_neon_acge_f32(CPU_T001);
4425 gen_helper_neon_acgt_f32(CPU_T001);
4427 case 30: /* Float min/max. */
4429 gen_helper_neon_max_f32(CPU_T001);
4431 gen_helper_neon_min_f32(CPU_T001);
4435 gen_helper_recps_f32(cpu_T[0], cpu_T[0], cpu_T[1], cpu_env);
4437 gen_helper_rsqrts_f32(cpu_T[0], cpu_T[0], cpu_T[1], cpu_env);
4442 /* Save the result. For elementwise operations we can put it
4443 straight into the destination register. For pairwise operations
4444 we have to be careful to avoid clobbering the source operands. */
4445 if (pairwise && rd == rm) {
4446 gen_neon_movl_scratch_T0(pass);
4448 NEON_SET_REG(T0, rd, pass);
4452 if (pairwise && rd == rm) {
4453 for (pass = 0; pass < (q ? 4 : 2); pass++) {
4454 gen_neon_movl_T0_scratch(pass);
4455 NEON_SET_REG(T0, rd, pass);
4458 /* End of 3 register same size operations. */
4459 } else if (insn & (1 << 4)) {
4460 if ((insn & 0x00380080) != 0) {
4461 /* Two registers and shift. */
4462 op = (insn >> 8) & 0xf;
4463 if (insn & (1 << 7)) {
4468 while ((insn & (1 << (size + 19))) == 0)
4471 shift = (insn >> 16) & ((1 << (3 + size)) - 1);
4472 /* To avoid excessive dumplication of ops we implement shift
4473 by immediate using the variable shift operations. */
4475 /* Shift by immediate:
4476 VSHR, VSRA, VRSHR, VRSRA, VSRI, VSHL, VQSHL, VQSHLU. */
4477 /* Right shifts are encoded as N - shift, where N is the
4478 element size in bits. */
4480 shift = shift - (1 << (size + 3));
4488 imm = (uint8_t) shift;
4493 imm = (uint16_t) shift;
4504 for (pass = 0; pass < count; pass++) {
4506 neon_load_reg64(cpu_V0, rm + pass);
4507 tcg_gen_movi_i64(cpu_V1, imm);
4512 gen_helper_neon_shl_u64(cpu_V0, cpu_V0, cpu_V1);
4514 gen_helper_neon_shl_s64(cpu_V0, cpu_V0, cpu_V1);
4519 gen_helper_neon_rshl_u64(cpu_V0, cpu_V0, cpu_V1);
4521 gen_helper_neon_rshl_s64(cpu_V0, cpu_V0, cpu_V1);
4526 gen_helper_neon_shl_u64(cpu_V0, cpu_V0, cpu_V1);
4528 case 5: /* VSHL, VSLI */
4529 gen_helper_neon_shl_u64(cpu_V0, cpu_V0, cpu_V1);
4533 gen_helper_neon_qshl_u64(cpu_V0, cpu_env, cpu_V0, cpu_V1);
4535 gen_helper_neon_qshl_s64(cpu_V0, cpu_env, cpu_V0, cpu_V1);
4537 case 7: /* VQSHLU */
4538 gen_helper_neon_qshl_u64(cpu_V0, cpu_env, cpu_V0, cpu_V1);
4541 if (op == 1 || op == 3) {
4543 neon_load_reg64(cpu_V0, rd + pass);
4544 tcg_gen_add_i64(cpu_V0, cpu_V0, cpu_V1);
4545 } else if (op == 4 || (op == 5 && u)) {
4547 cpu_abort(env, "VS[LR]I.64 not implemented");
4549 neon_store_reg64(cpu_V0, rd + pass);
4550 } else { /* size < 3 */
4551 /* Operands in T0 and T1. */
4552 gen_op_movl_T1_im(imm);
4553 NEON_GET_REG(T0, rm, pass);
4557 GEN_NEON_INTEGER_OP(shl);
4561 GEN_NEON_INTEGER_OP(rshl);
4566 GEN_NEON_INTEGER_OP(shl);
4568 case 5: /* VSHL, VSLI */
4570 case 0: gen_helper_neon_shl_u8(CPU_T001); break;
4571 case 1: gen_helper_neon_shl_u16(CPU_T001); break;
4572 case 2: gen_helper_neon_shl_u32(CPU_T001); break;
4577 GEN_NEON_INTEGER_OP_ENV(qshl);
4579 case 7: /* VQSHLU */
4581 case 0: gen_helper_neon_qshl_u8(CPU_T0E01); break;
4582 case 1: gen_helper_neon_qshl_u16(CPU_T0E01); break;
4583 case 2: gen_helper_neon_qshl_u32(CPU_T0E01); break;
4589 if (op == 1 || op == 3) {
4591 NEON_GET_REG(T1, rd, pass);
4593 } else if (op == 4 || (op == 5 && u)) {
4598 imm = 0xff >> -shift;
4600 imm = (uint8_t)(0xff << shift);
4606 imm = 0xffff >> -shift;
4608 imm = (uint16_t)(0xffff << shift);
4613 imm = 0xffffffffu >> -shift;
4615 imm = 0xffffffffu << shift;
4620 tmp = neon_load_reg(rd, pass);
4621 tcg_gen_andi_i32(cpu_T[0], cpu_T[0], imm);
4622 tcg_gen_andi_i32(tmp, tmp, ~imm);
4623 tcg_gen_or_i32(cpu_T[0], cpu_T[0], tmp);
4625 NEON_SET_REG(T0, rd, pass);
4628 } else if (op < 10) {
4629 /* Shift by immediate and narrow:
4630 VSHRN, VRSHRN, VQSHRN, VQRSHRN. */
4631 shift = shift - (1 << (size + 3));
4635 imm = (uint16_t)shift;
4637 tmp2 = tcg_const_i32(imm);
4640 imm = (uint32_t)shift;
4641 tmp2 = tcg_const_i32(imm);
4643 tmp2 = tcg_const_i64(shift);
4649 for (pass = 0; pass < 2; pass++) {
4651 neon_load_reg64(cpu_V0, rm + pass);
4654 gen_helper_neon_rshl_u64(cpu_V0, cpu_V0, tmp2);
4656 gen_helper_neon_rshl_s64(cpu_V0, cpu_V0, tmp2);
4659 gen_helper_neon_shl_u64(cpu_V0, cpu_V0, tmp2);
4661 gen_helper_neon_shl_s64(cpu_V0, cpu_V0, tmp2);
4664 tmp = neon_load_reg(rm + pass, 0);
4665 gen_neon_shift_narrow(size, tmp, tmp2, q, u);
4666 tcg_gen_extu_i32_i64(cpu_V0, tmp);
4668 tmp = neon_load_reg(rm + pass, 1);
4669 gen_neon_shift_narrow(size, tmp, tmp2, q, u);
4670 tcg_gen_extu_i32_i64(cpu_V1, tmp);
4672 tcg_gen_shli_i64(cpu_V1, cpu_V1, 32);
4673 tcg_gen_or_i64(cpu_V0, cpu_V0, cpu_V1);
4676 if (op == 8 && !u) {
4677 gen_neon_narrow(size - 1, tmp, cpu_V0);
4680 gen_neon_narrow_sats(size - 1, tmp, cpu_V0);
4682 gen_neon_narrow_satu(size - 1, tmp, cpu_V0);
4687 neon_store_reg(rd, 0, tmp2);
4688 neon_store_reg(rd, 1, tmp);
4691 } else if (op == 10) {
4695 tmp = neon_load_reg(rm, 0);
4696 tmp2 = neon_load_reg(rm, 1);
4697 for (pass = 0; pass < 2; pass++) {
4701 gen_neon_widen(cpu_V0, tmp, size, u);
4704 /* The shift is less than the width of the source
4705 type, so we can just shift the whole register. */
4706 tcg_gen_shli_i64(cpu_V0, cpu_V0, shift);
4707 if (size < 2 || !u) {
4710 imm = (0xffu >> (8 - shift));
4713 imm = 0xffff >> (16 - shift);
4715 imm64 = imm | (((uint64_t)imm) << 32);
4716 tcg_gen_andi_i64(cpu_V0, cpu_V0, imm64);
4719 neon_store_reg64(cpu_V0, rd + pass);
4721 } else if (op == 15 || op == 16) {
4722 /* VCVT fixed-point. */
4723 for (pass = 0; pass < (q ? 4 : 2); pass++) {
4724 tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, pass));
4727 gen_vfp_ulto(0, shift);
4729 gen_vfp_slto(0, shift);
4732 gen_vfp_toul(0, shift);
4734 gen_vfp_tosl(0, shift);
4736 tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, pass));
4741 } else { /* (insn & 0x00380080) == 0 */
4744 op = (insn >> 8) & 0xf;
4745 /* One register and immediate. */
4746 imm = (u << 7) | ((insn >> 12) & 0x70) | (insn & 0xf);
4747 invert = (insn & (1 << 5)) != 0;
4765 imm = (imm << 8) | (imm << 24);
4768 imm = (imm < 8) | 0xff;
4771 imm = (imm << 16) | 0xffff;
4774 imm |= (imm << 8) | (imm << 16) | (imm << 24);
4779 imm = ((imm & 0x80) << 24) | ((imm & 0x3f) << 19)
4780 | ((imm & 0x40) ? (0x1f << 25) : (1 << 30));
4786 if (op != 14 || !invert)
4787 gen_op_movl_T1_im(imm);
4789 for (pass = 0; pass < (q ? 4 : 2); pass++) {
4790 if (op & 1 && op < 12) {
4791 tmp = neon_load_reg(rd, pass);
4793 /* The immediate value has already been inverted, so
4795 tcg_gen_andi_i32(tmp, tmp, imm);
4797 tcg_gen_ori_i32(tmp, tmp, imm);
4802 if (op == 14 && invert) {
4805 for (n = 0; n < 4; n++) {
4806 if (imm & (1 << (n + (pass & 1) * 4)))
4807 val |= 0xff << (n * 8);
4809 tcg_gen_movi_i32(tmp, val);
4811 tcg_gen_movi_i32(tmp, imm);
4814 neon_store_reg(rd, pass, tmp);
4817 } else { /* (insn & 0x00800010 == 0x00800010) */
4819 op = (insn >> 8) & 0xf;
4820 if ((insn & (1 << 6)) == 0) {
4821 /* Three registers of different lengths. */
4825 /* prewiden, src1_wide, src2_wide */
4826 static const int neon_3reg_wide[16][3] = {
4827 {1, 0, 0}, /* VADDL */
4828 {1, 1, 0}, /* VADDW */
4829 {1, 0, 0}, /* VSUBL */
4830 {1, 1, 0}, /* VSUBW */
4831 {0, 1, 1}, /* VADDHN */
4832 {0, 0, 0}, /* VABAL */
4833 {0, 1, 1}, /* VSUBHN */
4834 {0, 0, 0}, /* VABDL */
4835 {0, 0, 0}, /* VMLAL */
4836 {0, 0, 0}, /* VQDMLAL */
4837 {0, 0, 0}, /* VMLSL */
4838 {0, 0, 0}, /* VQDMLSL */
4839 {0, 0, 0}, /* Integer VMULL */
4840 {0, 0, 0}, /* VQDMULL */
4841 {0, 0, 0} /* Polynomial VMULL */
4844 prewiden = neon_3reg_wide[op][0];
4845 src1_wide = neon_3reg_wide[op][1];
4846 src2_wide = neon_3reg_wide[op][2];
4848 if (size == 0 && (op == 9 || op == 11 || op == 13))
4851 /* Avoid overlapping operands. Wide source operands are
4852 always aligned so will never overlap with wide
4853 destinations in problematic ways. */
4854 if (rd == rm && !src2_wide) {
4855 NEON_GET_REG(T0, rm, 1);
4856 gen_neon_movl_scratch_T0(2);
4857 } else if (rd == rn && !src1_wide) {
4858 NEON_GET_REG(T0, rn, 1);
4859 gen_neon_movl_scratch_T0(2);
4862 for (pass = 0; pass < 2; pass++) {
4864 neon_load_reg64(cpu_V0, rn + pass);
4867 if (pass == 1 && rd == rn) {
4868 gen_neon_movl_T0_scratch(2);
4870 tcg_gen_mov_i32(tmp, cpu_T[0]);
4872 tmp = neon_load_reg(rn, pass);
4875 gen_neon_widen(cpu_V0, tmp, size, u);
4879 neon_load_reg64(cpu_V1, rm + pass);
4882 if (pass == 1 && rd == rm) {
4883 gen_neon_movl_T0_scratch(2);
4885 tcg_gen_mov_i32(tmp2, cpu_T[0]);
4887 tmp2 = neon_load_reg(rm, pass);
4890 gen_neon_widen(cpu_V1, tmp2, size, u);
4894 case 0: case 1: case 4: /* VADDL, VADDW, VADDHN, VRADDHN */
4895 gen_neon_addl(size);
4897 case 2: case 3: case 6: /* VSUBL, VSUBW, VSUBHL, VRSUBHL */
4898 gen_neon_subl(size);
4900 case 5: case 7: /* VABAL, VABDL */
4901 switch ((size << 1) | u) {
4903 gen_helper_neon_abdl_s16(cpu_V0, tmp, tmp2);
4906 gen_helper_neon_abdl_u16(cpu_V0, tmp, tmp2);
4909 gen_helper_neon_abdl_s32(cpu_V0, tmp, tmp2);
4912 gen_helper_neon_abdl_u32(cpu_V0, tmp, tmp2);
4915 gen_helper_neon_abdl_s64(cpu_V0, tmp, tmp2);
4918 gen_helper_neon_abdl_u64(cpu_V0, tmp, tmp2);
4925 case 8: case 9: case 10: case 11: case 12: case 13:
4926 /* VMLAL, VQDMLAL, VMLSL, VQDMLSL, VMULL, VQDMULL */
4927 gen_neon_mull(cpu_V0, tmp, tmp2, size, u);
4929 case 14: /* Polynomial VMULL */
4930 cpu_abort(env, "Polynomial VMULL not implemented");
4932 default: /* 15 is RESERVED. */
4935 if (op == 5 || op == 13 || (op >= 8 && op <= 11)) {
4937 if (op == 10 || op == 11) {
4938 gen_neon_negl(cpu_V0, size);
4942 neon_load_reg64(cpu_V1, rd + pass);
4946 case 5: case 8: case 10: /* VABAL, VMLAL, VMLSL */
4947 gen_neon_addl(size);
4949 case 9: case 11: /* VQDMLAL, VQDMLSL */
4950 gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
4951 gen_neon_addl_saturate(cpu_V0, cpu_V1, size);
4954 case 13: /* VQDMULL */
4955 gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
4960 neon_store_reg64(cpu_V0, rd + pass);
4961 } else if (op == 4 || op == 6) {
4962 /* Narrowing operation. */
4967 gen_helper_neon_narrow_high_u8(tmp, cpu_V0);
4970 gen_helper_neon_narrow_high_u16(tmp, cpu_V0);
4973 tcg_gen_shri_i64(cpu_V0, cpu_V0, 32);
4974 tcg_gen_trunc_i64_i32(tmp, cpu_V0);
4981 gen_helper_neon_narrow_round_high_u8(tmp, cpu_V0);
4984 gen_helper_neon_narrow_round_high_u16(tmp, cpu_V0);
4987 tcg_gen_addi_i64(cpu_V0, cpu_V0, 1u << 31);
4988 tcg_gen_shri_i64(cpu_V0, cpu_V0, 32);
4989 tcg_gen_trunc_i64_i32(tmp, cpu_V0);
4997 neon_store_reg(rd, 0, tmp3);
4998 neon_store_reg(rd, 1, tmp);
5001 /* Write back the result. */
5002 neon_store_reg64(cpu_V0, rd + pass);
5006 /* Two registers and a scalar. */
5008 case 0: /* Integer VMLA scalar */
5009 case 1: /* Float VMLA scalar */
5010 case 4: /* Integer VMLS scalar */
5011 case 5: /* Floating point VMLS scalar */
5012 case 8: /* Integer VMUL scalar */
5013 case 9: /* Floating point VMUL scalar */
5014 case 12: /* VQDMULH scalar */
5015 case 13: /* VQRDMULH scalar */
5016 gen_neon_get_scalar(size, rm);
5017 gen_neon_movl_scratch_T0(0);
5018 for (pass = 0; pass < (u ? 4 : 2); pass++) {
5020 gen_neon_movl_T0_scratch(0);
5021 NEON_GET_REG(T1, rn, pass);
5024 gen_helper_neon_qdmulh_s16(CPU_T0E01);
5026 gen_helper_neon_qdmulh_s32(CPU_T0E01);
5028 } else if (op == 13) {
5030 gen_helper_neon_qrdmulh_s16(CPU_T0E01);
5032 gen_helper_neon_qrdmulh_s32(CPU_T0E01);
5034 } else if (op & 1) {
5035 gen_helper_neon_mul_f32(CPU_T001);
5038 case 0: gen_helper_neon_mul_u8(CPU_T001); break;
5039 case 1: gen_helper_neon_mul_u16(CPU_T001); break;
5040 case 2: gen_op_mul_T0_T1(); break;
5046 NEON_GET_REG(T1, rd, pass);
5052 gen_helper_neon_add_f32(CPU_T001);
5058 gen_helper_neon_sub_f32(cpu_T[0], cpu_T[1], cpu_T[0]);
5064 NEON_SET_REG(T0, rd, pass);
5067 case 2: /* VMLAL sclar */
5068 case 3: /* VQDMLAL scalar */
5069 case 6: /* VMLSL scalar */
5070 case 7: /* VQDMLSL scalar */
5071 case 10: /* VMULL scalar */
5072 case 11: /* VQDMULL scalar */
5073 if (size == 0 && (op == 3 || op == 7 || op == 11))
5076 gen_neon_get_scalar(size, rm);
5077 NEON_GET_REG(T1, rn, 1);
5079 for (pass = 0; pass < 2; pass++) {
5081 tmp = neon_load_reg(rn, 0);
5084 tcg_gen_mov_i32(tmp, cpu_T[1]);
5087 tcg_gen_mov_i32(tmp2, cpu_T[0]);
5088 gen_neon_mull(cpu_V0, tmp, tmp2, size, u);
5089 if (op == 6 || op == 7) {
5090 gen_neon_negl(cpu_V0, size);
5093 neon_load_reg64(cpu_V1, rd + pass);
5097 gen_neon_addl(size);
5100 gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
5101 gen_neon_addl_saturate(cpu_V0, cpu_V1, size);
5107 gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
5112 neon_store_reg64(cpu_V0, rd + pass);
5115 default: /* 14 and 15 are RESERVED */
5119 } else { /* size == 3 */
5122 imm = (insn >> 8) & 0xf;
5129 neon_load_reg64(cpu_V0, rn);
5131 neon_load_reg64(cpu_V1, rn + 1);
5133 } else if (imm == 8) {
5134 neon_load_reg64(cpu_V0, rn + 1);
5136 neon_load_reg64(cpu_V1, rm);
5139 tmp = tcg_temp_new(TCG_TYPE_I64);
5141 neon_load_reg64(cpu_V0, rn);
5142 neon_load_reg64(tmp, rn + 1);
5144 neon_load_reg64(cpu_V0, rn + 1);
5145 neon_load_reg64(tmp, rm);
5147 tcg_gen_shri_i64(cpu_V0, cpu_V0, (imm & 7) * 8);
5148 tcg_gen_shli_i64(cpu_V1, tmp, 64 - ((imm & 7) * 8));
5149 tcg_gen_or_i64(cpu_V0, cpu_V0, cpu_V1);
5151 neon_load_reg64(cpu_V1, rm);
5153 neon_load_reg64(cpu_V1, rm + 1);
5156 tcg_gen_shli_i64(cpu_V1, cpu_V1, 64 - (imm * 8));
5157 tcg_gen_shri_i64(tmp, tmp, imm * 8);
5158 tcg_gen_or_i64(cpu_V1, cpu_V1, tmp);
5160 neon_load_reg64(cpu_V0, rn);
5161 tcg_gen_shri_i32(cpu_V0, cpu_V0, imm * 8);
5162 neon_load_reg64(cpu_V1, rm);
5163 tcg_gen_shli_i32(cpu_V1, cpu_V1, 64 - (imm * 8));
5164 tcg_gen_or_i64(cpu_V0, cpu_V0, cpu_V1);
5166 neon_store_reg64(cpu_V0, rd);
5168 neon_store_reg64(cpu_V1, rd + 1);
5170 } else if ((insn & (1 << 11)) == 0) {
5171 /* Two register misc. */
5172 op = ((insn >> 12) & 0x30) | ((insn >> 7) & 0xf);
5173 size = (insn >> 18) & 3;
5175 case 0: /* VREV64 */
5178 for (pass = 0; pass < (q ? 2 : 1); pass++) {
5179 NEON_GET_REG(T0, rm, pass * 2);
5180 NEON_GET_REG(T1, rm, pass * 2 + 1);
5182 case 0: tcg_gen_bswap_i32(cpu_T[0], cpu_T[0]); break;
5183 case 1: gen_swap_half(cpu_T[0]); break;
5184 case 2: /* no-op */ break;
5187 NEON_SET_REG(T0, rd, pass * 2 + 1);
5189 NEON_SET_REG(T1, rd, pass * 2);
5191 gen_op_movl_T0_T1();
5193 case 0: tcg_gen_bswap_i32(cpu_T[0], cpu_T[0]); break;
5194 case 1: gen_swap_half(cpu_T[0]); break;
5197 NEON_SET_REG(T0, rd, pass * 2);
5201 case 4: case 5: /* VPADDL */
5202 case 12: case 13: /* VPADAL */
5205 for (pass = 0; pass < q + 1; pass++) {
5206 tmp = neon_load_reg(rm, pass * 2);
5207 gen_neon_widen(cpu_V0, tmp, size, op & 1);
5208 tmp = neon_load_reg(rm, pass * 2 + 1);
5209 gen_neon_widen(cpu_V1, tmp, size, op & 1);
5211 case 0: gen_helper_neon_paddl_u16(CPU_V001); break;
5212 case 1: gen_helper_neon_paddl_u32(CPU_V001); break;
5213 case 2: tcg_gen_add_i64(CPU_V001); break;
5218 neon_load_reg64(cpu_V1, rd + pass);
5219 gen_neon_addl(size);
5221 neon_store_reg64(cpu_V0, rd + pass);
5226 for (n = 0; n < (q ? 4 : 2); n += 2) {
5227 NEON_GET_REG(T0, rm, n);
5228 NEON_GET_REG(T1, rd, n + 1);
5229 NEON_SET_REG(T1, rm, n);
5230 NEON_SET_REG(T0, rd, n + 1);
5238 Rd A3 A2 A1 A0 B2 B0 A2 A0
5239 Rm B3 B2 B1 B0 B3 B1 A3 A1
5243 gen_neon_unzip(rd, q, 0, size);
5244 gen_neon_unzip(rm, q, 4, size);
5246 static int unzip_order_q[8] =
5247 {0, 2, 4, 6, 1, 3, 5, 7};
5248 for (n = 0; n < 8; n++) {
5249 int reg = (n < 4) ? rd : rm;
5250 gen_neon_movl_T0_scratch(unzip_order_q[n]);
5251 NEON_SET_REG(T0, reg, n % 4);
5254 static int unzip_order[4] =
5256 for (n = 0; n < 4; n++) {
5257 int reg = (n < 2) ? rd : rm;
5258 gen_neon_movl_T0_scratch(unzip_order[n]);
5259 NEON_SET_REG(T0, reg, n % 2);
5265 Rd A3 A2 A1 A0 B1 A1 B0 A0
5266 Rm B3 B2 B1 B0 B3 A3 B2 A2
5270 count = (q ? 4 : 2);
5271 for (n = 0; n < count; n++) {
5272 NEON_GET_REG(T0, rd, n);
5273 NEON_GET_REG(T1, rd, n);
5275 case 0: gen_helper_neon_zip_u8(); break;
5276 case 1: gen_helper_neon_zip_u16(); break;
5277 case 2: /* no-op */; break;
5280 gen_neon_movl_scratch_T0(n * 2);
5281 gen_neon_movl_scratch_T1(n * 2 + 1);
5283 for (n = 0; n < count * 2; n++) {
5284 int reg = (n < count) ? rd : rm;
5285 gen_neon_movl_T0_scratch(n);
5286 NEON_SET_REG(T0, reg, n % count);
5289 case 36: case 37: /* VMOVN, VQMOVUN, VQMOVN */
5293 for (pass = 0; pass < 2; pass++) {
5294 neon_load_reg64(cpu_V0, rm + pass);
5296 if (op == 36 && q == 0) {
5297 gen_neon_narrow(size, tmp, cpu_V0);
5299 gen_neon_narrow_satu(size, tmp, cpu_V0);
5301 gen_neon_narrow_sats(size, tmp, cpu_V0);
5306 neon_store_reg(rd, 0, tmp2);
5307 neon_store_reg(rd, 1, tmp);
5311 case 38: /* VSHLL */
5314 tmp = neon_load_reg(rm, 0);
5315 tmp2 = neon_load_reg(rm, 1);
5316 for (pass = 0; pass < 2; pass++) {
5319 gen_neon_widen(cpu_V0, tmp, size, 1);
5320 neon_store_reg64(cpu_V0, rd + pass);
5325 for (pass = 0; pass < (q ? 4 : 2); pass++) {
5326 if (op == 30 || op == 31 || op >= 58) {
5327 tcg_gen_ld_f32(cpu_F0s, cpu_env,
5328 neon_reg_offset(rm, pass));
5330 NEON_GET_REG(T0, rm, pass);
5333 case 1: /* VREV32 */
5335 case 0: tcg_gen_bswap_i32(cpu_T[0], cpu_T[0]); break;
5336 case 1: gen_swap_half(cpu_T[0]); break;
5340 case 2: /* VREV16 */
5343 gen_rev16(cpu_T[0]);
5347 case 0: gen_helper_neon_cls_s8(cpu_T[0], cpu_T[0]); break;
5348 case 1: gen_helper_neon_cls_s16(cpu_T[0], cpu_T[0]); break;
5349 case 2: gen_helper_neon_cls_s32(cpu_T[0], cpu_T[0]); break;
5355 case 0: gen_helper_neon_clz_u8(cpu_T[0], cpu_T[0]); break;
5356 case 1: gen_helper_neon_clz_u16(cpu_T[0], cpu_T[0]); break;
5357 case 2: gen_helper_clz(cpu_T[0], cpu_T[0]); break;
5364 gen_helper_neon_cnt_u8(cpu_T[0], cpu_T[0]);
5371 case 14: /* VQABS */
5373 case 0: gen_helper_neon_qabs_s8(cpu_T[0], cpu_env, cpu_T[0]); break;
5374 case 1: gen_helper_neon_qabs_s16(cpu_T[0], cpu_env, cpu_T[0]); break;
5375 case 2: gen_helper_neon_qabs_s32(cpu_T[0], cpu_env, cpu_T[0]); break;
5379 case 15: /* VQNEG */
5381 case 0: gen_helper_neon_qneg_s8(cpu_T[0], cpu_env, cpu_T[0]); break;
5382 case 1: gen_helper_neon_qneg_s16(cpu_T[0], cpu_env, cpu_T[0]); break;
5383 case 2: gen_helper_neon_qneg_s32(cpu_T[0], cpu_env, cpu_T[0]); break;
5387 case 16: case 19: /* VCGT #0, VCLE #0 */
5388 gen_op_movl_T1_im(0);
5390 case 0: gen_helper_neon_cgt_s8(CPU_T001); break;
5391 case 1: gen_helper_neon_cgt_s16(CPU_T001); break;
5392 case 2: gen_helper_neon_cgt_s32(CPU_T001); break;
5398 case 17: case 20: /* VCGE #0, VCLT #0 */
5399 gen_op_movl_T1_im(0);
5401 case 0: gen_helper_neon_cge_s8(CPU_T001); break;
5402 case 1: gen_helper_neon_cge_s16(CPU_T001); break;
5403 case 2: gen_helper_neon_cge_s32(CPU_T001); break;
5409 case 18: /* VCEQ #0 */
5410 gen_op_movl_T1_im(0);
5412 case 0: gen_helper_neon_ceq_u8(CPU_T001); break;
5413 case 1: gen_helper_neon_ceq_u16(CPU_T001); break;
5414 case 2: gen_helper_neon_ceq_u32(CPU_T001); break;
5420 case 0: gen_helper_neon_abs_s8(cpu_T[0], cpu_T[0]); break;
5421 case 1: gen_helper_neon_abs_s16(cpu_T[0], cpu_T[0]); break;
5422 case 2: tcg_gen_abs_i32(cpu_T[0], cpu_T[0]); break;
5427 gen_op_movl_T1_im(0);
5432 case 24: case 27: /* Float VCGT #0, Float VCLE #0 */
5433 gen_op_movl_T1_im(0);
5434 gen_helper_neon_cgt_f32(CPU_T001);
5438 case 25: case 28: /* Float VCGE #0, Float VCLT #0 */
5439 gen_op_movl_T1_im(0);
5440 gen_helper_neon_cge_f32(CPU_T001);
5444 case 26: /* Float VCEQ #0 */
5445 gen_op_movl_T1_im(0);
5446 gen_helper_neon_ceq_f32(CPU_T001);
5448 case 30: /* Float VABS */
5451 case 31: /* Float VNEG */
5455 NEON_GET_REG(T1, rd, pass);
5456 NEON_SET_REG(T1, rm, pass);
5459 NEON_GET_REG(T1, rd, pass);
5461 case 0: gen_helper_neon_trn_u8(); break;
5462 case 1: gen_helper_neon_trn_u16(); break;
5466 NEON_SET_REG(T1, rm, pass);
5468 case 56: /* Integer VRECPE */
5469 gen_helper_recpe_u32(cpu_T[0], cpu_T[0], cpu_env);
5471 case 57: /* Integer VRSQRTE */
5472 gen_helper_rsqrte_u32(cpu_T[0], cpu_T[0], cpu_env);
5474 case 58: /* Float VRECPE */
5475 gen_helper_recpe_f32(cpu_F0s, cpu_F0s, cpu_env);
5477 case 59: /* Float VRSQRTE */
5478 gen_helper_rsqrte_f32(cpu_F0s, cpu_F0s, cpu_env);
5480 case 60: /* VCVT.F32.S32 */
5483 case 61: /* VCVT.F32.U32 */
5486 case 62: /* VCVT.S32.F32 */
5489 case 63: /* VCVT.U32.F32 */
5493 /* Reserved: 21, 29, 39-56 */
5496 if (op == 30 || op == 31 || op >= 58) {
5497 tcg_gen_st_f32(cpu_F0s, cpu_env,
5498 neon_reg_offset(rd, pass));
5500 NEON_SET_REG(T0, rd, pass);
5505 } else if ((insn & (1 << 10)) == 0) {
5507 n = (insn >> 5) & 0x18;
5508 if (insn & (1 << 6)) {
5509 tmp = neon_load_reg(rd, 0);
5512 tcg_gen_movi_i32(tmp, 0);
5514 tmp2 = neon_load_reg(rm, 0);
5515 gen_helper_neon_tbl(tmp2, tmp2, tmp, tcg_const_i32(rn),
5517 if (insn & (1 << 6)) {
5518 tmp = neon_load_reg(rd, 1);
5521 tcg_gen_movi_i32(tmp, 0);
5523 tmp3 = neon_load_reg(rm, 1);
5524 gen_helper_neon_tbl(tmp3, tmp3, tmp, tcg_const_i32(rn),
5526 neon_store_reg(rd, 0, tmp2);
5527 neon_store_reg(rd, 1, tmp2);
5528 } else if ((insn & 0x380) == 0) {
5530 if (insn & (1 << 19)) {
5531 NEON_SET_REG(T0, rm, 1);
5533 NEON_SET_REG(T0, rm, 0);
5535 if (insn & (1 << 16)) {
5536 gen_neon_dup_u8(cpu_T[0], ((insn >> 17) & 3) * 8);
5537 } else if (insn & (1 << 17)) {
5538 if ((insn >> 18) & 1)
5539 gen_neon_dup_high16(cpu_T[0]);
5541 gen_neon_dup_low16(cpu_T[0]);
5543 for (pass = 0; pass < (q ? 4 : 2); pass++) {
5544 NEON_SET_REG(T0, rd, pass);
5554 static int disas_coproc_insn(CPUState * env, DisasContext *s, uint32_t insn)
5558 cpnum = (insn >> 8) & 0xf;
5559 if (arm_feature(env, ARM_FEATURE_XSCALE)
5560 && ((env->cp15.c15_cpar ^ 0x3fff) & (1 << cpnum)))
5566 if (arm_feature(env, ARM_FEATURE_IWMMXT)) {
5567 return disas_iwmmxt_insn(env, s, insn);
5568 } else if (arm_feature(env, ARM_FEATURE_XSCALE)) {
5569 return disas_dsp_insn(env, s, insn);
5574 return disas_vfp_insn (env, s, insn);
5576 return disas_cp15_insn (env, s, insn);
5578 /* Unknown coprocessor. See if the board has hooked it. */
5579 return disas_cp_insn (env, s, insn);
5584 /* Store a 64-bit value to a register pair. Clobbers val. */
5585 static void gen_storeq_reg(DisasContext *s, int rlow, int rhigh, TCGv val)
5589 tcg_gen_trunc_i64_i32(tmp, val);
5590 store_reg(s, rlow, tmp);
5592 tcg_gen_shri_i64(val, val, 32);
5593 tcg_gen_trunc_i64_i32(tmp, val);
5594 store_reg(s, rhigh, tmp);
5597 /* load a 32-bit value from a register and perform a 64-bit accumulate. */
5598 static void gen_addq_lo(DisasContext *s, TCGv val, int rlow)
5603 /* Load 64-bit value rd:rn. */
5604 tmp = tcg_temp_new(TCG_TYPE_I64);
5605 tmp2 = load_reg(s, rlow);
5606 tcg_gen_extu_i32_i64(tmp, tmp2);
5608 tcg_gen_add_i64(val, val, tmp);
5611 /* load and add a 64-bit value from a register pair. */
5612 static void gen_addq(DisasContext *s, TCGv val, int rlow, int rhigh)
5617 /* Load 64-bit value rd:rn. */
5618 tmp = tcg_temp_new(TCG_TYPE_I64);
5619 tmp2 = load_reg(s, rhigh);
5620 tcg_gen_extu_i32_i64(tmp, tmp2);
5622 tcg_gen_shli_i64(tmp, tmp, 32);
5623 tcg_gen_add_i64(val, val, tmp);
5625 tmp2 = load_reg(s, rlow);
5626 tcg_gen_extu_i32_i64(tmp, tmp2);
5628 tcg_gen_add_i64(val, val, tmp);
5631 /* Set N and Z flags from a 64-bit value. */
5632 static void gen_logicq_cc(TCGv val)
5634 TCGv tmp = new_tmp();
5635 gen_helper_logicq_cc(tmp, val);
5640 static void disas_arm_insn(CPUState * env, DisasContext *s)
5642 unsigned int cond, insn, val, op1, i, shift, rm, rs, rn, rd, sh;
5648 insn = ldl_code(s->pc);
5651 /* M variants do not implement ARM mode. */
5656 /* Unconditional instructions. */
5657 if (((insn >> 25) & 7) == 1) {
5658 /* NEON Data processing. */
5659 if (!arm_feature(env, ARM_FEATURE_NEON))
5662 if (disas_neon_data_insn(env, s, insn))
5666 if ((insn & 0x0f100000) == 0x04000000) {
5667 /* NEON load/store. */
5668 if (!arm_feature(env, ARM_FEATURE_NEON))
5671 if (disas_neon_ls_insn(env, s, insn))
5675 if ((insn & 0x0d70f000) == 0x0550f000)
5677 else if ((insn & 0x0ffffdff) == 0x01010000) {
5680 if (insn & (1 << 9)) {
5681 /* BE8 mode not implemented. */
5685 } else if ((insn & 0x0fffff00) == 0x057ff000) {
5686 switch ((insn >> 4) & 0xf) {
5689 gen_helper_clrex(cpu_env);
5695 /* We don't emulate caches so these are a no-op. */
5700 } else if ((insn & 0x0e5fffe0) == 0x084d0500) {
5706 op1 = (insn & 0x1f);
5707 if (op1 == (env->uncached_cpsr & CPSR_M)) {
5708 addr = load_reg(s, 13);
5711 gen_helper_get_r13_banked(addr, cpu_env, tcg_const_i32(op1));
5713 i = (insn >> 23) & 3;
5715 case 0: offset = -4; break; /* DA */
5716 case 1: offset = -8; break; /* DB */
5717 case 2: offset = 0; break; /* IA */
5718 case 3: offset = 4; break; /* IB */
5722 tcg_gen_addi_i32(addr, addr, offset);
5723 tmp = load_reg(s, 14);
5724 gen_st32(tmp, addr, 0);
5726 gen_helper_cpsr_read(tmp);
5727 tcg_gen_addi_i32(addr, addr, 4);
5728 gen_st32(tmp, addr, 0);
5729 if (insn & (1 << 21)) {
5730 /* Base writeback. */
5732 case 0: offset = -8; break;
5733 case 1: offset = -4; break;
5734 case 2: offset = 4; break;
5735 case 3: offset = 0; break;
5739 tcg_gen_addi_i32(addr, tmp, offset);
5740 if (op1 == (env->uncached_cpsr & CPSR_M)) {
5741 gen_movl_reg_T1(s, 13);
5743 gen_helper_set_r13_banked(cpu_env, tcg_const_i32(op1), cpu_T[1]);
5748 } else if ((insn & 0x0e5fffe0) == 0x081d0a00) {
5754 rn = (insn >> 16) & 0xf;
5755 addr = load_reg(s, rn);
5756 i = (insn >> 23) & 3;
5758 case 0: offset = -4; break; /* DA */
5759 case 1: offset = -8; break; /* DB */
5760 case 2: offset = 0; break; /* IA */
5761 case 3: offset = 4; break; /* IB */
5765 tcg_gen_addi_i32(addr, addr, offset);
5766 /* Load PC into tmp and CPSR into tmp2. */
5767 tmp = gen_ld32(addr, 0);
5768 tcg_gen_addi_i32(addr, addr, 4);
5769 tmp2 = gen_ld32(addr, 0);
5770 if (insn & (1 << 21)) {
5771 /* Base writeback. */
5773 case 0: offset = -8; break;
5774 case 1: offset = -4; break;
5775 case 2: offset = 4; break;
5776 case 3: offset = 0; break;
5780 tcg_gen_addi_i32(addr, addr, offset);
5781 store_reg(s, rn, addr);
5785 gen_rfe(s, tmp, tmp2);
5786 } else if ((insn & 0x0e000000) == 0x0a000000) {
5787 /* branch link and change to thumb (blx <offset>) */
5790 val = (uint32_t)s->pc;
5792 tcg_gen_movi_i32(tmp, val);
5793 store_reg(s, 14, tmp);
5794 /* Sign-extend the 24-bit offset */
5795 offset = (((int32_t)insn) << 8) >> 8;
5796 /* offset * 4 + bit24 * 2 + (thumb bit) */
5797 val += (offset << 2) | ((insn >> 23) & 2) | 1;
5798 /* pipeline offset */
5802 } else if ((insn & 0x0e000f00) == 0x0c000100) {
5803 if (arm_feature(env, ARM_FEATURE_IWMMXT)) {
5804 /* iWMMXt register transfer. */
5805 if (env->cp15.c15_cpar & (1 << 1))
5806 if (!disas_iwmmxt_insn(env, s, insn))
5809 } else if ((insn & 0x0fe00000) == 0x0c400000) {
5810 /* Coprocessor double register transfer. */
5811 } else if ((insn & 0x0f000010) == 0x0e000010) {
5812 /* Additional coprocessor register transfer. */
5813 } else if ((insn & 0x0ff10020) == 0x01000000) {
5816 /* cps (privileged) */
5820 if (insn & (1 << 19)) {
5821 if (insn & (1 << 8))
5823 if (insn & (1 << 7))
5825 if (insn & (1 << 6))
5827 if (insn & (1 << 18))
5830 if (insn & (1 << 17)) {
5832 val |= (insn & 0x1f);
5835 gen_op_movl_T0_im(val);
5836 gen_set_psr_T0(s, mask, 0);
5843 /* if not always execute, we generate a conditional jump to
5845 s->condlabel = gen_new_label();
5846 gen_test_cc(cond ^ 1, s->condlabel);
5849 if ((insn & 0x0f900000) == 0x03000000) {
5850 if ((insn & (1 << 21)) == 0) {
5852 rd = (insn >> 12) & 0xf;
5853 val = ((insn >> 4) & 0xf000) | (insn & 0xfff);
5854 if ((insn & (1 << 22)) == 0) {
5857 tcg_gen_movi_i32(tmp, val);
5860 tmp = load_reg(s, rd);
5861 tcg_gen_ext16u_i32(tmp, tmp);
5862 tcg_gen_ori_i32(tmp, tmp, val << 16);
5864 store_reg(s, rd, tmp);
5866 if (((insn >> 12) & 0xf) != 0xf)
5868 if (((insn >> 16) & 0xf) == 0) {
5869 gen_nop_hint(s, insn & 0xff);
5871 /* CPSR = immediate */
5873 shift = ((insn >> 8) & 0xf) * 2;
5875 val = (val >> shift) | (val << (32 - shift));
5876 gen_op_movl_T0_im(val);
5877 i = ((insn & (1 << 22)) != 0);
5878 if (gen_set_psr_T0(s, msr_mask(env, s, (insn >> 16) & 0xf, i), i))
5882 } else if ((insn & 0x0f900000) == 0x01000000
5883 && (insn & 0x00000090) != 0x00000090) {
5884 /* miscellaneous instructions */
5885 op1 = (insn >> 21) & 3;
5886 sh = (insn >> 4) & 0xf;
5889 case 0x0: /* move program status register */
5892 gen_movl_T0_reg(s, rm);
5893 i = ((op1 & 2) != 0);
5894 if (gen_set_psr_T0(s, msr_mask(env, s, (insn >> 16) & 0xf, i), i))
5898 rd = (insn >> 12) & 0xf;
5902 tmp = load_cpu_field(spsr);
5905 gen_helper_cpsr_read(tmp);
5907 store_reg(s, rd, tmp);
5912 /* branch/exchange thumb (bx). */
5913 tmp = load_reg(s, rm);
5915 } else if (op1 == 3) {
5917 rd = (insn >> 12) & 0xf;
5918 tmp = load_reg(s, rm);
5919 gen_helper_clz(tmp, tmp);
5920 store_reg(s, rd, tmp);
5928 /* Trivial implementation equivalent to bx. */
5929 tmp = load_reg(s, rm);
5939 /* branch link/exchange thumb (blx) */
5940 tmp = load_reg(s, rm);
5942 tcg_gen_movi_i32(tmp2, s->pc);
5943 store_reg(s, 14, tmp2);
5946 case 0x5: /* saturating add/subtract */
5947 rd = (insn >> 12) & 0xf;
5948 rn = (insn >> 16) & 0xf;
5949 tmp = load_reg(s, rn);
5950 tmp2 = load_reg(s, rn);
5952 gen_helper_double_saturate(tmp2, tmp2);
5954 gen_helper_sub_saturate(tmp, tmp, tmp2);
5956 gen_helper_add_saturate(tmp, tmp, tmp2);
5958 store_reg(s, rd, tmp);
5961 gen_set_condexec(s);
5962 gen_set_pc_im(s->pc - 4);
5963 gen_exception(EXCP_BKPT);
5964 s->is_jmp = DISAS_JUMP;
5966 case 0x8: /* signed multiply */
5970 rs = (insn >> 8) & 0xf;
5971 rn = (insn >> 12) & 0xf;
5972 rd = (insn >> 16) & 0xf;
5974 /* (32 * 16) >> 16 */
5975 tmp = load_reg(s, rm);
5976 tmp2 = load_reg(s, rs);
5978 tcg_gen_sari_i32(tmp2, tmp2, 16);
5981 tmp2 = gen_muls_i64_i32(tmp, tmp2);
5982 tcg_gen_shri_i64(tmp2, tmp2, 16);
5984 tcg_gen_trunc_i64_i32(tmp, tmp2);
5985 if ((sh & 2) == 0) {
5986 tmp2 = load_reg(s, rn);
5987 gen_helper_add_setq(tmp, tmp, tmp2);
5990 store_reg(s, rd, tmp);
5993 tmp = load_reg(s, rm);
5994 tmp2 = load_reg(s, rs);
5995 gen_mulxy(tmp, tmp2, sh & 2, sh & 4);
5998 tmp2 = tcg_temp_new(TCG_TYPE_I64);
5999 tcg_gen_ext_i32_i64(tmp2, tmp);
6001 gen_addq(s, tmp2, rn, rd);
6002 gen_storeq_reg(s, rn, rd, tmp2);
6005 tmp2 = load_reg(s, rn);
6006 gen_helper_add_setq(tmp, tmp, tmp2);
6009 store_reg(s, rd, tmp);
6016 } else if (((insn & 0x0e000000) == 0 &&
6017 (insn & 0x00000090) != 0x90) ||
6018 ((insn & 0x0e000000) == (1 << 25))) {
6019 int set_cc, logic_cc, shiftop;
6021 op1 = (insn >> 21) & 0xf;
6022 set_cc = (insn >> 20) & 1;
6023 logic_cc = table_logic_cc[op1] & set_cc;
6025 /* data processing instruction */
6026 if (insn & (1 << 25)) {
6027 /* immediate operand */
6029 shift = ((insn >> 8) & 0xf) * 2;
6031 val = (val >> shift) | (val << (32 - shift));
6032 gen_op_movl_T1_im(val);
6033 if (logic_cc && shift)
6034 gen_set_CF_bit31(cpu_T[1]);
6038 gen_movl_T1_reg(s, rm);
6039 shiftop = (insn >> 5) & 3;
6040 if (!(insn & (1 << 4))) {
6041 shift = (insn >> 7) & 0x1f;
6042 gen_arm_shift_im(cpu_T[1], shiftop, shift, logic_cc);
6044 rs = (insn >> 8) & 0xf;
6045 tmp = load_reg(s, rs);
6046 gen_arm_shift_reg(cpu_T[1], shiftop, tmp, logic_cc);
6049 if (op1 != 0x0f && op1 != 0x0d) {
6050 rn = (insn >> 16) & 0xf;
6051 gen_movl_T0_reg(s, rn);
6053 rd = (insn >> 12) & 0xf;
6056 gen_op_andl_T0_T1();
6057 gen_movl_reg_T0(s, rd);
6059 gen_op_logic_T0_cc();
6062 gen_op_xorl_T0_T1();
6063 gen_movl_reg_T0(s, rd);
6065 gen_op_logic_T0_cc();
6068 if (set_cc && rd == 15) {
6069 /* SUBS r15, ... is used for exception return. */
6072 gen_op_subl_T0_T1_cc();
6073 gen_exception_return(s);
6076 gen_op_subl_T0_T1_cc();
6078 gen_op_subl_T0_T1();
6079 gen_movl_reg_T0(s, rd);
6084 gen_op_rsbl_T0_T1_cc();
6086 gen_op_rsbl_T0_T1();
6087 gen_movl_reg_T0(s, rd);
6091 gen_op_addl_T0_T1_cc();
6093 gen_op_addl_T0_T1();
6094 gen_movl_reg_T0(s, rd);
6098 gen_op_adcl_T0_T1_cc();
6101 gen_movl_reg_T0(s, rd);
6105 gen_op_sbcl_T0_T1_cc();
6108 gen_movl_reg_T0(s, rd);
6112 gen_op_rscl_T0_T1_cc();
6115 gen_movl_reg_T0(s, rd);
6119 gen_op_andl_T0_T1();
6120 gen_op_logic_T0_cc();
6125 gen_op_xorl_T0_T1();
6126 gen_op_logic_T0_cc();
6131 gen_op_subl_T0_T1_cc();
6136 gen_op_addl_T0_T1_cc();
6141 gen_movl_reg_T0(s, rd);
6143 gen_op_logic_T0_cc();
6146 if (logic_cc && rd == 15) {
6147 /* MOVS r15, ... is used for exception return. */
6150 gen_op_movl_T0_T1();
6151 gen_exception_return(s);
6153 gen_movl_reg_T1(s, rd);
6155 gen_op_logic_T1_cc();
6159 gen_op_bicl_T0_T1();
6160 gen_movl_reg_T0(s, rd);
6162 gen_op_logic_T0_cc();
6167 gen_movl_reg_T1(s, rd);
6169 gen_op_logic_T1_cc();
6173 /* other instructions */
6174 op1 = (insn >> 24) & 0xf;
6178 /* multiplies, extra load/stores */
6179 sh = (insn >> 5) & 3;
6182 rd = (insn >> 16) & 0xf;
6183 rn = (insn >> 12) & 0xf;
6184 rs = (insn >> 8) & 0xf;
6186 op1 = (insn >> 20) & 0xf;
6188 case 0: case 1: case 2: case 3: case 6:
6190 tmp = load_reg(s, rs);
6191 tmp2 = load_reg(s, rm);
6192 tcg_gen_mul_i32(tmp, tmp, tmp2);
6194 if (insn & (1 << 22)) {
6195 /* Subtract (mls) */
6197 tmp2 = load_reg(s, rn);
6198 tcg_gen_sub_i32(tmp, tmp2, tmp);
6200 } else if (insn & (1 << 21)) {
6202 tmp2 = load_reg(s, rn);
6203 tcg_gen_add_i32(tmp, tmp, tmp2);
6206 if (insn & (1 << 20))
6208 store_reg(s, rd, tmp);
6212 tmp = load_reg(s, rs);
6213 tmp2 = load_reg(s, rm);
6214 if (insn & (1 << 22))
6215 tmp = gen_muls_i64_i32(tmp, tmp2);
6217 tmp = gen_mulu_i64_i32(tmp, tmp2);
6218 if (insn & (1 << 21)) /* mult accumulate */
6219 gen_addq(s, tmp, rn, rd);
6220 if (!(insn & (1 << 23))) { /* double accumulate */
6222 gen_addq_lo(s, tmp, rn);
6223 gen_addq_lo(s, tmp, rd);
6225 if (insn & (1 << 20))
6227 gen_storeq_reg(s, rn, rd, tmp);
6231 rn = (insn >> 16) & 0xf;
6232 rd = (insn >> 12) & 0xf;
6233 if (insn & (1 << 23)) {
6234 /* load/store exclusive */
6235 gen_movl_T1_reg(s, rn);
6237 if (insn & (1 << 20)) {
6238 gen_helper_mark_exclusive(cpu_env, cpu_T[1]);
6239 tmp = gen_ld32(addr, IS_USER(s));
6240 store_reg(s, rd, tmp);
6242 int label = gen_new_label();
6244 gen_helper_test_exclusive(cpu_T[0], cpu_env, addr);
6245 tcg_gen_brcondi_i32(TCG_COND_NE, cpu_T[0],
6247 tmp = load_reg(s,rm);
6248 gen_st32(tmp, cpu_T[1], IS_USER(s));
6249 gen_set_label(label);
6250 gen_movl_reg_T0(s, rd);
6253 /* SWP instruction */
6256 /* ??? This is not really atomic. However we know
6257 we never have multiple CPUs running in parallel,
6258 so it is good enough. */
6259 addr = load_reg(s, rn);
6260 tmp = load_reg(s, rm);
6261 if (insn & (1 << 22)) {
6262 tmp2 = gen_ld8u(addr, IS_USER(s));
6263 gen_st8(tmp, addr, IS_USER(s));
6265 tmp2 = gen_ld32(addr, IS_USER(s));
6266 gen_st32(tmp, addr, IS_USER(s));
6269 store_reg(s, rd, tmp2);
6275 /* Misc load/store */
6276 rn = (insn >> 16) & 0xf;
6277 rd = (insn >> 12) & 0xf;
6278 addr = load_reg(s, rn);
6279 if (insn & (1 << 24))
6280 gen_add_datah_offset(s, insn, 0, addr);
6282 if (insn & (1 << 20)) {
6286 tmp = gen_ld16u(addr, IS_USER(s));
6289 tmp = gen_ld8s(addr, IS_USER(s));
6293 tmp = gen_ld16s(addr, IS_USER(s));
6297 } else if (sh & 2) {
6301 tmp = load_reg(s, rd);
6302 gen_st32(tmp, addr, IS_USER(s));
6303 tcg_gen_addi_i32(addr, addr, 4);
6304 tmp = load_reg(s, rd + 1);
6305 gen_st32(tmp, addr, IS_USER(s));
6309 tmp = gen_ld32(addr, IS_USER(s));
6310 store_reg(s, rd, tmp);
6311 tcg_gen_addi_i32(addr, addr, 4);
6312 tmp = gen_ld32(addr, IS_USER(s));
6316 address_offset = -4;
6319 tmp = load_reg(s, rd);
6320 gen_st16(tmp, addr, IS_USER(s));
6323 /* Perform base writeback before the loaded value to
6324 ensure correct behavior with overlapping index registers.
6325 ldrd with base writeback is is undefined if the
6326 destination and index registers overlap. */
6327 if (!(insn & (1 << 24))) {
6328 gen_add_datah_offset(s, insn, address_offset, addr);
6329 store_reg(s, rn, addr);
6330 } else if (insn & (1 << 21)) {
6332 tcg_gen_addi_i32(addr, addr, address_offset);
6333 store_reg(s, rn, addr);
6338 /* Complete the load. */
6339 store_reg(s, rd, tmp);
6348 if (insn & (1 << 4)) {
6350 /* Armv6 Media instructions. */
6352 rn = (insn >> 16) & 0xf;
6353 rd = (insn >> 12) & 0xf;
6354 rs = (insn >> 8) & 0xf;
6355 switch ((insn >> 23) & 3) {
6356 case 0: /* Parallel add/subtract. */
6357 op1 = (insn >> 20) & 7;
6358 tmp = load_reg(s, rn);
6359 tmp2 = load_reg(s, rm);
6360 sh = (insn >> 5) & 7;
6361 if ((op1 & 3) == 0 || sh == 5 || sh == 6)
6363 gen_arm_parallel_addsub(op1, sh, tmp, tmp2);
6365 store_reg(s, rd, tmp);
6368 if ((insn & 0x00700020) == 0) {
6369 /* Halfword pack. */
6370 tmp = load_reg(s, rn);
6371 tmp2 = load_reg(s, rm);
6372 shift = (insn >> 7) & 0x1f;
6373 if (insn & (1 << 6)) {
6377 tcg_gen_sari_i32(tmp2, tmp2, shift);
6378 tcg_gen_andi_i32(tmp, tmp, 0xffff0000);
6379 tcg_gen_ext16u_i32(tmp2, tmp2);
6383 tcg_gen_shli_i32(tmp2, tmp2, shift);
6384 tcg_gen_ext16u_i32(tmp, tmp);
6385 tcg_gen_andi_i32(tmp2, tmp2, 0xffff0000);
6387 tcg_gen_or_i32(tmp, tmp, tmp2);
6389 store_reg(s, rd, tmp);
6390 } else if ((insn & 0x00200020) == 0x00200000) {
6392 tmp = load_reg(s, rm);
6393 shift = (insn >> 7) & 0x1f;
6394 if (insn & (1 << 6)) {
6397 tcg_gen_sari_i32(tmp, tmp, shift);
6399 tcg_gen_shli_i32(tmp, tmp, shift);
6401 sh = (insn >> 16) & 0x1f;
6403 if (insn & (1 << 22))
6404 gen_helper_usat(tmp, tmp, tcg_const_i32(sh));
6406 gen_helper_ssat(tmp, tmp, tcg_const_i32(sh));
6408 store_reg(s, rd, tmp);
6409 } else if ((insn & 0x00300fe0) == 0x00200f20) {
6411 tmp = load_reg(s, rm);
6412 sh = (insn >> 16) & 0x1f;
6414 if (insn & (1 << 22))
6415 gen_helper_usat16(tmp, tmp, tcg_const_i32(sh));
6417 gen_helper_ssat16(tmp, tmp, tcg_const_i32(sh));
6419 store_reg(s, rd, tmp);
6420 } else if ((insn & 0x00700fe0) == 0x00000fa0) {
6422 tmp = load_reg(s, rn);
6423 tmp2 = load_reg(s, rm);
6425 tcg_gen_ld_i32(tmp3, cpu_env, offsetof(CPUState, GE));
6426 gen_helper_sel_flags(tmp, tmp3, tmp, tmp2);
6429 store_reg(s, rd, tmp);
6430 } else if ((insn & 0x000003e0) == 0x00000060) {
6431 tmp = load_reg(s, rm);
6432 shift = (insn >> 10) & 3;
6433 /* ??? In many cases it's not neccessary to do a
6434 rotate, a shift is sufficient. */
6436 tcg_gen_rori_i32(tmp, tmp, shift * 8);
6437 op1 = (insn >> 20) & 7;
6439 case 0: gen_sxtb16(tmp); break;
6440 case 2: gen_sxtb(tmp); break;
6441 case 3: gen_sxth(tmp); break;
6442 case 4: gen_uxtb16(tmp); break;
6443 case 6: gen_uxtb(tmp); break;
6444 case 7: gen_uxth(tmp); break;
6445 default: goto illegal_op;
6448 tmp2 = load_reg(s, rn);
6449 if ((op1 & 3) == 0) {
6450 gen_add16(tmp, tmp2);
6452 tcg_gen_add_i32(tmp, tmp, tmp2);
6456 store_reg(s, rd, tmp);
6457 } else if ((insn & 0x003f0f60) == 0x003f0f20) {
6459 tmp = load_reg(s, rm);
6460 if (insn & (1 << 22)) {
6461 if (insn & (1 << 7)) {
6465 gen_helper_rbit(tmp, tmp);
6468 if (insn & (1 << 7))
6471 tcg_gen_bswap_i32(tmp, tmp);
6473 store_reg(s, rd, tmp);
6478 case 2: /* Multiplies (Type 3). */
6479 tmp = load_reg(s, rm);
6480 tmp2 = load_reg(s, rs);
6481 if (insn & (1 << 20)) {
6482 /* Signed multiply most significant [accumulate]. */
6483 tmp2 = gen_muls_i64_i32(tmp, tmp2);
6484 if (insn & (1 << 5))
6485 tcg_gen_addi_i64(tmp2, tmp2, 0x80000000u);
6486 tcg_gen_shri_i64(tmp2, tmp2, 32);
6488 tcg_gen_trunc_i64_i32(tmp, tmp2);
6490 tmp2 = load_reg(s, rn);
6491 if (insn & (1 << 6)) {
6492 tcg_gen_sub_i32(tmp, tmp, tmp2);
6494 tcg_gen_add_i32(tmp, tmp, tmp2);
6498 store_reg(s, rd, tmp);
6500 if (insn & (1 << 5))
6501 gen_swap_half(tmp2);
6502 gen_smul_dual(tmp, tmp2);
6503 /* This addition cannot overflow. */
6504 if (insn & (1 << 6)) {
6505 tcg_gen_sub_i32(tmp, tmp, tmp2);
6507 tcg_gen_add_i32(tmp, tmp, tmp2);
6510 if (insn & (1 << 22)) {
6511 /* smlald, smlsld */
6512 tmp2 = tcg_temp_new(TCG_TYPE_I64);
6513 tcg_gen_ext_i32_i64(tmp2, tmp);
6515 gen_addq(s, tmp2, rd, rn);
6516 gen_storeq_reg(s, rd, rn, tmp2);
6518 /* smuad, smusd, smlad, smlsd */
6521 tmp2 = load_reg(s, rd);
6522 gen_helper_add_setq(tmp, tmp, tmp2);
6525 store_reg(s, rn, tmp);
6530 op1 = ((insn >> 17) & 0x38) | ((insn >> 5) & 7);
6532 case 0: /* Unsigned sum of absolute differences. */
6534 tmp = load_reg(s, rm);
6535 tmp2 = load_reg(s, rs);
6536 gen_helper_usad8(tmp, tmp, tmp2);
6539 tmp2 = load_reg(s, rn);
6540 tcg_gen_add_i32(tmp, tmp, tmp2);
6543 store_reg(s, rd, tmp);
6545 case 0x20: case 0x24: case 0x28: case 0x2c:
6546 /* Bitfield insert/clear. */
6548 shift = (insn >> 7) & 0x1f;
6549 i = (insn >> 16) & 0x1f;
6553 tcg_gen_movi_i32(tmp, 0);
6555 tmp = load_reg(s, rm);
6558 tmp2 = load_reg(s, rd);
6559 gen_bfi(tmp, tmp2, tmp, shift, (1u << i) - 1);
6562 store_reg(s, rd, tmp);
6564 case 0x12: case 0x16: case 0x1a: case 0x1e: /* sbfx */
6565 case 0x32: case 0x36: case 0x3a: case 0x3e: /* ubfx */
6566 tmp = load_reg(s, rm);
6567 shift = (insn >> 7) & 0x1f;
6568 i = ((insn >> 16) & 0x1f) + 1;
6573 gen_ubfx(tmp, shift, (1u << i) - 1);
6575 gen_sbfx(tmp, shift, i);
6578 store_reg(s, rd, tmp);
6588 /* Check for undefined extension instructions
6589 * per the ARM Bible IE:
6590 * xxxx 0111 1111 xxxx xxxx xxxx 1111 xxxx
6592 sh = (0xf << 20) | (0xf << 4);
6593 if (op1 == 0x7 && ((insn & sh) == sh))
6597 /* load/store byte/word */
6598 rn = (insn >> 16) & 0xf;
6599 rd = (insn >> 12) & 0xf;
6600 tmp2 = load_reg(s, rn);
6601 i = (IS_USER(s) || (insn & 0x01200000) == 0x00200000);
6602 if (insn & (1 << 24))
6603 gen_add_data_offset(s, insn, tmp2);
6604 if (insn & (1 << 20)) {
6607 if (insn & (1 << 22)) {
6608 tmp = gen_ld8u(tmp2, i);
6610 tmp = gen_ld32(tmp2, i);
6614 tmp = load_reg(s, rd);
6615 if (insn & (1 << 22))
6616 gen_st8(tmp, tmp2, i);
6618 gen_st32(tmp, tmp2, i);
6620 if (!(insn & (1 << 24))) {
6621 gen_add_data_offset(s, insn, tmp2);
6622 store_reg(s, rn, tmp2);
6623 } else if (insn & (1 << 21)) {
6624 store_reg(s, rn, tmp2);
6628 if (insn & (1 << 20)) {
6629 /* Complete the load. */
6633 store_reg(s, rd, tmp);
6639 int j, n, user, loaded_base;
6641 /* load/store multiple words */
6642 /* XXX: store correct base if write back */
6644 if (insn & (1 << 22)) {
6646 goto illegal_op; /* only usable in supervisor mode */
6648 if ((insn & (1 << 15)) == 0)
6651 rn = (insn >> 16) & 0xf;
6652 addr = load_reg(s, rn);
6654 /* compute total size */
6656 TCGV_UNUSED(loaded_var);
6659 if (insn & (1 << i))
6662 /* XXX: test invalid n == 0 case ? */
6663 if (insn & (1 << 23)) {
6664 if (insn & (1 << 24)) {
6666 tcg_gen_addi_i32(addr, addr, 4);
6668 /* post increment */
6671 if (insn & (1 << 24)) {
6673 tcg_gen_addi_i32(addr, addr, -(n * 4));
6675 /* post decrement */
6677 tcg_gen_addi_i32(addr, addr, -((n - 1) * 4));
6682 if (insn & (1 << i)) {
6683 if (insn & (1 << 20)) {
6685 tmp = gen_ld32(addr, IS_USER(s));
6689 gen_helper_set_user_reg(tcg_const_i32(i), tmp);
6691 } else if (i == rn) {
6695 store_reg(s, i, tmp);
6700 /* special case: r15 = PC + 8 */
6701 val = (long)s->pc + 4;
6703 tcg_gen_movi_i32(tmp, val);
6706 gen_helper_get_user_reg(tmp, tcg_const_i32(i));
6708 tmp = load_reg(s, i);
6710 gen_st32(tmp, addr, IS_USER(s));
6713 /* no need to add after the last transfer */
6715 tcg_gen_addi_i32(addr, addr, 4);
6718 if (insn & (1 << 21)) {
6720 if (insn & (1 << 23)) {
6721 if (insn & (1 << 24)) {
6724 /* post increment */
6725 tcg_gen_addi_i32(addr, addr, 4);
6728 if (insn & (1 << 24)) {
6731 tcg_gen_addi_i32(addr, addr, -((n - 1) * 4));
6733 /* post decrement */
6734 tcg_gen_addi_i32(addr, addr, -(n * 4));
6737 store_reg(s, rn, addr);
6742 store_reg(s, rn, loaded_var);
6744 if ((insn & (1 << 22)) && !user) {
6745 /* Restore CPSR from SPSR. */
6746 tmp = load_cpu_field(spsr);
6747 gen_set_cpsr(tmp, 0xffffffff);
6749 s->is_jmp = DISAS_UPDATE;
6758 /* branch (and link) */
6759 val = (int32_t)s->pc;
6760 if (insn & (1 << 24)) {
6762 tcg_gen_movi_i32(tmp, val);
6763 store_reg(s, 14, tmp);
6765 offset = (((int32_t)insn << 8) >> 8);
6766 val += (offset << 2) + 4;
6774 if (disas_coproc_insn(env, s, insn))
6779 gen_set_pc_im(s->pc);
6780 s->is_jmp = DISAS_SWI;
6784 gen_set_condexec(s);
6785 gen_set_pc_im(s->pc - 4);
6786 gen_exception(EXCP_UDEF);
6787 s->is_jmp = DISAS_JUMP;
6793 /* Return true if this is a Thumb-2 logical op. */
6795 thumb2_logic_op(int op)
6800 /* Generate code for a Thumb-2 data processing operation. If CONDS is nonzero
6801 then set condition code flags based on the result of the operation.
6802 If SHIFTER_OUT is nonzero then set the carry flag for logical operations
6803 to the high bit of T1.
6804 Returns zero if the opcode is valid. */
6807 gen_thumb2_data_op(DisasContext *s, int op, int conds, uint32_t shifter_out)
6814 gen_op_andl_T0_T1();
6818 gen_op_bicl_T0_T1();
6831 gen_op_xorl_T0_T1();
6836 gen_op_addl_T0_T1_cc();
6838 gen_op_addl_T0_T1();
6842 gen_op_adcl_T0_T1_cc();
6848 gen_op_sbcl_T0_T1_cc();
6854 gen_op_subl_T0_T1_cc();
6856 gen_op_subl_T0_T1();
6860 gen_op_rsbl_T0_T1_cc();
6862 gen_op_rsbl_T0_T1();
6864 default: /* 5, 6, 7, 9, 12, 15. */
6868 gen_op_logic_T0_cc();
6870 gen_set_CF_bit31(cpu_T[1]);
6875 /* Translate a 32-bit thumb instruction. Returns nonzero if the instruction
6877 static int disas_thumb2_insn(CPUState *env, DisasContext *s, uint16_t insn_hw1)
6879 uint32_t insn, imm, shift, offset;
6880 uint32_t rd, rn, rm, rs;
6890 if (!(arm_feature(env, ARM_FEATURE_THUMB2)
6891 || arm_feature (env, ARM_FEATURE_M))) {
6892 /* Thumb-1 cores may need to treat bl and blx as a pair of
6893 16-bit instructions to get correct prefetch abort behavior. */
6895 if ((insn & (1 << 12)) == 0) {
6896 /* Second half of blx. */
6897 offset = ((insn & 0x7ff) << 1);
6898 tmp = load_reg(s, 14);
6899 tcg_gen_addi_i32(tmp, tmp, offset);
6900 tcg_gen_andi_i32(tmp, tmp, 0xfffffffc);
6903 tcg_gen_movi_i32(tmp2, s->pc | 1);
6904 store_reg(s, 14, tmp2);
6908 if (insn & (1 << 11)) {
6909 /* Second half of bl. */
6910 offset = ((insn & 0x7ff) << 1) | 1;
6911 tmp = load_reg(s, 14);
6912 tcg_gen_addi_i32(tmp, tmp, offset);
6915 tcg_gen_movi_i32(tmp2, s->pc | 1);
6916 store_reg(s, 14, tmp2);
6920 if ((s->pc & ~TARGET_PAGE_MASK) == 0) {
6921 /* Instruction spans a page boundary. Implement it as two
6922 16-bit instructions in case the second half causes an
6924 offset = ((int32_t)insn << 21) >> 9;
6925 gen_op_movl_T0_im(s->pc + 2 + offset);
6926 gen_movl_reg_T0(s, 14);
6929 /* Fall through to 32-bit decode. */
6932 insn = lduw_code(s->pc);
6934 insn |= (uint32_t)insn_hw1 << 16;
6936 if ((insn & 0xf800e800) != 0xf000e800) {
6940 rn = (insn >> 16) & 0xf;
6941 rs = (insn >> 12) & 0xf;
6942 rd = (insn >> 8) & 0xf;
6944 switch ((insn >> 25) & 0xf) {
6945 case 0: case 1: case 2: case 3:
6946 /* 16-bit instructions. Should never happen. */
6949 if (insn & (1 << 22)) {
6950 /* Other load/store, table branch. */
6951 if (insn & 0x01200000) {
6952 /* Load/store doubleword. */
6955 tcg_gen_movi_i32(addr, s->pc & ~3);
6957 addr = load_reg(s, rn);
6959 offset = (insn & 0xff) * 4;
6960 if ((insn & (1 << 23)) == 0)
6962 if (insn & (1 << 24)) {
6963 tcg_gen_addi_i32(addr, addr, offset);
6966 if (insn & (1 << 20)) {
6968 tmp = gen_ld32(addr, IS_USER(s));
6969 store_reg(s, rs, tmp);
6970 tcg_gen_addi_i32(addr, addr, 4);
6971 tmp = gen_ld32(addr, IS_USER(s));
6972 store_reg(s, rd, tmp);
6975 tmp = load_reg(s, rs);
6976 gen_st32(tmp, addr, IS_USER(s));
6977 tcg_gen_addi_i32(addr, addr, 4);
6978 tmp = load_reg(s, rd);
6979 gen_st32(tmp, addr, IS_USER(s));
6981 if (insn & (1 << 21)) {
6982 /* Base writeback. */
6985 tcg_gen_addi_i32(addr, addr, offset - 4);
6986 store_reg(s, rn, addr);
6990 } else if ((insn & (1 << 23)) == 0) {
6991 /* Load/store exclusive word. */
6992 gen_movl_T1_reg(s, rn);
6994 if (insn & (1 << 20)) {
6995 gen_helper_mark_exclusive(cpu_env, cpu_T[1]);
6996 tmp = gen_ld32(addr, IS_USER(s));
6997 store_reg(s, rd, tmp);
6999 int label = gen_new_label();
7000 gen_helper_test_exclusive(cpu_T[0], cpu_env, addr);
7001 tcg_gen_brcondi_i32(TCG_COND_NE, cpu_T[0],
7003 tmp = load_reg(s, rs);
7004 gen_st32(tmp, cpu_T[1], IS_USER(s));
7005 gen_set_label(label);
7006 gen_movl_reg_T0(s, rd);
7008 } else if ((insn & (1 << 6)) == 0) {
7012 tcg_gen_movi_i32(addr, s->pc);
7014 addr = load_reg(s, rn);
7016 tmp = load_reg(s, rm);
7017 tcg_gen_add_i32(addr, addr, tmp);
7018 if (insn & (1 << 4)) {
7020 tcg_gen_add_i32(addr, addr, tmp);
7022 tmp = gen_ld16u(addr, IS_USER(s));
7025 tmp = gen_ld8u(addr, IS_USER(s));
7028 tcg_gen_shli_i32(tmp, tmp, 1);
7029 tcg_gen_addi_i32(tmp, tmp, s->pc);
7030 store_reg(s, 15, tmp);
7032 /* Load/store exclusive byte/halfword/doubleword. */
7033 /* ??? These are not really atomic. However we know
7034 we never have multiple CPUs running in parallel,
7035 so it is good enough. */
7036 op = (insn >> 4) & 0x3;
7037 /* Must use a global reg for the address because we have
7038 a conditional branch in the store instruction. */
7039 gen_movl_T1_reg(s, rn);
7041 if (insn & (1 << 20)) {
7042 gen_helper_mark_exclusive(cpu_env, addr);
7045 tmp = gen_ld8u(addr, IS_USER(s));
7048 tmp = gen_ld16u(addr, IS_USER(s));
7051 tmp = gen_ld32(addr, IS_USER(s));
7052 tcg_gen_addi_i32(addr, addr, 4);
7053 tmp2 = gen_ld32(addr, IS_USER(s));
7054 store_reg(s, rd, tmp2);
7059 store_reg(s, rs, tmp);
7061 int label = gen_new_label();
7062 /* Must use a global that is not killed by the branch. */
7063 gen_helper_test_exclusive(cpu_T[0], cpu_env, addr);
7064 tcg_gen_brcondi_i32(TCG_COND_NE, cpu_T[0], 0, label);
7065 tmp = load_reg(s, rs);
7068 gen_st8(tmp, addr, IS_USER(s));
7071 gen_st16(tmp, addr, IS_USER(s));
7074 gen_st32(tmp, addr, IS_USER(s));
7075 tcg_gen_addi_i32(addr, addr, 4);
7076 tmp = load_reg(s, rd);
7077 gen_st32(tmp, addr, IS_USER(s));
7082 gen_set_label(label);
7083 gen_movl_reg_T0(s, rm);
7087 /* Load/store multiple, RFE, SRS. */
7088 if (((insn >> 23) & 1) == ((insn >> 24) & 1)) {
7089 /* Not available in user mode. */
7092 if (insn & (1 << 20)) {
7094 addr = load_reg(s, rn);
7095 if ((insn & (1 << 24)) == 0)
7096 tcg_gen_addi_i32(addr, addr, -8);
7097 /* Load PC into tmp and CPSR into tmp2. */
7098 tmp = gen_ld32(addr, 0);
7099 tcg_gen_addi_i32(addr, addr, 4);
7100 tmp2 = gen_ld32(addr, 0);
7101 if (insn & (1 << 21)) {
7102 /* Base writeback. */
7103 if (insn & (1 << 24)) {
7104 tcg_gen_addi_i32(addr, addr, 4);
7106 tcg_gen_addi_i32(addr, addr, -4);
7108 store_reg(s, rn, addr);
7112 gen_rfe(s, tmp, tmp2);
7116 if (op == (env->uncached_cpsr & CPSR_M)) {
7117 addr = load_reg(s, 13);
7120 gen_helper_get_r13_banked(addr, cpu_env, tcg_const_i32(op));
7122 if ((insn & (1 << 24)) == 0) {
7123 tcg_gen_addi_i32(addr, addr, -8);
7125 tmp = load_reg(s, 14);
7126 gen_st32(tmp, addr, 0);
7127 tcg_gen_addi_i32(addr, addr, 4);
7129 gen_helper_cpsr_read(tmp);
7130 gen_st32(tmp, addr, 0);
7131 if (insn & (1 << 21)) {
7132 if ((insn & (1 << 24)) == 0) {
7133 tcg_gen_addi_i32(addr, addr, -4);
7135 tcg_gen_addi_i32(addr, addr, 4);
7137 if (op == (env->uncached_cpsr & CPSR_M)) {
7138 store_reg(s, 13, addr);
7140 gen_helper_set_r13_banked(cpu_env,
7141 tcg_const_i32(op), addr);
7149 /* Load/store multiple. */
7150 addr = load_reg(s, rn);
7152 for (i = 0; i < 16; i++) {
7153 if (insn & (1 << i))
7156 if (insn & (1 << 24)) {
7157 tcg_gen_addi_i32(addr, addr, -offset);
7160 for (i = 0; i < 16; i++) {
7161 if ((insn & (1 << i)) == 0)
7163 if (insn & (1 << 20)) {
7165 tmp = gen_ld32(addr, IS_USER(s));
7169 store_reg(s, i, tmp);
7173 tmp = load_reg(s, i);
7174 gen_st32(tmp, addr, IS_USER(s));
7176 tcg_gen_addi_i32(addr, addr, 4);
7178 if (insn & (1 << 21)) {
7179 /* Base register writeback. */
7180 if (insn & (1 << 24)) {
7181 tcg_gen_addi_i32(addr, addr, -offset);
7183 /* Fault if writeback register is in register list. */
7184 if (insn & (1 << rn))
7186 store_reg(s, rn, addr);
7193 case 5: /* Data processing register constant shift. */
7195 gen_op_movl_T0_im(0);
7197 gen_movl_T0_reg(s, rn);
7198 gen_movl_T1_reg(s, rm);
7199 op = (insn >> 21) & 0xf;
7200 shiftop = (insn >> 4) & 3;
7201 shift = ((insn >> 6) & 3) | ((insn >> 10) & 0x1c);
7202 conds = (insn & (1 << 20)) != 0;
7203 logic_cc = (conds && thumb2_logic_op(op));
7204 gen_arm_shift_im(cpu_T[1], shiftop, shift, logic_cc);
7205 if (gen_thumb2_data_op(s, op, conds, 0))
7208 gen_movl_reg_T0(s, rd);
7210 case 13: /* Misc data processing. */
7211 op = ((insn >> 22) & 6) | ((insn >> 7) & 1);
7212 if (op < 4 && (insn & 0xf000) != 0xf000)
7215 case 0: /* Register controlled shift. */
7216 tmp = load_reg(s, rn);
7217 tmp2 = load_reg(s, rm);
7218 if ((insn & 0x70) != 0)
7220 op = (insn >> 21) & 3;
7221 logic_cc = (insn & (1 << 20)) != 0;
7222 gen_arm_shift_reg(tmp, op, tmp2, logic_cc);
7225 store_reg(s, rd, tmp);
7227 case 1: /* Sign/zero extend. */
7228 tmp = load_reg(s, rm);
7229 shift = (insn >> 4) & 3;
7230 /* ??? In many cases it's not neccessary to do a
7231 rotate, a shift is sufficient. */
7233 tcg_gen_rori_i32(tmp, tmp, shift * 8);
7234 op = (insn >> 20) & 7;
7236 case 0: gen_sxth(tmp); break;
7237 case 1: gen_uxth(tmp); break;
7238 case 2: gen_sxtb16(tmp); break;
7239 case 3: gen_uxtb16(tmp); break;
7240 case 4: gen_sxtb(tmp); break;
7241 case 5: gen_uxtb(tmp); break;
7242 default: goto illegal_op;
7245 tmp2 = load_reg(s, rn);
7246 if ((op >> 1) == 1) {
7247 gen_add16(tmp, tmp2);
7249 tcg_gen_add_i32(tmp, tmp, tmp2);
7253 store_reg(s, rd, tmp);
7255 case 2: /* SIMD add/subtract. */
7256 op = (insn >> 20) & 7;
7257 shift = (insn >> 4) & 7;
7258 if ((op & 3) == 3 || (shift & 3) == 3)
7260 tmp = load_reg(s, rn);
7261 tmp2 = load_reg(s, rm);
7262 gen_thumb2_parallel_addsub(op, shift, tmp, tmp2);
7264 store_reg(s, rd, tmp);
7266 case 3: /* Other data processing. */
7267 op = ((insn >> 17) & 0x38) | ((insn >> 4) & 7);
7269 /* Saturating add/subtract. */
7270 tmp = load_reg(s, rn);
7271 tmp2 = load_reg(s, rm);
7273 gen_helper_double_saturate(tmp, tmp);
7275 gen_helper_sub_saturate(tmp, tmp2, tmp);
7277 gen_helper_add_saturate(tmp, tmp, tmp2);
7280 tmp = load_reg(s, rn);
7282 case 0x0a: /* rbit */
7283 gen_helper_rbit(tmp, tmp);
7285 case 0x08: /* rev */
7286 tcg_gen_bswap_i32(tmp, tmp);
7288 case 0x09: /* rev16 */
7291 case 0x0b: /* revsh */
7294 case 0x10: /* sel */
7295 tmp2 = load_reg(s, rm);
7297 tcg_gen_ld_i32(tmp3, cpu_env, offsetof(CPUState, GE));
7298 gen_helper_sel_flags(tmp, tmp3, tmp, tmp2);
7302 case 0x18: /* clz */
7303 gen_helper_clz(tmp, tmp);
7309 store_reg(s, rd, tmp);
7311 case 4: case 5: /* 32-bit multiply. Sum of absolute differences. */
7312 op = (insn >> 4) & 0xf;
7313 tmp = load_reg(s, rn);
7314 tmp2 = load_reg(s, rm);
7315 switch ((insn >> 20) & 7) {
7316 case 0: /* 32 x 32 -> 32 */
7317 tcg_gen_mul_i32(tmp, tmp, tmp2);
7320 tmp2 = load_reg(s, rs);
7322 tcg_gen_sub_i32(tmp, tmp2, tmp);
7324 tcg_gen_add_i32(tmp, tmp, tmp2);
7328 case 1: /* 16 x 16 -> 32 */
7329 gen_mulxy(tmp, tmp2, op & 2, op & 1);
7332 tmp2 = load_reg(s, rs);
7333 gen_helper_add_setq(tmp, tmp, tmp2);
7337 case 2: /* Dual multiply add. */
7338 case 4: /* Dual multiply subtract. */
7340 gen_swap_half(tmp2);
7341 gen_smul_dual(tmp, tmp2);
7342 /* This addition cannot overflow. */
7343 if (insn & (1 << 22)) {
7344 tcg_gen_sub_i32(tmp, tmp, tmp2);
7346 tcg_gen_add_i32(tmp, tmp, tmp2);
7351 tmp2 = load_reg(s, rs);
7352 gen_helper_add_setq(tmp, tmp, tmp2);
7356 case 3: /* 32 * 16 -> 32msb */
7358 tcg_gen_sari_i32(tmp2, tmp2, 16);
7361 tmp2 = gen_muls_i64_i32(tmp, tmp2);
7362 tcg_gen_shri_i64(tmp2, tmp2, 16);
7364 tcg_gen_trunc_i64_i32(tmp, tmp2);
7367 tmp2 = load_reg(s, rs);
7368 gen_helper_add_setq(tmp, tmp, tmp2);
7372 case 5: case 6: /* 32 * 32 -> 32msb */
7373 gen_imull(tmp, tmp2);
7374 if (insn & (1 << 5)) {
7375 gen_roundqd(tmp, tmp2);
7382 tmp2 = load_reg(s, rs);
7383 if (insn & (1 << 21)) {
7384 tcg_gen_add_i32(tmp, tmp, tmp2);
7386 tcg_gen_sub_i32(tmp, tmp2, tmp);
7391 case 7: /* Unsigned sum of absolute differences. */
7392 gen_helper_usad8(tmp, tmp, tmp2);
7395 tmp2 = load_reg(s, rs);
7396 tcg_gen_add_i32(tmp, tmp, tmp2);
7401 store_reg(s, rd, tmp);
7403 case 6: case 7: /* 64-bit multiply, Divide. */
7404 op = ((insn >> 4) & 0xf) | ((insn >> 16) & 0x70);
7405 tmp = load_reg(s, rn);
7406 tmp2 = load_reg(s, rm);
7407 if ((op & 0x50) == 0x10) {
7409 if (!arm_feature(env, ARM_FEATURE_DIV))
7412 gen_helper_udiv(tmp, tmp, tmp2);
7414 gen_helper_sdiv(tmp, tmp, tmp2);
7416 store_reg(s, rd, tmp);
7417 } else if ((op & 0xe) == 0xc) {
7418 /* Dual multiply accumulate long. */
7420 gen_swap_half(tmp2);
7421 gen_smul_dual(tmp, tmp2);
7423 tcg_gen_sub_i32(tmp, tmp, tmp2);
7425 tcg_gen_add_i32(tmp, tmp, tmp2);
7428 tmp2 = tcg_temp_new(TCG_TYPE_I64);
7429 gen_addq(s, tmp, rs, rd);
7430 gen_storeq_reg(s, rs, rd, tmp);
7433 /* Unsigned 64-bit multiply */
7434 tmp = gen_mulu_i64_i32(tmp, tmp2);
7438 gen_mulxy(tmp, tmp2, op & 2, op & 1);
7440 tmp2 = tcg_temp_new(TCG_TYPE_I64);
7441 tcg_gen_ext_i32_i64(tmp2, tmp);
7445 /* Signed 64-bit multiply */
7446 tmp = gen_muls_i64_i32(tmp, tmp2);
7451 gen_addq_lo(s, tmp, rs);
7452 gen_addq_lo(s, tmp, rd);
7453 } else if (op & 0x40) {
7454 /* 64-bit accumulate. */
7455 gen_addq(s, tmp, rs, rd);
7457 gen_storeq_reg(s, rs, rd, tmp);
7462 case 6: case 7: case 14: case 15:
7464 if (((insn >> 24) & 3) == 3) {
7465 /* Translate into the equivalent ARM encoding. */
7466 insn = (insn & 0xe2ffffff) | ((insn & (1 << 28)) >> 4);
7467 if (disas_neon_data_insn(env, s, insn))
7470 if (insn & (1 << 28))
7472 if (disas_coproc_insn (env, s, insn))
7476 case 8: case 9: case 10: case 11:
7477 if (insn & (1 << 15)) {
7478 /* Branches, misc control. */
7479 if (insn & 0x5000) {
7480 /* Unconditional branch. */
7481 /* signextend(hw1[10:0]) -> offset[:12]. */
7482 offset = ((int32_t)insn << 5) >> 9 & ~(int32_t)0xfff;
7483 /* hw1[10:0] -> offset[11:1]. */
7484 offset |= (insn & 0x7ff) << 1;
7485 /* (~hw2[13, 11] ^ offset[24]) -> offset[23,22]
7486 offset[24:22] already have the same value because of the
7487 sign extension above. */
7488 offset ^= ((~insn) & (1 << 13)) << 10;
7489 offset ^= ((~insn) & (1 << 11)) << 11;
7491 if (insn & (1 << 14)) {
7492 /* Branch and link. */
7493 gen_op_movl_T1_im(s->pc | 1);
7494 gen_movl_reg_T1(s, 14);
7498 if (insn & (1 << 12)) {
7503 offset &= ~(uint32_t)2;
7504 gen_bx_im(s, offset);
7506 } else if (((insn >> 23) & 7) == 7) {
7508 if (insn & (1 << 13))
7511 if (insn & (1 << 26)) {
7512 /* Secure monitor call (v6Z) */
7513 goto illegal_op; /* not implemented. */
7515 op = (insn >> 20) & 7;
7517 case 0: /* msr cpsr. */
7519 tmp = load_reg(s, rn);
7520 addr = tcg_const_i32(insn & 0xff);
7521 gen_helper_v7m_msr(cpu_env, addr, tmp);
7526 case 1: /* msr spsr. */
7529 gen_movl_T0_reg(s, rn);
7530 if (gen_set_psr_T0(s,
7531 msr_mask(env, s, (insn >> 8) & 0xf, op == 1),
7535 case 2: /* cps, nop-hint. */
7536 if (((insn >> 8) & 7) == 0) {
7537 gen_nop_hint(s, insn & 0xff);
7539 /* Implemented as NOP in user mode. */
7544 if (insn & (1 << 10)) {
7545 if (insn & (1 << 7))
7547 if (insn & (1 << 6))
7549 if (insn & (1 << 5))
7551 if (insn & (1 << 9))
7552 imm = CPSR_A | CPSR_I | CPSR_F;
7554 if (insn & (1 << 8)) {
7556 imm |= (insn & 0x1f);
7559 gen_op_movl_T0_im(imm);
7560 gen_set_psr_T0(s, offset, 0);
7563 case 3: /* Special control operations. */
7564 op = (insn >> 4) & 0xf;
7567 gen_helper_clrex(cpu_env);
7572 /* These execute as NOPs. */
7580 /* Trivial implementation equivalent to bx. */
7581 tmp = load_reg(s, rn);
7584 case 5: /* Exception return. */
7585 /* Unpredictable in user mode. */
7587 case 6: /* mrs cpsr. */
7590 addr = tcg_const_i32(insn & 0xff);
7591 gen_helper_v7m_mrs(tmp, cpu_env, addr);
7593 gen_helper_cpsr_read(tmp);
7595 store_reg(s, rd, tmp);
7597 case 7: /* mrs spsr. */
7598 /* Not accessible in user mode. */
7599 if (IS_USER(s) || IS_M(env))
7601 tmp = load_cpu_field(spsr);
7602 store_reg(s, rd, tmp);
7607 /* Conditional branch. */
7608 op = (insn >> 22) & 0xf;
7609 /* Generate a conditional jump to next instruction. */
7610 s->condlabel = gen_new_label();
7611 gen_test_cc(op ^ 1, s->condlabel);
7614 /* offset[11:1] = insn[10:0] */
7615 offset = (insn & 0x7ff) << 1;
7616 /* offset[17:12] = insn[21:16]. */
7617 offset |= (insn & 0x003f0000) >> 4;
7618 /* offset[31:20] = insn[26]. */
7619 offset |= ((int32_t)((insn << 5) & 0x80000000)) >> 11;
7620 /* offset[18] = insn[13]. */
7621 offset |= (insn & (1 << 13)) << 5;
7622 /* offset[19] = insn[11]. */
7623 offset |= (insn & (1 << 11)) << 8;
7625 /* jump to the offset */
7626 gen_jmp(s, s->pc + offset);
7629 /* Data processing immediate. */
7630 if (insn & (1 << 25)) {
7631 if (insn & (1 << 24)) {
7632 if (insn & (1 << 20))
7634 /* Bitfield/Saturate. */
7635 op = (insn >> 21) & 7;
7637 shift = ((insn >> 6) & 3) | ((insn >> 10) & 0x1c);
7640 tcg_gen_movi_i32(tmp, 0);
7642 tmp = load_reg(s, rn);
7645 case 2: /* Signed bitfield extract. */
7647 if (shift + imm > 32)
7650 gen_sbfx(tmp, shift, imm);
7652 case 6: /* Unsigned bitfield extract. */
7654 if (shift + imm > 32)
7657 gen_ubfx(tmp, shift, (1u << imm) - 1);
7659 case 3: /* Bitfield insert/clear. */
7662 imm = imm + 1 - shift;
7664 tmp2 = load_reg(s, rd);
7665 gen_bfi(tmp, tmp2, tmp, shift, (1u << imm) - 1);
7671 default: /* Saturate. */
7674 tcg_gen_sari_i32(tmp, tmp, shift);
7676 tcg_gen_shli_i32(tmp, tmp, shift);
7678 tmp2 = tcg_const_i32(imm);
7681 if ((op & 1) && shift == 0)
7682 gen_helper_usat16(tmp, tmp, tmp2);
7684 gen_helper_usat(tmp, tmp, tmp2);
7687 if ((op & 1) && shift == 0)
7688 gen_helper_ssat16(tmp, tmp, tmp2);
7690 gen_helper_ssat(tmp, tmp, tmp2);
7694 store_reg(s, rd, tmp);
7696 imm = ((insn & 0x04000000) >> 15)
7697 | ((insn & 0x7000) >> 4) | (insn & 0xff);
7698 if (insn & (1 << 22)) {
7699 /* 16-bit immediate. */
7700 imm |= (insn >> 4) & 0xf000;
7701 if (insn & (1 << 23)) {
7703 tmp = load_reg(s, rd);
7704 tcg_gen_ext16u_i32(tmp, tmp);
7705 tcg_gen_ori_i32(tmp, tmp, imm << 16);
7709 tcg_gen_movi_i32(tmp, imm);
7712 /* Add/sub 12-bit immediate. */
7714 offset = s->pc & ~(uint32_t)3;
7715 if (insn & (1 << 23))
7720 tcg_gen_movi_i32(tmp, offset);
7722 tmp = load_reg(s, rn);
7723 if (insn & (1 << 23))
7724 tcg_gen_subi_i32(tmp, tmp, imm);
7726 tcg_gen_addi_i32(tmp, tmp, imm);
7729 store_reg(s, rd, tmp);
7732 int shifter_out = 0;
7733 /* modified 12-bit immediate. */
7734 shift = ((insn & 0x04000000) >> 23) | ((insn & 0x7000) >> 12);
7735 imm = (insn & 0xff);
7738 /* Nothing to do. */
7740 case 1: /* 00XY00XY */
7743 case 2: /* XY00XY00 */
7747 case 3: /* XYXYXYXY */
7751 default: /* Rotated constant. */
7752 shift = (shift << 1) | (imm >> 7);
7754 imm = imm << (32 - shift);
7758 gen_op_movl_T1_im(imm);
7759 rn = (insn >> 16) & 0xf;
7761 gen_op_movl_T0_im(0);
7763 gen_movl_T0_reg(s, rn);
7764 op = (insn >> 21) & 0xf;
7765 if (gen_thumb2_data_op(s, op, (insn & (1 << 20)) != 0,
7768 rd = (insn >> 8) & 0xf;
7770 gen_movl_reg_T0(s, rd);
7775 case 12: /* Load/store single data item. */
7780 if ((insn & 0x01100000) == 0x01000000) {
7781 if (disas_neon_ls_insn(env, s, insn))
7789 /* s->pc has already been incremented by 4. */
7790 imm = s->pc & 0xfffffffc;
7791 if (insn & (1 << 23))
7792 imm += insn & 0xfff;
7794 imm -= insn & 0xfff;
7795 tcg_gen_movi_i32(addr, imm);
7797 addr = load_reg(s, rn);
7798 if (insn & (1 << 23)) {
7799 /* Positive offset. */
7801 tcg_gen_addi_i32(addr, addr, imm);
7803 op = (insn >> 8) & 7;
7806 case 0: case 8: /* Shifted Register. */
7807 shift = (insn >> 4) & 0xf;
7810 tmp = load_reg(s, rm);
7812 tcg_gen_shli_i32(tmp, tmp, shift);
7813 tcg_gen_add_i32(addr, addr, tmp);
7816 case 4: /* Negative offset. */
7817 tcg_gen_addi_i32(addr, addr, -imm);
7819 case 6: /* User privilege. */
7820 tcg_gen_addi_i32(addr, addr, imm);
7823 case 1: /* Post-decrement. */
7826 case 3: /* Post-increment. */
7830 case 5: /* Pre-decrement. */
7833 case 7: /* Pre-increment. */
7834 tcg_gen_addi_i32(addr, addr, imm);
7842 op = ((insn >> 21) & 3) | ((insn >> 22) & 4);
7843 if (insn & (1 << 20)) {
7845 if (rs == 15 && op != 2) {
7848 /* Memory hint. Implemented as NOP. */
7851 case 0: tmp = gen_ld8u(addr, user); break;
7852 case 4: tmp = gen_ld8s(addr, user); break;
7853 case 1: tmp = gen_ld16u(addr, user); break;
7854 case 5: tmp = gen_ld16s(addr, user); break;
7855 case 2: tmp = gen_ld32(addr, user); break;
7856 default: goto illegal_op;
7861 store_reg(s, rs, tmp);
7868 tmp = load_reg(s, rs);
7870 case 0: gen_st8(tmp, addr, user); break;
7871 case 1: gen_st16(tmp, addr, user); break;
7872 case 2: gen_st32(tmp, addr, user); break;
7873 default: goto illegal_op;
7877 tcg_gen_addi_i32(addr, addr, imm);
7879 store_reg(s, rn, addr);
7893 static void disas_thumb_insn(CPUState *env, DisasContext *s)
7895 uint32_t val, insn, op, rm, rn, rd, shift, cond;
7902 if (s->condexec_mask) {
7903 cond = s->condexec_cond;
7904 s->condlabel = gen_new_label();
7905 gen_test_cc(cond ^ 1, s->condlabel);
7909 insn = lduw_code(s->pc);
7912 switch (insn >> 12) {
7915 op = (insn >> 11) & 3;
7918 rn = (insn >> 3) & 7;
7919 gen_movl_T0_reg(s, rn);
7920 if (insn & (1 << 10)) {
7922 gen_op_movl_T1_im((insn >> 6) & 7);
7925 rm = (insn >> 6) & 7;
7926 gen_movl_T1_reg(s, rm);
7928 if (insn & (1 << 9)) {
7929 if (s->condexec_mask)
7930 gen_op_subl_T0_T1();
7932 gen_op_subl_T0_T1_cc();
7934 if (s->condexec_mask)
7935 gen_op_addl_T0_T1();
7937 gen_op_addl_T0_T1_cc();
7939 gen_movl_reg_T0(s, rd);
7941 /* shift immediate */
7942 rm = (insn >> 3) & 7;
7943 shift = (insn >> 6) & 0x1f;
7944 tmp = load_reg(s, rm);
7945 gen_arm_shift_im(tmp, op, shift, s->condexec_mask == 0);
7946 if (!s->condexec_mask)
7948 store_reg(s, rd, tmp);
7952 /* arithmetic large immediate */
7953 op = (insn >> 11) & 3;
7954 rd = (insn >> 8) & 0x7;
7956 gen_op_movl_T0_im(insn & 0xff);
7958 gen_movl_T0_reg(s, rd);
7959 gen_op_movl_T1_im(insn & 0xff);
7963 if (!s->condexec_mask)
7964 gen_op_logic_T0_cc();
7967 gen_op_subl_T0_T1_cc();
7970 if (s->condexec_mask)
7971 gen_op_addl_T0_T1();
7973 gen_op_addl_T0_T1_cc();
7976 if (s->condexec_mask)
7977 gen_op_subl_T0_T1();
7979 gen_op_subl_T0_T1_cc();
7983 gen_movl_reg_T0(s, rd);
7986 if (insn & (1 << 11)) {
7987 rd = (insn >> 8) & 7;
7988 /* load pc-relative. Bit 1 of PC is ignored. */
7989 val = s->pc + 2 + ((insn & 0xff) * 4);
7990 val &= ~(uint32_t)2;
7992 tcg_gen_movi_i32(addr, val);
7993 tmp = gen_ld32(addr, IS_USER(s));
7995 store_reg(s, rd, tmp);
7998 if (insn & (1 << 10)) {
7999 /* data processing extended or blx */
8000 rd = (insn & 7) | ((insn >> 4) & 8);
8001 rm = (insn >> 3) & 0xf;
8002 op = (insn >> 8) & 3;
8005 gen_movl_T0_reg(s, rd);
8006 gen_movl_T1_reg(s, rm);
8007 gen_op_addl_T0_T1();
8008 gen_movl_reg_T0(s, rd);
8011 gen_movl_T0_reg(s, rd);
8012 gen_movl_T1_reg(s, rm);
8013 gen_op_subl_T0_T1_cc();
8015 case 2: /* mov/cpy */
8016 gen_movl_T0_reg(s, rm);
8017 gen_movl_reg_T0(s, rd);
8019 case 3:/* branch [and link] exchange thumb register */
8020 tmp = load_reg(s, rm);
8021 if (insn & (1 << 7)) {
8022 val = (uint32_t)s->pc | 1;
8024 tcg_gen_movi_i32(tmp2, val);
8025 store_reg(s, 14, tmp2);
8033 /* data processing register */
8035 rm = (insn >> 3) & 7;
8036 op = (insn >> 6) & 0xf;
8037 if (op == 2 || op == 3 || op == 4 || op == 7) {
8038 /* the shift/rotate ops want the operands backwards */
8047 if (op == 9) /* neg */
8048 gen_op_movl_T0_im(0);
8049 else if (op != 0xf) /* mvn doesn't read its first operand */
8050 gen_movl_T0_reg(s, rd);
8052 gen_movl_T1_reg(s, rm);
8055 gen_op_andl_T0_T1();
8056 if (!s->condexec_mask)
8057 gen_op_logic_T0_cc();
8060 gen_op_xorl_T0_T1();
8061 if (!s->condexec_mask)
8062 gen_op_logic_T0_cc();
8065 if (s->condexec_mask) {
8066 gen_helper_shl(cpu_T[1], cpu_T[1], cpu_T[0]);
8068 gen_helper_shl_cc(cpu_T[1], cpu_T[1], cpu_T[0]);
8069 gen_op_logic_T1_cc();
8073 if (s->condexec_mask) {
8074 gen_helper_shr(cpu_T[1], cpu_T[1], cpu_T[0]);
8076 gen_helper_shr_cc(cpu_T[1], cpu_T[1], cpu_T[0]);
8077 gen_op_logic_T1_cc();
8081 if (s->condexec_mask) {
8082 gen_helper_sar(cpu_T[1], cpu_T[1], cpu_T[0]);
8084 gen_helper_sar_cc(cpu_T[1], cpu_T[1], cpu_T[0]);
8085 gen_op_logic_T1_cc();
8089 if (s->condexec_mask)
8092 gen_op_adcl_T0_T1_cc();
8095 if (s->condexec_mask)
8098 gen_op_sbcl_T0_T1_cc();
8101 if (s->condexec_mask) {
8102 gen_helper_ror(cpu_T[1], cpu_T[1], cpu_T[0]);
8104 gen_helper_ror_cc(cpu_T[1], cpu_T[1], cpu_T[0]);
8105 gen_op_logic_T1_cc();
8109 gen_op_andl_T0_T1();
8110 gen_op_logic_T0_cc();
8114 if (s->condexec_mask)
8115 tcg_gen_neg_i32(cpu_T[0], cpu_T[1]);
8117 gen_op_subl_T0_T1_cc();
8120 gen_op_subl_T0_T1_cc();
8124 gen_op_addl_T0_T1_cc();
8129 if (!s->condexec_mask)
8130 gen_op_logic_T0_cc();
8133 gen_op_mull_T0_T1();
8134 if (!s->condexec_mask)
8135 gen_op_logic_T0_cc();
8138 gen_op_bicl_T0_T1();
8139 if (!s->condexec_mask)
8140 gen_op_logic_T0_cc();
8144 if (!s->condexec_mask)
8145 gen_op_logic_T1_cc();
8152 gen_movl_reg_T1(s, rm);
8154 gen_movl_reg_T0(s, rd);
8159 /* load/store register offset. */
8161 rn = (insn >> 3) & 7;
8162 rm = (insn >> 6) & 7;
8163 op = (insn >> 9) & 7;
8164 addr = load_reg(s, rn);
8165 tmp = load_reg(s, rm);
8166 tcg_gen_add_i32(addr, addr, tmp);
8169 if (op < 3) /* store */
8170 tmp = load_reg(s, rd);
8174 gen_st32(tmp, addr, IS_USER(s));
8177 gen_st16(tmp, addr, IS_USER(s));
8180 gen_st8(tmp, addr, IS_USER(s));
8183 tmp = gen_ld8s(addr, IS_USER(s));
8186 tmp = gen_ld32(addr, IS_USER(s));
8189 tmp = gen_ld16u(addr, IS_USER(s));
8192 tmp = gen_ld8u(addr, IS_USER(s));
8195 tmp = gen_ld16s(addr, IS_USER(s));
8198 if (op >= 3) /* load */
8199 store_reg(s, rd, tmp);
8204 /* load/store word immediate offset */
8206 rn = (insn >> 3) & 7;
8207 addr = load_reg(s, rn);
8208 val = (insn >> 4) & 0x7c;
8209 tcg_gen_addi_i32(addr, addr, val);
8211 if (insn & (1 << 11)) {
8213 tmp = gen_ld32(addr, IS_USER(s));
8214 store_reg(s, rd, tmp);
8217 tmp = load_reg(s, rd);
8218 gen_st32(tmp, addr, IS_USER(s));
8224 /* load/store byte immediate offset */
8226 rn = (insn >> 3) & 7;
8227 addr = load_reg(s, rn);
8228 val = (insn >> 6) & 0x1f;
8229 tcg_gen_addi_i32(addr, addr, val);
8231 if (insn & (1 << 11)) {
8233 tmp = gen_ld8u(addr, IS_USER(s));
8234 store_reg(s, rd, tmp);
8237 tmp = load_reg(s, rd);
8238 gen_st8(tmp, addr, IS_USER(s));
8244 /* load/store halfword immediate offset */
8246 rn = (insn >> 3) & 7;
8247 addr = load_reg(s, rn);
8248 val = (insn >> 5) & 0x3e;
8249 tcg_gen_addi_i32(addr, addr, val);
8251 if (insn & (1 << 11)) {
8253 tmp = gen_ld16u(addr, IS_USER(s));
8254 store_reg(s, rd, tmp);
8257 tmp = load_reg(s, rd);
8258 gen_st16(tmp, addr, IS_USER(s));
8264 /* load/store from stack */
8265 rd = (insn >> 8) & 7;
8266 addr = load_reg(s, 13);
8267 val = (insn & 0xff) * 4;
8268 tcg_gen_addi_i32(addr, addr, val);
8270 if (insn & (1 << 11)) {
8272 tmp = gen_ld32(addr, IS_USER(s));
8273 store_reg(s, rd, tmp);
8276 tmp = load_reg(s, rd);
8277 gen_st32(tmp, addr, IS_USER(s));
8283 /* add to high reg */
8284 rd = (insn >> 8) & 7;
8285 if (insn & (1 << 11)) {
8287 tmp = load_reg(s, 13);
8289 /* PC. bit 1 is ignored. */
8291 tcg_gen_movi_i32(tmp, (s->pc + 2) & ~(uint32_t)2);
8293 val = (insn & 0xff) * 4;
8294 tcg_gen_addi_i32(tmp, tmp, val);
8295 store_reg(s, rd, tmp);
8300 op = (insn >> 8) & 0xf;
8303 /* adjust stack pointer */
8304 tmp = load_reg(s, 13);
8305 val = (insn & 0x7f) * 4;
8306 if (insn & (1 << 7))
8307 val = -(int32_t)val;
8308 tcg_gen_addi_i32(tmp, tmp, val);
8309 store_reg(s, 13, tmp);
8312 case 2: /* sign/zero extend. */
8315 rm = (insn >> 3) & 7;
8316 tmp = load_reg(s, rm);
8317 switch ((insn >> 6) & 3) {
8318 case 0: gen_sxth(tmp); break;
8319 case 1: gen_sxtb(tmp); break;
8320 case 2: gen_uxth(tmp); break;
8321 case 3: gen_uxtb(tmp); break;
8323 store_reg(s, rd, tmp);
8325 case 4: case 5: case 0xc: case 0xd:
8327 addr = load_reg(s, 13);
8328 if (insn & (1 << 8))
8332 for (i = 0; i < 8; i++) {
8333 if (insn & (1 << i))
8336 if ((insn & (1 << 11)) == 0) {
8337 tcg_gen_addi_i32(addr, addr, -offset);
8339 for (i = 0; i < 8; i++) {
8340 if (insn & (1 << i)) {
8341 if (insn & (1 << 11)) {
8343 tmp = gen_ld32(addr, IS_USER(s));
8344 store_reg(s, i, tmp);
8347 tmp = load_reg(s, i);
8348 gen_st32(tmp, addr, IS_USER(s));
8350 /* advance to the next address. */
8351 tcg_gen_addi_i32(addr, addr, 4);
8355 if (insn & (1 << 8)) {
8356 if (insn & (1 << 11)) {
8358 tmp = gen_ld32(addr, IS_USER(s));
8359 /* don't set the pc until the rest of the instruction
8363 tmp = load_reg(s, 14);
8364 gen_st32(tmp, addr, IS_USER(s));
8366 tcg_gen_addi_i32(addr, addr, 4);
8368 if ((insn & (1 << 11)) == 0) {
8369 tcg_gen_addi_i32(addr, addr, -offset);
8371 /* write back the new stack pointer */
8372 store_reg(s, 13, addr);
8373 /* set the new PC value */
8374 if ((insn & 0x0900) == 0x0900)
8378 case 1: case 3: case 9: case 11: /* czb */
8380 tmp = load_reg(s, rm);
8381 s->condlabel = gen_new_label();
8383 if (insn & (1 << 11))
8384 tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 0, s->condlabel);
8386 tcg_gen_brcondi_i32(TCG_COND_NE, tmp, 0, s->condlabel);
8388 offset = ((insn & 0xf8) >> 2) | (insn & 0x200) >> 3;
8389 val = (uint32_t)s->pc + 2;
8394 case 15: /* IT, nop-hint. */
8395 if ((insn & 0xf) == 0) {
8396 gen_nop_hint(s, (insn >> 4) & 0xf);
8400 s->condexec_cond = (insn >> 4) & 0xe;
8401 s->condexec_mask = insn & 0x1f;
8402 /* No actual code generated for this insn, just setup state. */
8405 case 0xe: /* bkpt */
8406 gen_set_condexec(s);
8407 gen_set_pc_im(s->pc - 2);
8408 gen_exception(EXCP_BKPT);
8409 s->is_jmp = DISAS_JUMP;
8414 rn = (insn >> 3) & 0x7;
8416 tmp = load_reg(s, rn);
8417 switch ((insn >> 6) & 3) {
8418 case 0: tcg_gen_bswap_i32(tmp, tmp); break;
8419 case 1: gen_rev16(tmp); break;
8420 case 3: gen_revsh(tmp); break;
8421 default: goto illegal_op;
8423 store_reg(s, rd, tmp);
8431 tmp = tcg_const_i32((insn & (1 << 4)) != 0);
8434 addr = tcg_const_i32(16);
8435 gen_helper_v7m_msr(cpu_env, addr, tmp);
8439 addr = tcg_const_i32(17);
8440 gen_helper_v7m_msr(cpu_env, addr, tmp);
8444 if (insn & (1 << 4))
8445 shift = CPSR_A | CPSR_I | CPSR_F;
8449 val = ((insn & 7) << 6) & shift;
8450 gen_op_movl_T0_im(val);
8451 gen_set_psr_T0(s, shift, 0);
8461 /* load/store multiple */
8462 rn = (insn >> 8) & 0x7;
8463 addr = load_reg(s, rn);
8464 for (i = 0; i < 8; i++) {
8465 if (insn & (1 << i)) {
8466 if (insn & (1 << 11)) {
8468 tmp = gen_ld32(addr, IS_USER(s));
8469 store_reg(s, i, tmp);
8472 tmp = load_reg(s, i);
8473 gen_st32(tmp, addr, IS_USER(s));
8475 /* advance to the next address */
8476 tcg_gen_addi_i32(addr, addr, 4);
8479 /* Base register writeback. */
8480 if ((insn & (1 << rn)) == 0) {
8481 store_reg(s, rn, addr);
8488 /* conditional branch or swi */
8489 cond = (insn >> 8) & 0xf;
8495 gen_set_condexec(s);
8496 gen_set_pc_im(s->pc);
8497 s->is_jmp = DISAS_SWI;
8500 /* generate a conditional jump to next instruction */
8501 s->condlabel = gen_new_label();
8502 gen_test_cc(cond ^ 1, s->condlabel);
8504 gen_movl_T1_reg(s, 15);
8506 /* jump to the offset */
8507 val = (uint32_t)s->pc + 2;
8508 offset = ((int32_t)insn << 24) >> 24;
8514 if (insn & (1 << 11)) {
8515 if (disas_thumb2_insn(env, s, insn))
8519 /* unconditional branch */
8520 val = (uint32_t)s->pc;
8521 offset = ((int32_t)insn << 21) >> 21;
8522 val += (offset << 1) + 2;
8527 if (disas_thumb2_insn(env, s, insn))
8533 gen_set_condexec(s);
8534 gen_set_pc_im(s->pc - 4);
8535 gen_exception(EXCP_UDEF);
8536 s->is_jmp = DISAS_JUMP;
8540 gen_set_condexec(s);
8541 gen_set_pc_im(s->pc - 2);
8542 gen_exception(EXCP_UDEF);
8543 s->is_jmp = DISAS_JUMP;
8546 /* generate intermediate code in gen_opc_buf and gen_opparam_buf for
8547 basic block 'tb'. If search_pc is TRUE, also generate PC
8548 information for each intermediate instruction. */
8549 static inline void gen_intermediate_code_internal(CPUState *env,
8550 TranslationBlock *tb,
8553 DisasContext dc1, *dc = &dc1;
8554 uint16_t *gen_opc_end;
8556 target_ulong pc_start;
8557 uint32_t next_page_start;
8561 /* generate intermediate code */
8563 memset(temps, 0, sizeof(temps));
8569 gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
8571 dc->is_jmp = DISAS_NEXT;
8573 dc->singlestep_enabled = env->singlestep_enabled;
8575 dc->thumb = env->thumb;
8576 dc->condexec_mask = (env->condexec_bits & 0xf) << 1;
8577 dc->condexec_cond = env->condexec_bits >> 4;
8579 #if !defined(CONFIG_USER_ONLY)
8581 dc->user = ((env->v7m.exception == 0) && (env->v7m.control & 1));
8583 dc->user = (env->uncached_cpsr & 0x1f) == ARM_CPU_MODE_USR;
8586 cpu_F0s = tcg_temp_new(TCG_TYPE_I32);
8587 cpu_F1s = tcg_temp_new(TCG_TYPE_I32);
8588 cpu_F0d = tcg_temp_new(TCG_TYPE_I64);
8589 cpu_F1d = tcg_temp_new(TCG_TYPE_I64);
8592 /* FIXME: cpu_M0 can probably be the same as cpu_V0. */
8593 cpu_M0 = tcg_temp_new(TCG_TYPE_I64);
8594 next_page_start = (pc_start & TARGET_PAGE_MASK) + TARGET_PAGE_SIZE;
8597 max_insns = tb->cflags & CF_COUNT_MASK;
8599 max_insns = CF_COUNT_MASK;
8602 /* Reset the conditional execution bits immediately. This avoids
8603 complications trying to do it at the end of the block. */
8604 if (env->condexec_bits)
8606 TCGv tmp = new_tmp();
8607 tcg_gen_movi_i32(tmp, 0);
8608 store_cpu_field(tmp, condexec_bits);
8611 #ifdef CONFIG_USER_ONLY
8612 /* Intercept jump to the magic kernel page. */
8613 if (dc->pc >= 0xffff0000) {
8614 /* We always get here via a jump, so know we are not in a
8615 conditional execution block. */
8616 gen_exception(EXCP_KERNEL_TRAP);
8617 dc->is_jmp = DISAS_UPDATE;
8621 if (dc->pc >= 0xfffffff0 && IS_M(env)) {
8622 /* We always get here via a jump, so know we are not in a
8623 conditional execution block. */
8624 gen_exception(EXCP_EXCEPTION_EXIT);
8625 dc->is_jmp = DISAS_UPDATE;
8630 if (env->nb_breakpoints > 0) {
8631 for(j = 0; j < env->nb_breakpoints; j++) {
8632 if (env->breakpoints[j] == dc->pc) {
8633 gen_set_condexec(dc);
8634 gen_set_pc_im(dc->pc);
8635 gen_exception(EXCP_DEBUG);
8636 dc->is_jmp = DISAS_JUMP;
8637 /* Advance PC so that clearing the breakpoint will
8638 invalidate this TB. */
8640 goto done_generating;
8646 j = gen_opc_ptr - gen_opc_buf;
8650 gen_opc_instr_start[lj++] = 0;
8652 gen_opc_pc[lj] = dc->pc;
8653 gen_opc_instr_start[lj] = 1;
8654 gen_opc_icount[lj] = num_insns;
8657 if (num_insns + 1 == max_insns && (tb->cflags & CF_LAST_IO))
8661 disas_thumb_insn(env, dc);
8662 if (dc->condexec_mask) {
8663 dc->condexec_cond = (dc->condexec_cond & 0xe)
8664 | ((dc->condexec_mask >> 4) & 1);
8665 dc->condexec_mask = (dc->condexec_mask << 1) & 0x1f;
8666 if (dc->condexec_mask == 0) {
8667 dc->condexec_cond = 0;
8671 disas_arm_insn(env, dc);
8674 fprintf(stderr, "Internal resource leak before %08x\n", dc->pc);
8678 if (dc->condjmp && !dc->is_jmp) {
8679 gen_set_label(dc->condlabel);
8682 /* Terminate the TB on memory ops if watchpoints are present. */
8683 /* FIXME: This should be replacd by the deterministic execution
8684 * IRQ raising bits. */
8685 if (dc->is_mem && env->nb_watchpoints)
8688 /* Translation stops when a conditional branch is enoutered.
8689 * Otherwise the subsequent code could get translated several times.
8690 * Also stop translation when a page boundary is reached. This
8691 * ensures prefetch aborts occur at the right place. */
8693 } while (!dc->is_jmp && gen_opc_ptr < gen_opc_end &&
8694 !env->singlestep_enabled &&
8695 dc->pc < next_page_start &&
8696 num_insns < max_insns);
8698 if (tb->cflags & CF_LAST_IO) {
8700 /* FIXME: This can theoretically happen with self-modifying
8702 cpu_abort(env, "IO on conditional branch instruction");
8707 /* At this stage dc->condjmp will only be set when the skipped
8708 instruction was a conditional branch or trap, and the PC has
8709 already been written. */
8710 if (unlikely(env->singlestep_enabled)) {
8711 /* Make sure the pc is updated, and raise a debug exception. */
8713 gen_set_condexec(dc);
8714 if (dc->is_jmp == DISAS_SWI) {
8715 gen_exception(EXCP_SWI);
8717 gen_exception(EXCP_DEBUG);
8719 gen_set_label(dc->condlabel);
8721 if (dc->condjmp || !dc->is_jmp) {
8722 gen_set_pc_im(dc->pc);
8725 gen_set_condexec(dc);
8726 if (dc->is_jmp == DISAS_SWI && !dc->condjmp) {
8727 gen_exception(EXCP_SWI);
8729 /* FIXME: Single stepping a WFI insn will not halt
8731 gen_exception(EXCP_DEBUG);
8734 /* While branches must always occur at the end of an IT block,
8735 there are a few other things that can cause us to terminate
8736 the TB in the middel of an IT block:
8737 - Exception generating instructions (bkpt, swi, undefined).
8739 - Hardware watchpoints.
8740 Hardware breakpoints have already been handled and skip this code.
8742 gen_set_condexec(dc);
8743 switch(dc->is_jmp) {
8745 gen_goto_tb(dc, 1, dc->pc);
8750 /* indicate that the hash table must be used to find the next TB */
8754 /* nothing more to generate */
8760 gen_exception(EXCP_SWI);
8764 gen_set_label(dc->condlabel);
8765 gen_set_condexec(dc);
8766 gen_goto_tb(dc, 1, dc->pc);
8772 gen_icount_end(tb, num_insns);
8773 *gen_opc_ptr = INDEX_op_end;
8776 if (loglevel & CPU_LOG_TB_IN_ASM) {
8777 fprintf(logfile, "----------------\n");
8778 fprintf(logfile, "IN: %s\n", lookup_symbol(pc_start));
8779 target_disas(logfile, pc_start, dc->pc - pc_start, env->thumb);
8780 fprintf(logfile, "\n");
8784 j = gen_opc_ptr - gen_opc_buf;
8787 gen_opc_instr_start[lj++] = 0;
8789 tb->size = dc->pc - pc_start;
8790 tb->icount = num_insns;
8794 void gen_intermediate_code(CPUState *env, TranslationBlock *tb)
8796 gen_intermediate_code_internal(env, tb, 0);
8799 void gen_intermediate_code_pc(CPUState *env, TranslationBlock *tb)
8801 gen_intermediate_code_internal(env, tb, 1);
8804 static const char *cpu_mode_names[16] = {
8805 "usr", "fiq", "irq", "svc", "???", "???", "???", "abt",
8806 "???", "???", "???", "und", "???", "???", "???", "sys"
8809 void cpu_dump_state(CPUState *env, FILE *f,
8810 int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
8820 /* ??? This assumes float64 and double have the same layout.
8821 Oh well, it's only debug dumps. */
8830 cpu_fprintf(f, "R%02d=%08x", i, env->regs[i]);
8832 cpu_fprintf(f, "\n");
8834 cpu_fprintf(f, " ");
8836 psr = cpsr_read(env);
8837 cpu_fprintf(f, "PSR=%08x %c%c%c%c %c %s%d\n",
8839 psr & (1 << 31) ? 'N' : '-',
8840 psr & (1 << 30) ? 'Z' : '-',
8841 psr & (1 << 29) ? 'C' : '-',
8842 psr & (1 << 28) ? 'V' : '-',
8843 psr & CPSR_T ? 'T' : 'A',
8844 cpu_mode_names[psr & 0xf], (psr & 0x10) ? 32 : 26);
8847 for (i = 0; i < 16; i++) {
8848 d.d = env->vfp.regs[i];
8852 cpu_fprintf(f, "s%02d=%08x(%8g) s%02d=%08x(%8g) d%02d=%08x%08x(%8g)\n",
8853 i * 2, (int)s0.i, s0.s,
8854 i * 2 + 1, (int)s1.i, s1.s,
8855 i, (int)(uint32_t)d.l.upper, (int)(uint32_t)d.l.lower,
8858 cpu_fprintf(f, "FPSCR: %08x\n", (int)env->vfp.xregs[ARM_VFP_FPSCR]);
8862 void gen_pc_load(CPUState *env, TranslationBlock *tb,
8863 unsigned long searched_pc, int pc_pos, void *puc)
8865 env->regs[15] = gen_opc_pc[pc_pos];