4 * Copyright (c) 2003 Fabrice Bellard
5 * Copyright (c) 2005-2007 CodeSourcery
6 * Copyright (c) 2007 OpenedHand, Ltd.
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2 of the License, or (at your option) any later version.
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
36 #define ENABLE_ARCH_5J 0
37 #define ENABLE_ARCH_6 arm_feature(env, ARM_FEATURE_V6)
38 #define ENABLE_ARCH_6K arm_feature(env, ARM_FEATURE_V6K)
39 #define ENABLE_ARCH_6T2 arm_feature(env, ARM_FEATURE_THUMB2)
40 #define ENABLE_ARCH_7 arm_feature(env, ARM_FEATURE_V7)
42 #define ARCH(x) if (!ENABLE_ARCH_##x) goto illegal_op;
44 /* internal defines */
45 typedef struct DisasContext {
48 /* Nonzero if this instruction has been conditionally skipped. */
50 /* The label that will be jumped to when the instruction is skipped. */
52 /* Thumb-2 condtional execution bits. */
55 struct TranslationBlock *tb;
56 int singlestep_enabled;
59 #if !defined(CONFIG_USER_ONLY)
64 #if defined(CONFIG_USER_ONLY)
67 #define IS_USER(s) (s->user)
70 /* These instructions trap after executing, so defer them until after the
71 conditional executions state has been updated. */
75 /* XXX: move that elsewhere */
80 /* We reuse the same 64-bit temporaries for efficiency. */
81 static TCGv cpu_V0, cpu_V1, cpu_M0;
83 /* FIXME: These should be removed. */
85 static TCGv cpu_F0s, cpu_F1s, cpu_F0d, cpu_F1d;
87 #define ICOUNT_TEMP cpu_T[0]
88 #include "gen-icount.h"
90 /* initialize TCG globals. */
91 void arm_translate_init(void)
93 cpu_env = tcg_global_reg_new(TCG_TYPE_PTR, TCG_AREG0, "env");
95 cpu_T[0] = tcg_global_reg_new(TCG_TYPE_I32, TCG_AREG1, "T0");
96 cpu_T[1] = tcg_global_reg_new(TCG_TYPE_I32, TCG_AREG2, "T1");
99 /* The code generator doesn't like lots of temporaries, so maintain our own
100 cache for reuse within a function. */
102 static int num_temps;
103 static TCGv temps[MAX_TEMPS];
105 /* Allocate a temporary variable. */
106 static TCGv new_tmp(void)
109 if (num_temps == MAX_TEMPS)
112 if (GET_TCGV(temps[num_temps]))
113 return temps[num_temps++];
115 tmp = tcg_temp_new(TCG_TYPE_I32);
116 temps[num_temps++] = tmp;
120 /* Release a temporary variable. */
121 static void dead_tmp(TCGv tmp)
126 if (GET_TCGV(temps[i]) == GET_TCGV(tmp))
129 /* Shuffle this temp to the last slot. */
130 while (GET_TCGV(temps[i]) != GET_TCGV(tmp))
132 while (i < num_temps) {
133 temps[i] = temps[i + 1];
139 static inline TCGv load_cpu_offset(int offset)
141 TCGv tmp = new_tmp();
142 tcg_gen_ld_i32(tmp, cpu_env, offset);
146 #define load_cpu_field(name) load_cpu_offset(offsetof(CPUState, name))
148 static inline void store_cpu_offset(TCGv var, int offset)
150 tcg_gen_st_i32(var, cpu_env, offset);
154 #define store_cpu_field(var, name) \
155 store_cpu_offset(var, offsetof(CPUState, name))
157 /* Set a variable to the value of a CPU register. */
158 static void load_reg_var(DisasContext *s, TCGv var, int reg)
162 /* normaly, since we updated PC, we need only to add one insn */
164 addr = (long)s->pc + 2;
166 addr = (long)s->pc + 4;
167 tcg_gen_movi_i32(var, addr);
169 tcg_gen_ld_i32(var, cpu_env, offsetof(CPUState, regs[reg]));
173 /* Create a new temporary and set it to the value of a CPU register. */
174 static inline TCGv load_reg(DisasContext *s, int reg)
176 TCGv tmp = new_tmp();
177 load_reg_var(s, tmp, reg);
181 /* Set a CPU register. The source must be a temporary and will be
183 static void store_reg(DisasContext *s, int reg, TCGv var)
186 tcg_gen_andi_i32(var, var, ~1);
187 s->is_jmp = DISAS_JUMP;
189 tcg_gen_st_i32(var, cpu_env, offsetof(CPUState, regs[reg]));
194 /* Basic operations. */
195 #define gen_op_movl_T0_T1() tcg_gen_mov_i32(cpu_T[0], cpu_T[1])
196 #define gen_op_movl_T1_T0() tcg_gen_mov_i32(cpu_T[1], cpu_T[0])
197 #define gen_op_movl_T0_im(im) tcg_gen_movi_i32(cpu_T[0], im)
198 #define gen_op_movl_T1_im(im) tcg_gen_movi_i32(cpu_T[1], im)
200 #define gen_op_addl_T1_im(im) tcg_gen_addi_i32(cpu_T[1], cpu_T[1], im)
201 #define gen_op_addl_T0_T1() tcg_gen_add_i32(cpu_T[0], cpu_T[0], cpu_T[1])
202 #define gen_op_subl_T0_T1() tcg_gen_sub_i32(cpu_T[0], cpu_T[0], cpu_T[1])
203 #define gen_op_rsbl_T0_T1() tcg_gen_sub_i32(cpu_T[0], cpu_T[1], cpu_T[0])
205 #define gen_op_addl_T0_T1_cc() gen_helper_add_cc(cpu_T[0], cpu_T[0], cpu_T[1])
206 #define gen_op_adcl_T0_T1_cc() gen_helper_adc_cc(cpu_T[0], cpu_T[0], cpu_T[1])
207 #define gen_op_subl_T0_T1_cc() gen_helper_sub_cc(cpu_T[0], cpu_T[0], cpu_T[1])
208 #define gen_op_sbcl_T0_T1_cc() gen_helper_sbc_cc(cpu_T[0], cpu_T[0], cpu_T[1])
209 #define gen_op_rsbl_T0_T1_cc() gen_helper_sub_cc(cpu_T[0], cpu_T[1], cpu_T[0])
210 #define gen_op_rscl_T0_T1_cc() gen_helper_sbc_cc(cpu_T[0], cpu_T[1], cpu_T[0])
212 #define gen_op_andl_T0_T1() tcg_gen_and_i32(cpu_T[0], cpu_T[0], cpu_T[1])
213 #define gen_op_xorl_T0_T1() tcg_gen_xor_i32(cpu_T[0], cpu_T[0], cpu_T[1])
214 #define gen_op_orl_T0_T1() tcg_gen_or_i32(cpu_T[0], cpu_T[0], cpu_T[1])
215 #define gen_op_notl_T0() tcg_gen_not_i32(cpu_T[0], cpu_T[0])
216 #define gen_op_notl_T1() tcg_gen_not_i32(cpu_T[1], cpu_T[1])
217 #define gen_op_logic_T0_cc() gen_logic_CC(cpu_T[0]);
218 #define gen_op_logic_T1_cc() gen_logic_CC(cpu_T[1]);
220 #define gen_op_shll_T0_im(im) tcg_gen_shli_i32(cpu_T[0], cpu_T[0], im)
221 #define gen_op_shll_T1_im(im) tcg_gen_shli_i32(cpu_T[1], cpu_T[1], im)
222 #define gen_op_shrl_T1_im(im) tcg_gen_shri_i32(cpu_T[1], cpu_T[1], im)
223 #define gen_op_sarl_T1_im(im) tcg_gen_sari_i32(cpu_T[1], cpu_T[1], im)
224 #define gen_op_rorl_T1_im(im) tcg_gen_rori_i32(cpu_T[1], cpu_T[1], im)
226 /* Value extensions. */
227 #define gen_uxtb(var) tcg_gen_ext8u_i32(var, var)
228 #define gen_uxth(var) tcg_gen_ext16u_i32(var, var)
229 #define gen_sxtb(var) tcg_gen_ext8s_i32(var, var)
230 #define gen_sxth(var) tcg_gen_ext16s_i32(var, var)
232 #define gen_sxtb16(var) gen_helper_sxtb16(var, var)
233 #define gen_uxtb16(var) gen_helper_uxtb16(var, var)
235 #define gen_op_mul_T0_T1() tcg_gen_mul_i32(cpu_T[0], cpu_T[0], cpu_T[1])
237 #define gen_set_cpsr(var, mask) gen_helper_cpsr_write(var, tcg_const_i32(mask))
238 /* Set NZCV flags from the high 4 bits of var. */
239 #define gen_set_nzcv(var) gen_set_cpsr(var, CPSR_NZCV)
241 static void gen_exception(int excp)
243 TCGv tmp = new_tmp();
244 tcg_gen_movi_i32(tmp, excp);
245 gen_helper_exception(tmp);
249 static void gen_smul_dual(TCGv a, TCGv b)
251 TCGv tmp1 = new_tmp();
252 TCGv tmp2 = new_tmp();
253 tcg_gen_ext8s_i32(tmp1, a);
254 tcg_gen_ext8s_i32(tmp2, b);
255 tcg_gen_mul_i32(tmp1, tmp1, tmp2);
257 tcg_gen_sari_i32(a, a, 16);
258 tcg_gen_sari_i32(b, b, 16);
259 tcg_gen_mul_i32(b, b, a);
260 tcg_gen_mov_i32(a, tmp1);
264 /* Byteswap each halfword. */
265 static void gen_rev16(TCGv var)
267 TCGv tmp = new_tmp();
268 tcg_gen_shri_i32(tmp, var, 8);
269 tcg_gen_andi_i32(tmp, tmp, 0x00ff00ff);
270 tcg_gen_shli_i32(var, var, 8);
271 tcg_gen_andi_i32(var, var, 0xff00ff00);
272 tcg_gen_or_i32(var, var, tmp);
276 /* Byteswap low halfword and sign extend. */
277 static void gen_revsh(TCGv var)
279 TCGv tmp = new_tmp();
280 tcg_gen_shri_i32(tmp, var, 8);
281 tcg_gen_andi_i32(tmp, tmp, 0x00ff);
282 tcg_gen_shli_i32(var, var, 8);
283 tcg_gen_ext8s_i32(var, var);
284 tcg_gen_or_i32(var, var, tmp);
288 /* Unsigned bitfield extract. */
289 static void gen_ubfx(TCGv var, int shift, uint32_t mask)
292 tcg_gen_shri_i32(var, var, shift);
293 tcg_gen_andi_i32(var, var, mask);
296 /* Signed bitfield extract. */
297 static void gen_sbfx(TCGv var, int shift, int width)
302 tcg_gen_sari_i32(var, var, shift);
303 if (shift + width < 32) {
304 signbit = 1u << (width - 1);
305 tcg_gen_andi_i32(var, var, (1u << width) - 1);
306 tcg_gen_xori_i32(var, var, signbit);
307 tcg_gen_subi_i32(var, var, signbit);
311 /* Bitfield insertion. Insert val into base. Clobbers base and val. */
312 static void gen_bfi(TCGv dest, TCGv base, TCGv val, int shift, uint32_t mask)
314 tcg_gen_andi_i32(val, val, mask);
315 tcg_gen_shli_i32(val, val, shift);
316 tcg_gen_andi_i32(base, base, ~(mask << shift));
317 tcg_gen_or_i32(dest, base, val);
320 /* Round the top 32 bits of a 64-bit value. */
321 static void gen_roundqd(TCGv a, TCGv b)
323 tcg_gen_shri_i32(a, a, 31);
324 tcg_gen_add_i32(a, a, b);
327 /* FIXME: Most targets have native widening multiplication.
328 It would be good to use that instead of a full wide multiply. */
329 /* 32x32->64 multiply. Marks inputs as dead. */
330 static TCGv gen_mulu_i64_i32(TCGv a, TCGv b)
332 TCGv tmp1 = tcg_temp_new(TCG_TYPE_I64);
333 TCGv tmp2 = tcg_temp_new(TCG_TYPE_I64);
335 tcg_gen_extu_i32_i64(tmp1, a);
337 tcg_gen_extu_i32_i64(tmp2, b);
339 tcg_gen_mul_i64(tmp1, tmp1, tmp2);
343 static TCGv gen_muls_i64_i32(TCGv a, TCGv b)
345 TCGv tmp1 = tcg_temp_new(TCG_TYPE_I64);
346 TCGv tmp2 = tcg_temp_new(TCG_TYPE_I64);
348 tcg_gen_ext_i32_i64(tmp1, a);
350 tcg_gen_ext_i32_i64(tmp2, b);
352 tcg_gen_mul_i64(tmp1, tmp1, tmp2);
356 /* Unsigned 32x32->64 multiply. */
357 static void gen_op_mull_T0_T1(void)
359 TCGv tmp1 = tcg_temp_new(TCG_TYPE_I64);
360 TCGv tmp2 = tcg_temp_new(TCG_TYPE_I64);
362 tcg_gen_extu_i32_i64(tmp1, cpu_T[0]);
363 tcg_gen_extu_i32_i64(tmp2, cpu_T[1]);
364 tcg_gen_mul_i64(tmp1, tmp1, tmp2);
365 tcg_gen_trunc_i64_i32(cpu_T[0], tmp1);
366 tcg_gen_shri_i64(tmp1, tmp1, 32);
367 tcg_gen_trunc_i64_i32(cpu_T[1], tmp1);
370 /* Signed 32x32->64 multiply. */
371 static void gen_imull(TCGv a, TCGv b)
373 TCGv tmp1 = tcg_temp_new(TCG_TYPE_I64);
374 TCGv tmp2 = tcg_temp_new(TCG_TYPE_I64);
376 tcg_gen_ext_i32_i64(tmp1, a);
377 tcg_gen_ext_i32_i64(tmp2, b);
378 tcg_gen_mul_i64(tmp1, tmp1, tmp2);
379 tcg_gen_trunc_i64_i32(a, tmp1);
380 tcg_gen_shri_i64(tmp1, tmp1, 32);
381 tcg_gen_trunc_i64_i32(b, tmp1);
383 #define gen_op_imull_T0_T1() gen_imull(cpu_T[0], cpu_T[1])
385 /* Swap low and high halfwords. */
386 static void gen_swap_half(TCGv var)
388 TCGv tmp = new_tmp();
389 tcg_gen_shri_i32(tmp, var, 16);
390 tcg_gen_shli_i32(var, var, 16);
391 tcg_gen_or_i32(var, var, tmp);
395 /* Dual 16-bit add. Result placed in t0 and t1 is marked as dead.
396 tmp = (t0 ^ t1) & 0x8000;
399 t0 = (t0 + t1) ^ tmp;
402 static void gen_add16(TCGv t0, TCGv t1)
404 TCGv tmp = new_tmp();
405 tcg_gen_xor_i32(tmp, t0, t1);
406 tcg_gen_andi_i32(tmp, tmp, 0x8000);
407 tcg_gen_andi_i32(t0, t0, ~0x8000);
408 tcg_gen_andi_i32(t1, t1, ~0x8000);
409 tcg_gen_add_i32(t0, t0, t1);
410 tcg_gen_xor_i32(t0, t0, tmp);
415 #define gen_set_CF(var) tcg_gen_st_i32(var, cpu_env, offsetof(CPUState, CF))
417 /* Set CF to the top bit of var. */
418 static void gen_set_CF_bit31(TCGv var)
420 TCGv tmp = new_tmp();
421 tcg_gen_shri_i32(tmp, var, 31);
426 /* Set N and Z flags from var. */
427 static inline void gen_logic_CC(TCGv var)
429 tcg_gen_st_i32(var, cpu_env, offsetof(CPUState, NF));
430 tcg_gen_st_i32(var, cpu_env, offsetof(CPUState, ZF));
434 static void gen_adc_T0_T1(void)
438 tmp = load_cpu_field(CF);
439 tcg_gen_add_i32(cpu_T[0], cpu_T[0], tmp);
443 /* dest = T0 - T1 + CF - 1. */
444 static void gen_sub_carry(TCGv dest, TCGv t0, TCGv t1)
447 tcg_gen_sub_i32(dest, t0, t1);
448 tmp = load_cpu_field(CF);
449 tcg_gen_add_i32(dest, dest, tmp);
450 tcg_gen_subi_i32(dest, dest, 1);
454 #define gen_sbc_T0_T1() gen_sub_carry(cpu_T[0], cpu_T[0], cpu_T[1])
455 #define gen_rsc_T0_T1() gen_sub_carry(cpu_T[0], cpu_T[1], cpu_T[0])
457 /* T0 &= ~T1. Clobbers T1. */
458 /* FIXME: Implement bic natively. */
459 static inline void tcg_gen_bic_i32(TCGv dest, TCGv t0, TCGv t1)
461 TCGv tmp = new_tmp();
462 tcg_gen_not_i32(tmp, t1);
463 tcg_gen_and_i32(dest, t0, tmp);
466 static inline void gen_op_bicl_T0_T1(void)
472 /* FIXME: Implement this natively. */
473 #define tcg_gen_abs_i32(t0, t1) gen_helper_abs(t0, t1)
475 /* FIXME: Implement this natively. */
476 static void tcg_gen_rori_i32(TCGv t0, TCGv t1, int i)
484 tcg_gen_shri_i32(tmp, t1, i);
485 tcg_gen_shli_i32(t1, t1, 32 - i);
486 tcg_gen_or_i32(t0, t1, tmp);
490 static void shifter_out_im(TCGv var, int shift)
492 TCGv tmp = new_tmp();
494 tcg_gen_andi_i32(tmp, var, 1);
496 tcg_gen_shri_i32(tmp, var, shift);
498 tcg_gen_andi_i32(tmp, tmp, 1);
504 /* Shift by immediate. Includes special handling for shift == 0. */
505 static inline void gen_arm_shift_im(TCGv var, int shiftop, int shift, int flags)
511 shifter_out_im(var, 32 - shift);
512 tcg_gen_shli_i32(var, var, shift);
518 tcg_gen_shri_i32(var, var, 31);
521 tcg_gen_movi_i32(var, 0);
524 shifter_out_im(var, shift - 1);
525 tcg_gen_shri_i32(var, var, shift);
532 shifter_out_im(var, shift - 1);
535 tcg_gen_sari_i32(var, var, shift);
537 case 3: /* ROR/RRX */
540 shifter_out_im(var, shift - 1);
541 tcg_gen_rori_i32(var, var, shift); break;
543 TCGv tmp = load_cpu_field(CF);
545 shifter_out_im(var, 0);
546 tcg_gen_shri_i32(var, var, 1);
547 tcg_gen_shli_i32(tmp, tmp, 31);
548 tcg_gen_or_i32(var, var, tmp);
554 static inline void gen_arm_shift_reg(TCGv var, int shiftop,
555 TCGv shift, int flags)
559 case 0: gen_helper_shl_cc(var, var, shift); break;
560 case 1: gen_helper_shr_cc(var, var, shift); break;
561 case 2: gen_helper_sar_cc(var, var, shift); break;
562 case 3: gen_helper_ror_cc(var, var, shift); break;
566 case 0: gen_helper_shl(var, var, shift); break;
567 case 1: gen_helper_shr(var, var, shift); break;
568 case 2: gen_helper_sar(var, var, shift); break;
569 case 3: gen_helper_ror(var, var, shift); break;
575 #define PAS_OP(pfx) \
577 case 0: gen_pas_helper(glue(pfx,add16)); break; \
578 case 1: gen_pas_helper(glue(pfx,addsubx)); break; \
579 case 2: gen_pas_helper(glue(pfx,subaddx)); break; \
580 case 3: gen_pas_helper(glue(pfx,sub16)); break; \
581 case 4: gen_pas_helper(glue(pfx,add8)); break; \
582 case 7: gen_pas_helper(glue(pfx,sub8)); break; \
584 static void gen_arm_parallel_addsub(int op1, int op2, TCGv a, TCGv b)
589 #define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b, tmp)
591 tmp = tcg_temp_new(TCG_TYPE_PTR);
592 tcg_gen_addi_ptr(tmp, cpu_env, offsetof(CPUState, GE));
596 tmp = tcg_temp_new(TCG_TYPE_PTR);
597 tcg_gen_addi_ptr(tmp, cpu_env, offsetof(CPUState, GE));
600 #undef gen_pas_helper
601 #define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b)
614 #undef gen_pas_helper
619 /* For unknown reasons Arm and Thumb-2 use arbitrarily different encodings. */
620 #define PAS_OP(pfx) \
622 case 0: gen_pas_helper(glue(pfx,add8)); break; \
623 case 1: gen_pas_helper(glue(pfx,add16)); break; \
624 case 2: gen_pas_helper(glue(pfx,addsubx)); break; \
625 case 4: gen_pas_helper(glue(pfx,sub8)); break; \
626 case 5: gen_pas_helper(glue(pfx,sub16)); break; \
627 case 6: gen_pas_helper(glue(pfx,subaddx)); break; \
629 static void gen_thumb2_parallel_addsub(int op1, int op2, TCGv a, TCGv b)
634 #define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b, tmp)
636 tmp = tcg_temp_new(TCG_TYPE_PTR);
637 tcg_gen_addi_ptr(tmp, cpu_env, offsetof(CPUState, GE));
641 tmp = tcg_temp_new(TCG_TYPE_PTR);
642 tcg_gen_addi_ptr(tmp, cpu_env, offsetof(CPUState, GE));
645 #undef gen_pas_helper
646 #define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b)
659 #undef gen_pas_helper
664 static void gen_test_cc(int cc, int label)
672 tmp = load_cpu_field(ZF);
673 tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 0, label);
676 tmp = load_cpu_field(ZF);
677 tcg_gen_brcondi_i32(TCG_COND_NE, tmp, 0, label);
680 tmp = load_cpu_field(CF);
681 tcg_gen_brcondi_i32(TCG_COND_NE, tmp, 0, label);
684 tmp = load_cpu_field(CF);
685 tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 0, label);
688 tmp = load_cpu_field(NF);
689 tcg_gen_brcondi_i32(TCG_COND_LT, tmp, 0, label);
692 tmp = load_cpu_field(NF);
693 tcg_gen_brcondi_i32(TCG_COND_GE, tmp, 0, label);
696 tmp = load_cpu_field(VF);
697 tcg_gen_brcondi_i32(TCG_COND_LT, tmp, 0, label);
700 tmp = load_cpu_field(VF);
701 tcg_gen_brcondi_i32(TCG_COND_GE, tmp, 0, label);
703 case 8: /* hi: C && !Z */
704 inv = gen_new_label();
705 tmp = load_cpu_field(CF);
706 tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 0, inv);
708 tmp = load_cpu_field(ZF);
709 tcg_gen_brcondi_i32(TCG_COND_NE, tmp, 0, label);
712 case 9: /* ls: !C || Z */
713 tmp = load_cpu_field(CF);
714 tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 0, label);
716 tmp = load_cpu_field(ZF);
717 tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 0, label);
719 case 10: /* ge: N == V -> N ^ V == 0 */
720 tmp = load_cpu_field(VF);
721 tmp2 = load_cpu_field(NF);
722 tcg_gen_xor_i32(tmp, tmp, tmp2);
724 tcg_gen_brcondi_i32(TCG_COND_GE, tmp, 0, label);
726 case 11: /* lt: N != V -> N ^ V != 0 */
727 tmp = load_cpu_field(VF);
728 tmp2 = load_cpu_field(NF);
729 tcg_gen_xor_i32(tmp, tmp, tmp2);
731 tcg_gen_brcondi_i32(TCG_COND_LT, tmp, 0, label);
733 case 12: /* gt: !Z && N == V */
734 inv = gen_new_label();
735 tmp = load_cpu_field(ZF);
736 tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 0, inv);
738 tmp = load_cpu_field(VF);
739 tmp2 = load_cpu_field(NF);
740 tcg_gen_xor_i32(tmp, tmp, tmp2);
742 tcg_gen_brcondi_i32(TCG_COND_GE, tmp, 0, label);
745 case 13: /* le: Z || N != V */
746 tmp = load_cpu_field(ZF);
747 tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 0, label);
749 tmp = load_cpu_field(VF);
750 tmp2 = load_cpu_field(NF);
751 tcg_gen_xor_i32(tmp, tmp, tmp2);
753 tcg_gen_brcondi_i32(TCG_COND_LT, tmp, 0, label);
756 fprintf(stderr, "Bad condition code 0x%x\n", cc);
762 const uint8_t table_logic_cc[16] = {
781 /* Set PC and Thumb state from an immediate address. */
782 static inline void gen_bx_im(DisasContext *s, uint32_t addr)
786 s->is_jmp = DISAS_UPDATE;
788 if (s->thumb != (addr & 1)) {
789 tcg_gen_movi_i32(tmp, addr & 1);
790 tcg_gen_st_i32(tmp, cpu_env, offsetof(CPUState, thumb));
792 tcg_gen_movi_i32(tmp, addr & ~1);
793 tcg_gen_st_i32(tmp, cpu_env, offsetof(CPUState, regs[15]));
797 /* Set PC and Thumb state from var. var is marked as dead. */
798 static inline void gen_bx(DisasContext *s, TCGv var)
802 s->is_jmp = DISAS_UPDATE;
804 tcg_gen_andi_i32(tmp, var, 1);
805 store_cpu_field(tmp, thumb);
806 tcg_gen_andi_i32(var, var, ~1);
807 store_cpu_field(var, regs[15]);
810 /* TODO: This should be removed. Use gen_bx instead. */
811 static inline void gen_bx_T0(DisasContext *s)
813 TCGv tmp = new_tmp();
814 tcg_gen_mov_i32(tmp, cpu_T[0]);
818 #if defined(CONFIG_USER_ONLY)
819 #define gen_ldst(name, s) gen_op_##name##_raw()
821 #define gen_ldst(name, s) do { \
824 gen_op_##name##_user(); \
826 gen_op_##name##_kernel(); \
829 static inline TCGv gen_ld8s(TCGv addr, int index)
831 TCGv tmp = new_tmp();
832 tcg_gen_qemu_ld8s(tmp, addr, index);
835 static inline TCGv gen_ld8u(TCGv addr, int index)
837 TCGv tmp = new_tmp();
838 tcg_gen_qemu_ld8u(tmp, addr, index);
841 static inline TCGv gen_ld16s(TCGv addr, int index)
843 TCGv tmp = new_tmp();
844 tcg_gen_qemu_ld16s(tmp, addr, index);
847 static inline TCGv gen_ld16u(TCGv addr, int index)
849 TCGv tmp = new_tmp();
850 tcg_gen_qemu_ld16u(tmp, addr, index);
853 static inline TCGv gen_ld32(TCGv addr, int index)
855 TCGv tmp = new_tmp();
856 tcg_gen_qemu_ld32u(tmp, addr, index);
859 static inline void gen_st8(TCGv val, TCGv addr, int index)
861 tcg_gen_qemu_st8(val, addr, index);
864 static inline void gen_st16(TCGv val, TCGv addr, int index)
866 tcg_gen_qemu_st16(val, addr, index);
869 static inline void gen_st32(TCGv val, TCGv addr, int index)
871 tcg_gen_qemu_st32(val, addr, index);
875 static inline void gen_movl_T0_reg(DisasContext *s, int reg)
877 load_reg_var(s, cpu_T[0], reg);
880 static inline void gen_movl_T1_reg(DisasContext *s, int reg)
882 load_reg_var(s, cpu_T[1], reg);
885 static inline void gen_movl_T2_reg(DisasContext *s, int reg)
887 load_reg_var(s, cpu_T[2], reg);
890 static inline void gen_set_pc_im(uint32_t val)
892 TCGv tmp = new_tmp();
893 tcg_gen_movi_i32(tmp, val);
894 store_cpu_field(tmp, regs[15]);
897 static inline void gen_movl_reg_TN(DisasContext *s, int reg, int t)
902 tcg_gen_andi_i32(tmp, cpu_T[t], ~1);
906 tcg_gen_st_i32(tmp, cpu_env, offsetof(CPUState, regs[reg]));
909 s->is_jmp = DISAS_JUMP;
913 static inline void gen_movl_reg_T0(DisasContext *s, int reg)
915 gen_movl_reg_TN(s, reg, 0);
918 static inline void gen_movl_reg_T1(DisasContext *s, int reg)
920 gen_movl_reg_TN(s, reg, 1);
923 /* Force a TB lookup after an instruction that changes the CPU state. */
924 static inline void gen_lookup_tb(DisasContext *s)
926 gen_op_movl_T0_im(s->pc);
927 gen_movl_reg_T0(s, 15);
928 s->is_jmp = DISAS_UPDATE;
931 static inline void gen_add_data_offset(DisasContext *s, unsigned int insn,
934 int val, rm, shift, shiftop;
937 if (!(insn & (1 << 25))) {
940 if (!(insn & (1 << 23)))
943 tcg_gen_addi_i32(var, var, val);
947 shift = (insn >> 7) & 0x1f;
948 shiftop = (insn >> 5) & 3;
949 offset = load_reg(s, rm);
950 gen_arm_shift_im(offset, shiftop, shift, 0);
951 if (!(insn & (1 << 23)))
952 tcg_gen_sub_i32(var, var, offset);
954 tcg_gen_add_i32(var, var, offset);
959 static inline void gen_add_datah_offset(DisasContext *s, unsigned int insn,
965 if (insn & (1 << 22)) {
967 val = (insn & 0xf) | ((insn >> 4) & 0xf0);
968 if (!(insn & (1 << 23)))
972 tcg_gen_addi_i32(var, var, val);
976 tcg_gen_addi_i32(var, var, extra);
978 offset = load_reg(s, rm);
979 if (!(insn & (1 << 23)))
980 tcg_gen_sub_i32(var, var, offset);
982 tcg_gen_add_i32(var, var, offset);
987 #define VFP_OP2(name) \
988 static inline void gen_vfp_##name(int dp) \
991 gen_helper_vfp_##name##d(cpu_F0d, cpu_F0d, cpu_F1d, cpu_env); \
993 gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, cpu_F1s, cpu_env); \
996 #define VFP_OP1(name) \
997 static inline void gen_vfp_##name(int dp, int arg) \
1000 gen_op_vfp_##name##d(arg); \
1002 gen_op_vfp_##name##s(arg); \
1012 static inline void gen_vfp_abs(int dp)
1015 gen_helper_vfp_absd(cpu_F0d, cpu_F0d);
1017 gen_helper_vfp_abss(cpu_F0s, cpu_F0s);
1020 static inline void gen_vfp_neg(int dp)
1023 gen_helper_vfp_negd(cpu_F0d, cpu_F0d);
1025 gen_helper_vfp_negs(cpu_F0s, cpu_F0s);
1028 static inline void gen_vfp_sqrt(int dp)
1031 gen_helper_vfp_sqrtd(cpu_F0d, cpu_F0d, cpu_env);
1033 gen_helper_vfp_sqrts(cpu_F0s, cpu_F0s, cpu_env);
1036 static inline void gen_vfp_cmp(int dp)
1039 gen_helper_vfp_cmpd(cpu_F0d, cpu_F1d, cpu_env);
1041 gen_helper_vfp_cmps(cpu_F0s, cpu_F1s, cpu_env);
1044 static inline void gen_vfp_cmpe(int dp)
1047 gen_helper_vfp_cmped(cpu_F0d, cpu_F1d, cpu_env);
1049 gen_helper_vfp_cmpes(cpu_F0s, cpu_F1s, cpu_env);
1052 static inline void gen_vfp_F1_ld0(int dp)
1055 tcg_gen_movi_i64(cpu_F1d, 0);
1057 tcg_gen_movi_i32(cpu_F1s, 0);
1060 static inline void gen_vfp_uito(int dp)
1063 gen_helper_vfp_uitod(cpu_F0d, cpu_F0s, cpu_env);
1065 gen_helper_vfp_uitos(cpu_F0s, cpu_F0s, cpu_env);
1068 static inline void gen_vfp_sito(int dp)
1071 gen_helper_vfp_sitod(cpu_F0d, cpu_F0s, cpu_env);
1073 gen_helper_vfp_sitos(cpu_F0s, cpu_F0s, cpu_env);
1076 static inline void gen_vfp_toui(int dp)
1079 gen_helper_vfp_touid(cpu_F0s, cpu_F0d, cpu_env);
1081 gen_helper_vfp_touis(cpu_F0s, cpu_F0s, cpu_env);
1084 static inline void gen_vfp_touiz(int dp)
1087 gen_helper_vfp_touizd(cpu_F0s, cpu_F0d, cpu_env);
1089 gen_helper_vfp_touizs(cpu_F0s, cpu_F0s, cpu_env);
1092 static inline void gen_vfp_tosi(int dp)
1095 gen_helper_vfp_tosid(cpu_F0s, cpu_F0d, cpu_env);
1097 gen_helper_vfp_tosis(cpu_F0s, cpu_F0s, cpu_env);
1100 static inline void gen_vfp_tosiz(int dp)
1103 gen_helper_vfp_tosizd(cpu_F0s, cpu_F0d, cpu_env);
1105 gen_helper_vfp_tosizs(cpu_F0s, cpu_F0s, cpu_env);
1108 #define VFP_GEN_FIX(name) \
1109 static inline void gen_vfp_##name(int dp, int shift) \
1112 gen_helper_vfp_##name##d(cpu_F0d, cpu_F0d, tcg_const_i32(shift), cpu_env);\
1114 gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, tcg_const_i32(shift), cpu_env);\
1126 static inline void gen_vfp_ld(DisasContext *s, int dp)
1129 tcg_gen_qemu_ld64(cpu_F0d, cpu_T[1], IS_USER(s));
1131 tcg_gen_qemu_ld32u(cpu_F0s, cpu_T[1], IS_USER(s));
1134 static inline void gen_vfp_st(DisasContext *s, int dp)
1137 tcg_gen_qemu_st64(cpu_F0d, cpu_T[1], IS_USER(s));
1139 tcg_gen_qemu_st32(cpu_F0s, cpu_T[1], IS_USER(s));
1143 vfp_reg_offset (int dp, int reg)
1146 return offsetof(CPUARMState, vfp.regs[reg]);
1148 return offsetof(CPUARMState, vfp.regs[reg >> 1])
1149 + offsetof(CPU_DoubleU, l.upper);
1151 return offsetof(CPUARMState, vfp.regs[reg >> 1])
1152 + offsetof(CPU_DoubleU, l.lower);
1156 /* Return the offset of a 32-bit piece of a NEON register.
1157 zero is the least significant end of the register. */
1159 neon_reg_offset (int reg, int n)
1163 return vfp_reg_offset(0, sreg);
1166 /* FIXME: Remove these. */
1167 #define neon_T0 cpu_T[0]
1168 #define neon_T1 cpu_T[1]
1169 #define NEON_GET_REG(T, reg, n) \
1170 tcg_gen_ld_i32(neon_##T, cpu_env, neon_reg_offset(reg, n))
1171 #define NEON_SET_REG(T, reg, n) \
1172 tcg_gen_st_i32(neon_##T, cpu_env, neon_reg_offset(reg, n))
1174 static TCGv neon_load_reg(int reg, int pass)
1176 TCGv tmp = new_tmp();
1177 tcg_gen_ld_i32(tmp, cpu_env, neon_reg_offset(reg, pass));
1181 static void neon_store_reg(int reg, int pass, TCGv var)
1183 tcg_gen_st_i32(var, cpu_env, neon_reg_offset(reg, pass));
1187 static inline void neon_load_reg64(TCGv var, int reg)
1189 tcg_gen_ld_i64(var, cpu_env, vfp_reg_offset(1, reg));
1192 static inline void neon_store_reg64(TCGv var, int reg)
1194 tcg_gen_st_i64(var, cpu_env, vfp_reg_offset(1, reg));
1197 #define tcg_gen_ld_f32 tcg_gen_ld_i32
1198 #define tcg_gen_ld_f64 tcg_gen_ld_i64
1199 #define tcg_gen_st_f32 tcg_gen_st_i32
1200 #define tcg_gen_st_f64 tcg_gen_st_i64
1202 static inline void gen_mov_F0_vreg(int dp, int reg)
1205 tcg_gen_ld_f64(cpu_F0d, cpu_env, vfp_reg_offset(dp, reg));
1207 tcg_gen_ld_f32(cpu_F0s, cpu_env, vfp_reg_offset(dp, reg));
1210 static inline void gen_mov_F1_vreg(int dp, int reg)
1213 tcg_gen_ld_f64(cpu_F1d, cpu_env, vfp_reg_offset(dp, reg));
1215 tcg_gen_ld_f32(cpu_F1s, cpu_env, vfp_reg_offset(dp, reg));
1218 static inline void gen_mov_vreg_F0(int dp, int reg)
1221 tcg_gen_st_f64(cpu_F0d, cpu_env, vfp_reg_offset(dp, reg));
1223 tcg_gen_st_f32(cpu_F0s, cpu_env, vfp_reg_offset(dp, reg));
1226 #define ARM_CP_RW_BIT (1 << 20)
1228 static inline void iwmmxt_load_reg(TCGv var, int reg)
1230 tcg_gen_ld_i64(var, cpu_env, offsetof(CPUState, iwmmxt.regs[reg]));
1233 static inline void iwmmxt_store_reg(TCGv var, int reg)
1235 tcg_gen_st_i64(var, cpu_env, offsetof(CPUState, iwmmxt.regs[reg]));
1238 static inline void gen_op_iwmmxt_movl_wCx_T0(int reg)
1240 tcg_gen_st_i32(cpu_T[0], cpu_env, offsetof(CPUState, iwmmxt.cregs[reg]));
1243 static inline void gen_op_iwmmxt_movl_T0_wCx(int reg)
1245 tcg_gen_ld_i32(cpu_T[0], cpu_env, offsetof(CPUState, iwmmxt.cregs[reg]));
1248 static inline void gen_op_iwmmxt_movl_T1_wCx(int reg)
1250 tcg_gen_ld_i32(cpu_T[1], cpu_env, offsetof(CPUState, iwmmxt.cregs[reg]));
1253 static inline void gen_op_iwmmxt_movq_wRn_M0(int rn)
1255 iwmmxt_store_reg(cpu_M0, rn);
1258 static inline void gen_op_iwmmxt_movq_M0_wRn(int rn)
1260 iwmmxt_load_reg(cpu_M0, rn);
1263 static inline void gen_op_iwmmxt_orq_M0_wRn(int rn)
1265 iwmmxt_load_reg(cpu_V1, rn);
1266 tcg_gen_or_i64(cpu_M0, cpu_M0, cpu_V1);
1269 static inline void gen_op_iwmmxt_andq_M0_wRn(int rn)
1271 iwmmxt_load_reg(cpu_V1, rn);
1272 tcg_gen_and_i64(cpu_M0, cpu_M0, cpu_V1);
1275 static inline void gen_op_iwmmxt_xorq_M0_wRn(int rn)
1277 iwmmxt_load_reg(cpu_V1, rn);
1278 tcg_gen_xor_i64(cpu_M0, cpu_M0, cpu_V1);
1281 #define IWMMXT_OP(name) \
1282 static inline void gen_op_iwmmxt_##name##_M0_wRn(int rn) \
1284 iwmmxt_load_reg(cpu_V1, rn); \
1285 gen_helper_iwmmxt_##name(cpu_M0, cpu_M0, cpu_V1); \
1288 #define IWMMXT_OP_ENV(name) \
1289 static inline void gen_op_iwmmxt_##name##_M0_wRn(int rn) \
1291 iwmmxt_load_reg(cpu_V1, rn); \
1292 gen_helper_iwmmxt_##name(cpu_M0, cpu_env, cpu_M0, cpu_V1); \
1295 #define IWMMXT_OP_ENV_SIZE(name) \
1296 IWMMXT_OP_ENV(name##b) \
1297 IWMMXT_OP_ENV(name##w) \
1298 IWMMXT_OP_ENV(name##l)
1300 #define IWMMXT_OP_ENV1(name) \
1301 static inline void gen_op_iwmmxt_##name##_M0(void) \
1303 gen_helper_iwmmxt_##name(cpu_M0, cpu_env, cpu_M0); \
1317 IWMMXT_OP_ENV_SIZE(unpackl)
1318 IWMMXT_OP_ENV_SIZE(unpackh)
1320 IWMMXT_OP_ENV1(unpacklub)
1321 IWMMXT_OP_ENV1(unpackluw)
1322 IWMMXT_OP_ENV1(unpacklul)
1323 IWMMXT_OP_ENV1(unpackhub)
1324 IWMMXT_OP_ENV1(unpackhuw)
1325 IWMMXT_OP_ENV1(unpackhul)
1326 IWMMXT_OP_ENV1(unpacklsb)
1327 IWMMXT_OP_ENV1(unpacklsw)
1328 IWMMXT_OP_ENV1(unpacklsl)
1329 IWMMXT_OP_ENV1(unpackhsb)
1330 IWMMXT_OP_ENV1(unpackhsw)
1331 IWMMXT_OP_ENV1(unpackhsl)
1333 IWMMXT_OP_ENV_SIZE(cmpeq)
1334 IWMMXT_OP_ENV_SIZE(cmpgtu)
1335 IWMMXT_OP_ENV_SIZE(cmpgts)
1337 IWMMXT_OP_ENV_SIZE(mins)
1338 IWMMXT_OP_ENV_SIZE(minu)
1339 IWMMXT_OP_ENV_SIZE(maxs)
1340 IWMMXT_OP_ENV_SIZE(maxu)
1342 IWMMXT_OP_ENV_SIZE(subn)
1343 IWMMXT_OP_ENV_SIZE(addn)
1344 IWMMXT_OP_ENV_SIZE(subu)
1345 IWMMXT_OP_ENV_SIZE(addu)
1346 IWMMXT_OP_ENV_SIZE(subs)
1347 IWMMXT_OP_ENV_SIZE(adds)
1349 IWMMXT_OP_ENV(avgb0)
1350 IWMMXT_OP_ENV(avgb1)
1351 IWMMXT_OP_ENV(avgw0)
1352 IWMMXT_OP_ENV(avgw1)
1356 IWMMXT_OP_ENV(packuw)
1357 IWMMXT_OP_ENV(packul)
1358 IWMMXT_OP_ENV(packuq)
1359 IWMMXT_OP_ENV(packsw)
1360 IWMMXT_OP_ENV(packsl)
1361 IWMMXT_OP_ENV(packsq)
1363 static inline void gen_op_iwmmxt_muladdsl_M0_T0_T1(void)
1365 gen_helper_iwmmxt_muladdsl(cpu_M0, cpu_M0, cpu_T[0], cpu_T[1]);
1368 static inline void gen_op_iwmmxt_muladdsw_M0_T0_T1(void)
1370 gen_helper_iwmmxt_muladdsw(cpu_M0, cpu_M0, cpu_T[0], cpu_T[1]);
1373 static inline void gen_op_iwmmxt_muladdswl_M0_T0_T1(void)
1375 gen_helper_iwmmxt_muladdswl(cpu_M0, cpu_M0, cpu_T[0], cpu_T[1]);
1378 static inline void gen_op_iwmmxt_align_M0_T0_wRn(int rn)
1380 iwmmxt_load_reg(cpu_V1, rn);
1381 gen_helper_iwmmxt_align(cpu_M0, cpu_M0, cpu_V1, cpu_T[0]);
1384 static inline void gen_op_iwmmxt_insr_M0_T0_T1(int shift)
1386 TCGv tmp = tcg_const_i32(shift);
1387 gen_helper_iwmmxt_insr(cpu_M0, cpu_M0, cpu_T[0], cpu_T[1], tmp);
1390 static inline void gen_op_iwmmxt_extrsb_T0_M0(int shift)
1392 tcg_gen_shri_i64(cpu_M0, cpu_M0, shift);
1393 tcg_gen_trunc_i64_i32(cpu_T[0], cpu_M0);
1394 tcg_gen_ext8s_i32(cpu_T[0], cpu_T[0]);
1397 static inline void gen_op_iwmmxt_extrsw_T0_M0(int shift)
1399 tcg_gen_shri_i64(cpu_M0, cpu_M0, shift);
1400 tcg_gen_trunc_i64_i32(cpu_T[0], cpu_M0);
1401 tcg_gen_ext16s_i32(cpu_T[0], cpu_T[0]);
1404 static inline void gen_op_iwmmxt_extru_T0_M0(int shift, uint32_t mask)
1406 tcg_gen_shri_i64(cpu_M0, cpu_M0, shift);
1407 tcg_gen_trunc_i64_i32(cpu_T[0], cpu_M0);
1409 tcg_gen_andi_i32(cpu_T[0], cpu_T[0], mask);
1412 static void gen_op_iwmmxt_set_mup(void)
1415 tmp = load_cpu_field(iwmmxt.cregs[ARM_IWMMXT_wCon]);
1416 tcg_gen_ori_i32(tmp, tmp, 2);
1417 store_cpu_field(tmp, iwmmxt.cregs[ARM_IWMMXT_wCon]);
1420 static void gen_op_iwmmxt_set_cup(void)
1423 tmp = load_cpu_field(iwmmxt.cregs[ARM_IWMMXT_wCon]);
1424 tcg_gen_ori_i32(tmp, tmp, 1);
1425 store_cpu_field(tmp, iwmmxt.cregs[ARM_IWMMXT_wCon]);
1428 static void gen_op_iwmmxt_setpsr_nz(void)
1430 TCGv tmp = new_tmp();
1431 gen_helper_iwmmxt_setpsr_nz(tmp, cpu_M0);
1432 store_cpu_field(tmp, iwmmxt.cregs[ARM_IWMMXT_wCASF]);
1435 static inline void gen_op_iwmmxt_addl_M0_wRn(int rn)
1437 iwmmxt_load_reg(cpu_V1, rn);
1438 tcg_gen_ext32u_i64(cpu_V1, cpu_V1);
1439 tcg_gen_add_i64(cpu_M0, cpu_M0, cpu_V1);
1443 static void gen_iwmmxt_movl_T0_T1_wRn(int rn)
1445 iwmmxt_load_reg(cpu_V0, rn);
1446 tcg_gen_trunc_i64_i32(cpu_T[0], cpu_V0);
1447 tcg_gen_shri_i64(cpu_V0, cpu_V0, 32);
1448 tcg_gen_trunc_i64_i32(cpu_T[1], cpu_V0);
1451 static void gen_iwmmxt_movl_wRn_T0_T1(int rn)
1453 tcg_gen_extu_i32_i64(cpu_V0, cpu_T[0]);
1454 tcg_gen_extu_i32_i64(cpu_V1, cpu_T[0]);
1455 tcg_gen_shli_i64(cpu_V1, cpu_V1, 32);
1456 tcg_gen_or_i64(cpu_V0, cpu_V0, cpu_V1);
1457 iwmmxt_store_reg(cpu_V0, rn);
1460 static inline int gen_iwmmxt_address(DisasContext *s, uint32_t insn)
1465 rd = (insn >> 16) & 0xf;
1466 gen_movl_T1_reg(s, rd);
1468 offset = (insn & 0xff) << ((insn >> 7) & 2);
1469 if (insn & (1 << 24)) {
1471 if (insn & (1 << 23))
1472 gen_op_addl_T1_im(offset);
1474 gen_op_addl_T1_im(-offset);
1476 if (insn & (1 << 21))
1477 gen_movl_reg_T1(s, rd);
1478 } else if (insn & (1 << 21)) {
1480 if (insn & (1 << 23))
1481 gen_op_movl_T0_im(offset);
1483 gen_op_movl_T0_im(- offset);
1484 gen_op_addl_T0_T1();
1485 gen_movl_reg_T0(s, rd);
1486 } else if (!(insn & (1 << 23)))
1491 static inline int gen_iwmmxt_shift(uint32_t insn, uint32_t mask)
1493 int rd = (insn >> 0) & 0xf;
1495 if (insn & (1 << 8))
1496 if (rd < ARM_IWMMXT_wCGR0 || rd > ARM_IWMMXT_wCGR3)
1499 gen_op_iwmmxt_movl_T0_wCx(rd);
1501 gen_iwmmxt_movl_T0_T1_wRn(rd);
1503 gen_op_movl_T1_im(mask);
1504 gen_op_andl_T0_T1();
1508 /* Disassemble an iwMMXt instruction. Returns nonzero if an error occured
1509 (ie. an undefined instruction). */
1510 static int disas_iwmmxt_insn(CPUState *env, DisasContext *s, uint32_t insn)
1513 int rdhi, rdlo, rd0, rd1, i;
1516 if ((insn & 0x0e000e00) == 0x0c000000) {
1517 if ((insn & 0x0fe00ff0) == 0x0c400000) {
1519 rdlo = (insn >> 12) & 0xf;
1520 rdhi = (insn >> 16) & 0xf;
1521 if (insn & ARM_CP_RW_BIT) { /* TMRRC */
1522 gen_iwmmxt_movl_T0_T1_wRn(wrd);
1523 gen_movl_reg_T0(s, rdlo);
1524 gen_movl_reg_T1(s, rdhi);
1525 } else { /* TMCRR */
1526 gen_movl_T0_reg(s, rdlo);
1527 gen_movl_T1_reg(s, rdhi);
1528 gen_iwmmxt_movl_wRn_T0_T1(wrd);
1529 gen_op_iwmmxt_set_mup();
1534 wrd = (insn >> 12) & 0xf;
1535 if (gen_iwmmxt_address(s, insn))
1537 if (insn & ARM_CP_RW_BIT) {
1538 if ((insn >> 28) == 0xf) { /* WLDRW wCx */
1539 tmp = gen_ld32(cpu_T[1], IS_USER(s));
1540 tcg_gen_mov_i32(cpu_T[0], tmp);
1542 gen_op_iwmmxt_movl_wCx_T0(wrd);
1545 if (insn & (1 << 8)) {
1546 if (insn & (1 << 22)) { /* WLDRD */
1547 tcg_gen_qemu_ld64(cpu_M0, cpu_T[1], IS_USER(s));
1549 } else { /* WLDRW wRd */
1550 tmp = gen_ld32(cpu_T[1], IS_USER(s));
1553 if (insn & (1 << 22)) { /* WLDRH */
1554 tmp = gen_ld16u(cpu_T[1], IS_USER(s));
1555 } else { /* WLDRB */
1556 tmp = gen_ld8u(cpu_T[1], IS_USER(s));
1560 tcg_gen_extu_i32_i64(cpu_M0, tmp);
1563 gen_op_iwmmxt_movq_wRn_M0(wrd);
1566 if ((insn >> 28) == 0xf) { /* WSTRW wCx */
1567 gen_op_iwmmxt_movl_T0_wCx(wrd);
1569 tcg_gen_mov_i32(tmp, cpu_T[0]);
1570 gen_st32(tmp, cpu_T[1], IS_USER(s));
1572 gen_op_iwmmxt_movq_M0_wRn(wrd);
1574 if (insn & (1 << 8)) {
1575 if (insn & (1 << 22)) { /* WSTRD */
1577 tcg_gen_qemu_st64(cpu_M0, cpu_T[1], IS_USER(s));
1578 } else { /* WSTRW wRd */
1579 tcg_gen_trunc_i64_i32(tmp, cpu_M0);
1580 gen_st32(tmp, cpu_T[1], IS_USER(s));
1583 if (insn & (1 << 22)) { /* WSTRH */
1584 tcg_gen_trunc_i64_i32(tmp, cpu_M0);
1585 gen_st16(tmp, cpu_T[1], IS_USER(s));
1586 } else { /* WSTRB */
1587 tcg_gen_trunc_i64_i32(tmp, cpu_M0);
1588 gen_st8(tmp, cpu_T[1], IS_USER(s));
1596 if ((insn & 0x0f000000) != 0x0e000000)
1599 switch (((insn >> 12) & 0xf00) | ((insn >> 4) & 0xff)) {
1600 case 0x000: /* WOR */
1601 wrd = (insn >> 12) & 0xf;
1602 rd0 = (insn >> 0) & 0xf;
1603 rd1 = (insn >> 16) & 0xf;
1604 gen_op_iwmmxt_movq_M0_wRn(rd0);
1605 gen_op_iwmmxt_orq_M0_wRn(rd1);
1606 gen_op_iwmmxt_setpsr_nz();
1607 gen_op_iwmmxt_movq_wRn_M0(wrd);
1608 gen_op_iwmmxt_set_mup();
1609 gen_op_iwmmxt_set_cup();
1611 case 0x011: /* TMCR */
1614 rd = (insn >> 12) & 0xf;
1615 wrd = (insn >> 16) & 0xf;
1617 case ARM_IWMMXT_wCID:
1618 case ARM_IWMMXT_wCASF:
1620 case ARM_IWMMXT_wCon:
1621 gen_op_iwmmxt_set_cup();
1623 case ARM_IWMMXT_wCSSF:
1624 gen_op_iwmmxt_movl_T0_wCx(wrd);
1625 gen_movl_T1_reg(s, rd);
1626 gen_op_bicl_T0_T1();
1627 gen_op_iwmmxt_movl_wCx_T0(wrd);
1629 case ARM_IWMMXT_wCGR0:
1630 case ARM_IWMMXT_wCGR1:
1631 case ARM_IWMMXT_wCGR2:
1632 case ARM_IWMMXT_wCGR3:
1633 gen_op_iwmmxt_set_cup();
1634 gen_movl_reg_T0(s, rd);
1635 gen_op_iwmmxt_movl_wCx_T0(wrd);
1641 case 0x100: /* WXOR */
1642 wrd = (insn >> 12) & 0xf;
1643 rd0 = (insn >> 0) & 0xf;
1644 rd1 = (insn >> 16) & 0xf;
1645 gen_op_iwmmxt_movq_M0_wRn(rd0);
1646 gen_op_iwmmxt_xorq_M0_wRn(rd1);
1647 gen_op_iwmmxt_setpsr_nz();
1648 gen_op_iwmmxt_movq_wRn_M0(wrd);
1649 gen_op_iwmmxt_set_mup();
1650 gen_op_iwmmxt_set_cup();
1652 case 0x111: /* TMRC */
1655 rd = (insn >> 12) & 0xf;
1656 wrd = (insn >> 16) & 0xf;
1657 gen_op_iwmmxt_movl_T0_wCx(wrd);
1658 gen_movl_reg_T0(s, rd);
1660 case 0x300: /* WANDN */
1661 wrd = (insn >> 12) & 0xf;
1662 rd0 = (insn >> 0) & 0xf;
1663 rd1 = (insn >> 16) & 0xf;
1664 gen_op_iwmmxt_movq_M0_wRn(rd0);
1665 tcg_gen_neg_i64(cpu_M0, cpu_M0);
1666 gen_op_iwmmxt_andq_M0_wRn(rd1);
1667 gen_op_iwmmxt_setpsr_nz();
1668 gen_op_iwmmxt_movq_wRn_M0(wrd);
1669 gen_op_iwmmxt_set_mup();
1670 gen_op_iwmmxt_set_cup();
1672 case 0x200: /* WAND */
1673 wrd = (insn >> 12) & 0xf;
1674 rd0 = (insn >> 0) & 0xf;
1675 rd1 = (insn >> 16) & 0xf;
1676 gen_op_iwmmxt_movq_M0_wRn(rd0);
1677 gen_op_iwmmxt_andq_M0_wRn(rd1);
1678 gen_op_iwmmxt_setpsr_nz();
1679 gen_op_iwmmxt_movq_wRn_M0(wrd);
1680 gen_op_iwmmxt_set_mup();
1681 gen_op_iwmmxt_set_cup();
1683 case 0x810: case 0xa10: /* WMADD */
1684 wrd = (insn >> 12) & 0xf;
1685 rd0 = (insn >> 0) & 0xf;
1686 rd1 = (insn >> 16) & 0xf;
1687 gen_op_iwmmxt_movq_M0_wRn(rd0);
1688 if (insn & (1 << 21))
1689 gen_op_iwmmxt_maddsq_M0_wRn(rd1);
1691 gen_op_iwmmxt_madduq_M0_wRn(rd1);
1692 gen_op_iwmmxt_movq_wRn_M0(wrd);
1693 gen_op_iwmmxt_set_mup();
1695 case 0x10e: case 0x50e: case 0x90e: case 0xd0e: /* WUNPCKIL */
1696 wrd = (insn >> 12) & 0xf;
1697 rd0 = (insn >> 16) & 0xf;
1698 rd1 = (insn >> 0) & 0xf;
1699 gen_op_iwmmxt_movq_M0_wRn(rd0);
1700 switch ((insn >> 22) & 3) {
1702 gen_op_iwmmxt_unpacklb_M0_wRn(rd1);
1705 gen_op_iwmmxt_unpacklw_M0_wRn(rd1);
1708 gen_op_iwmmxt_unpackll_M0_wRn(rd1);
1713 gen_op_iwmmxt_movq_wRn_M0(wrd);
1714 gen_op_iwmmxt_set_mup();
1715 gen_op_iwmmxt_set_cup();
1717 case 0x10c: case 0x50c: case 0x90c: case 0xd0c: /* WUNPCKIH */
1718 wrd = (insn >> 12) & 0xf;
1719 rd0 = (insn >> 16) & 0xf;
1720 rd1 = (insn >> 0) & 0xf;
1721 gen_op_iwmmxt_movq_M0_wRn(rd0);
1722 switch ((insn >> 22) & 3) {
1724 gen_op_iwmmxt_unpackhb_M0_wRn(rd1);
1727 gen_op_iwmmxt_unpackhw_M0_wRn(rd1);
1730 gen_op_iwmmxt_unpackhl_M0_wRn(rd1);
1735 gen_op_iwmmxt_movq_wRn_M0(wrd);
1736 gen_op_iwmmxt_set_mup();
1737 gen_op_iwmmxt_set_cup();
1739 case 0x012: case 0x112: case 0x412: case 0x512: /* WSAD */
1740 wrd = (insn >> 12) & 0xf;
1741 rd0 = (insn >> 16) & 0xf;
1742 rd1 = (insn >> 0) & 0xf;
1743 gen_op_iwmmxt_movq_M0_wRn(rd0);
1744 if (insn & (1 << 22))
1745 gen_op_iwmmxt_sadw_M0_wRn(rd1);
1747 gen_op_iwmmxt_sadb_M0_wRn(rd1);
1748 if (!(insn & (1 << 20)))
1749 gen_op_iwmmxt_addl_M0_wRn(wrd);
1750 gen_op_iwmmxt_movq_wRn_M0(wrd);
1751 gen_op_iwmmxt_set_mup();
1753 case 0x010: case 0x110: case 0x210: case 0x310: /* WMUL */
1754 wrd = (insn >> 12) & 0xf;
1755 rd0 = (insn >> 16) & 0xf;
1756 rd1 = (insn >> 0) & 0xf;
1757 gen_op_iwmmxt_movq_M0_wRn(rd0);
1758 if (insn & (1 << 21)) {
1759 if (insn & (1 << 20))
1760 gen_op_iwmmxt_mulshw_M0_wRn(rd1);
1762 gen_op_iwmmxt_mulslw_M0_wRn(rd1);
1764 if (insn & (1 << 20))
1765 gen_op_iwmmxt_muluhw_M0_wRn(rd1);
1767 gen_op_iwmmxt_mululw_M0_wRn(rd1);
1769 gen_op_iwmmxt_movq_wRn_M0(wrd);
1770 gen_op_iwmmxt_set_mup();
1772 case 0x410: case 0x510: case 0x610: case 0x710: /* WMAC */
1773 wrd = (insn >> 12) & 0xf;
1774 rd0 = (insn >> 16) & 0xf;
1775 rd1 = (insn >> 0) & 0xf;
1776 gen_op_iwmmxt_movq_M0_wRn(rd0);
1777 if (insn & (1 << 21))
1778 gen_op_iwmmxt_macsw_M0_wRn(rd1);
1780 gen_op_iwmmxt_macuw_M0_wRn(rd1);
1781 if (!(insn & (1 << 20))) {
1782 iwmmxt_load_reg(cpu_V1, wrd);
1783 tcg_gen_add_i64(cpu_M0, cpu_M0, cpu_V1);
1785 gen_op_iwmmxt_movq_wRn_M0(wrd);
1786 gen_op_iwmmxt_set_mup();
1788 case 0x006: case 0x406: case 0x806: case 0xc06: /* WCMPEQ */
1789 wrd = (insn >> 12) & 0xf;
1790 rd0 = (insn >> 16) & 0xf;
1791 rd1 = (insn >> 0) & 0xf;
1792 gen_op_iwmmxt_movq_M0_wRn(rd0);
1793 switch ((insn >> 22) & 3) {
1795 gen_op_iwmmxt_cmpeqb_M0_wRn(rd1);
1798 gen_op_iwmmxt_cmpeqw_M0_wRn(rd1);
1801 gen_op_iwmmxt_cmpeql_M0_wRn(rd1);
1806 gen_op_iwmmxt_movq_wRn_M0(wrd);
1807 gen_op_iwmmxt_set_mup();
1808 gen_op_iwmmxt_set_cup();
1810 case 0x800: case 0x900: case 0xc00: case 0xd00: /* WAVG2 */
1811 wrd = (insn >> 12) & 0xf;
1812 rd0 = (insn >> 16) & 0xf;
1813 rd1 = (insn >> 0) & 0xf;
1814 gen_op_iwmmxt_movq_M0_wRn(rd0);
1815 if (insn & (1 << 22)) {
1816 if (insn & (1 << 20))
1817 gen_op_iwmmxt_avgw1_M0_wRn(rd1);
1819 gen_op_iwmmxt_avgw0_M0_wRn(rd1);
1821 if (insn & (1 << 20))
1822 gen_op_iwmmxt_avgb1_M0_wRn(rd1);
1824 gen_op_iwmmxt_avgb0_M0_wRn(rd1);
1826 gen_op_iwmmxt_movq_wRn_M0(wrd);
1827 gen_op_iwmmxt_set_mup();
1828 gen_op_iwmmxt_set_cup();
1830 case 0x802: case 0x902: case 0xa02: case 0xb02: /* WALIGNR */
1831 wrd = (insn >> 12) & 0xf;
1832 rd0 = (insn >> 16) & 0xf;
1833 rd1 = (insn >> 0) & 0xf;
1834 gen_op_iwmmxt_movq_M0_wRn(rd0);
1835 gen_op_iwmmxt_movl_T0_wCx(ARM_IWMMXT_wCGR0 + ((insn >> 20) & 3));
1836 gen_op_movl_T1_im(7);
1837 gen_op_andl_T0_T1();
1838 gen_op_iwmmxt_align_M0_T0_wRn(rd1);
1839 gen_op_iwmmxt_movq_wRn_M0(wrd);
1840 gen_op_iwmmxt_set_mup();
1842 case 0x601: case 0x605: case 0x609: case 0x60d: /* TINSR */
1843 rd = (insn >> 12) & 0xf;
1844 wrd = (insn >> 16) & 0xf;
1845 gen_movl_T0_reg(s, rd);
1846 gen_op_iwmmxt_movq_M0_wRn(wrd);
1847 switch ((insn >> 6) & 3) {
1849 gen_op_movl_T1_im(0xff);
1850 gen_op_iwmmxt_insr_M0_T0_T1((insn & 7) << 3);
1853 gen_op_movl_T1_im(0xffff);
1854 gen_op_iwmmxt_insr_M0_T0_T1((insn & 3) << 4);
1857 gen_op_movl_T1_im(0xffffffff);
1858 gen_op_iwmmxt_insr_M0_T0_T1((insn & 1) << 5);
1863 gen_op_iwmmxt_movq_wRn_M0(wrd);
1864 gen_op_iwmmxt_set_mup();
1866 case 0x107: case 0x507: case 0x907: case 0xd07: /* TEXTRM */
1867 rd = (insn >> 12) & 0xf;
1868 wrd = (insn >> 16) & 0xf;
1871 gen_op_iwmmxt_movq_M0_wRn(wrd);
1872 switch ((insn >> 22) & 3) {
1875 gen_op_iwmmxt_extrsb_T0_M0((insn & 7) << 3);
1877 gen_op_iwmmxt_extru_T0_M0((insn & 7) << 3, 0xff);
1882 gen_op_iwmmxt_extrsw_T0_M0((insn & 3) << 4);
1884 gen_op_iwmmxt_extru_T0_M0((insn & 3) << 4, 0xffff);
1888 gen_op_iwmmxt_extru_T0_M0((insn & 1) << 5, ~0u);
1893 gen_movl_reg_T0(s, rd);
1895 case 0x117: case 0x517: case 0x917: case 0xd17: /* TEXTRC */
1896 if ((insn & 0x000ff008) != 0x0003f000)
1898 gen_op_iwmmxt_movl_T1_wCx(ARM_IWMMXT_wCASF);
1899 switch ((insn >> 22) & 3) {
1901 gen_op_shrl_T1_im(((insn & 7) << 2) + 0);
1904 gen_op_shrl_T1_im(((insn & 3) << 3) + 4);
1907 gen_op_shrl_T1_im(((insn & 1) << 4) + 12);
1912 gen_op_shll_T1_im(28);
1913 gen_set_nzcv(cpu_T[1]);
1915 case 0x401: case 0x405: case 0x409: case 0x40d: /* TBCST */
1916 rd = (insn >> 12) & 0xf;
1917 wrd = (insn >> 16) & 0xf;
1918 gen_movl_T0_reg(s, rd);
1919 switch ((insn >> 6) & 3) {
1921 gen_helper_iwmmxt_bcstb(cpu_M0, cpu_T[0]);
1924 gen_helper_iwmmxt_bcstw(cpu_M0, cpu_T[0]);
1927 gen_helper_iwmmxt_bcstl(cpu_M0, cpu_T[0]);
1932 gen_op_iwmmxt_movq_wRn_M0(wrd);
1933 gen_op_iwmmxt_set_mup();
1935 case 0x113: case 0x513: case 0x913: case 0xd13: /* TANDC */
1936 if ((insn & 0x000ff00f) != 0x0003f000)
1938 gen_op_iwmmxt_movl_T1_wCx(ARM_IWMMXT_wCASF);
1939 switch ((insn >> 22) & 3) {
1941 for (i = 0; i < 7; i ++) {
1942 gen_op_shll_T1_im(4);
1943 gen_op_andl_T0_T1();
1947 for (i = 0; i < 3; i ++) {
1948 gen_op_shll_T1_im(8);
1949 gen_op_andl_T0_T1();
1953 gen_op_shll_T1_im(16);
1954 gen_op_andl_T0_T1();
1959 gen_set_nzcv(cpu_T[0]);
1961 case 0x01c: case 0x41c: case 0x81c: case 0xc1c: /* WACC */
1962 wrd = (insn >> 12) & 0xf;
1963 rd0 = (insn >> 16) & 0xf;
1964 gen_op_iwmmxt_movq_M0_wRn(rd0);
1965 switch ((insn >> 22) & 3) {
1967 gen_helper_iwmmxt_addcb(cpu_M0, cpu_M0);
1970 gen_helper_iwmmxt_addcw(cpu_M0, cpu_M0);
1973 gen_helper_iwmmxt_addcl(cpu_M0, cpu_M0);
1978 gen_op_iwmmxt_movq_wRn_M0(wrd);
1979 gen_op_iwmmxt_set_mup();
1981 case 0x115: case 0x515: case 0x915: case 0xd15: /* TORC */
1982 if ((insn & 0x000ff00f) != 0x0003f000)
1984 gen_op_iwmmxt_movl_T1_wCx(ARM_IWMMXT_wCASF);
1985 switch ((insn >> 22) & 3) {
1987 for (i = 0; i < 7; i ++) {
1988 gen_op_shll_T1_im(4);
1993 for (i = 0; i < 3; i ++) {
1994 gen_op_shll_T1_im(8);
1999 gen_op_shll_T1_im(16);
2005 gen_set_nzcv(cpu_T[0]);
2007 case 0x103: case 0x503: case 0x903: case 0xd03: /* TMOVMSK */
2008 rd = (insn >> 12) & 0xf;
2009 rd0 = (insn >> 16) & 0xf;
2010 if ((insn & 0xf) != 0)
2012 gen_op_iwmmxt_movq_M0_wRn(rd0);
2013 switch ((insn >> 22) & 3) {
2015 gen_helper_iwmmxt_msbb(cpu_T[0], cpu_M0);
2018 gen_helper_iwmmxt_msbw(cpu_T[0], cpu_M0);
2021 gen_helper_iwmmxt_msbl(cpu_T[0], cpu_M0);
2026 gen_movl_reg_T0(s, rd);
2028 case 0x106: case 0x306: case 0x506: case 0x706: /* WCMPGT */
2029 case 0x906: case 0xb06: case 0xd06: case 0xf06:
2030 wrd = (insn >> 12) & 0xf;
2031 rd0 = (insn >> 16) & 0xf;
2032 rd1 = (insn >> 0) & 0xf;
2033 gen_op_iwmmxt_movq_M0_wRn(rd0);
2034 switch ((insn >> 22) & 3) {
2036 if (insn & (1 << 21))
2037 gen_op_iwmmxt_cmpgtsb_M0_wRn(rd1);
2039 gen_op_iwmmxt_cmpgtub_M0_wRn(rd1);
2042 if (insn & (1 << 21))
2043 gen_op_iwmmxt_cmpgtsw_M0_wRn(rd1);
2045 gen_op_iwmmxt_cmpgtuw_M0_wRn(rd1);
2048 if (insn & (1 << 21))
2049 gen_op_iwmmxt_cmpgtsl_M0_wRn(rd1);
2051 gen_op_iwmmxt_cmpgtul_M0_wRn(rd1);
2056 gen_op_iwmmxt_movq_wRn_M0(wrd);
2057 gen_op_iwmmxt_set_mup();
2058 gen_op_iwmmxt_set_cup();
2060 case 0x00e: case 0x20e: case 0x40e: case 0x60e: /* WUNPCKEL */
2061 case 0x80e: case 0xa0e: case 0xc0e: case 0xe0e:
2062 wrd = (insn >> 12) & 0xf;
2063 rd0 = (insn >> 16) & 0xf;
2064 gen_op_iwmmxt_movq_M0_wRn(rd0);
2065 switch ((insn >> 22) & 3) {
2067 if (insn & (1 << 21))
2068 gen_op_iwmmxt_unpacklsb_M0();
2070 gen_op_iwmmxt_unpacklub_M0();
2073 if (insn & (1 << 21))
2074 gen_op_iwmmxt_unpacklsw_M0();
2076 gen_op_iwmmxt_unpackluw_M0();
2079 if (insn & (1 << 21))
2080 gen_op_iwmmxt_unpacklsl_M0();
2082 gen_op_iwmmxt_unpacklul_M0();
2087 gen_op_iwmmxt_movq_wRn_M0(wrd);
2088 gen_op_iwmmxt_set_mup();
2089 gen_op_iwmmxt_set_cup();
2091 case 0x00c: case 0x20c: case 0x40c: case 0x60c: /* WUNPCKEH */
2092 case 0x80c: case 0xa0c: case 0xc0c: case 0xe0c:
2093 wrd = (insn >> 12) & 0xf;
2094 rd0 = (insn >> 16) & 0xf;
2095 gen_op_iwmmxt_movq_M0_wRn(rd0);
2096 switch ((insn >> 22) & 3) {
2098 if (insn & (1 << 21))
2099 gen_op_iwmmxt_unpackhsb_M0();
2101 gen_op_iwmmxt_unpackhub_M0();
2104 if (insn & (1 << 21))
2105 gen_op_iwmmxt_unpackhsw_M0();
2107 gen_op_iwmmxt_unpackhuw_M0();
2110 if (insn & (1 << 21))
2111 gen_op_iwmmxt_unpackhsl_M0();
2113 gen_op_iwmmxt_unpackhul_M0();
2118 gen_op_iwmmxt_movq_wRn_M0(wrd);
2119 gen_op_iwmmxt_set_mup();
2120 gen_op_iwmmxt_set_cup();
2122 case 0x204: case 0x604: case 0xa04: case 0xe04: /* WSRL */
2123 case 0x214: case 0x614: case 0xa14: case 0xe14:
2124 wrd = (insn >> 12) & 0xf;
2125 rd0 = (insn >> 16) & 0xf;
2126 gen_op_iwmmxt_movq_M0_wRn(rd0);
2127 if (gen_iwmmxt_shift(insn, 0xff))
2129 switch ((insn >> 22) & 3) {
2133 gen_helper_iwmmxt_srlw(cpu_M0, cpu_env, cpu_M0, cpu_T[0]);
2136 gen_helper_iwmmxt_srll(cpu_M0, cpu_env, cpu_M0, cpu_T[0]);
2139 gen_helper_iwmmxt_srlq(cpu_M0, cpu_env, cpu_M0, cpu_T[0]);
2142 gen_op_iwmmxt_movq_wRn_M0(wrd);
2143 gen_op_iwmmxt_set_mup();
2144 gen_op_iwmmxt_set_cup();
2146 case 0x004: case 0x404: case 0x804: case 0xc04: /* WSRA */
2147 case 0x014: case 0x414: case 0x814: case 0xc14:
2148 wrd = (insn >> 12) & 0xf;
2149 rd0 = (insn >> 16) & 0xf;
2150 gen_op_iwmmxt_movq_M0_wRn(rd0);
2151 if (gen_iwmmxt_shift(insn, 0xff))
2153 switch ((insn >> 22) & 3) {
2157 gen_helper_iwmmxt_sraw(cpu_M0, cpu_env, cpu_M0, cpu_T[0]);
2160 gen_helper_iwmmxt_sral(cpu_M0, cpu_env, cpu_M0, cpu_T[0]);
2163 gen_helper_iwmmxt_sraq(cpu_M0, cpu_env, cpu_M0, cpu_T[0]);
2166 gen_op_iwmmxt_movq_wRn_M0(wrd);
2167 gen_op_iwmmxt_set_mup();
2168 gen_op_iwmmxt_set_cup();
2170 case 0x104: case 0x504: case 0x904: case 0xd04: /* WSLL */
2171 case 0x114: case 0x514: case 0x914: case 0xd14:
2172 wrd = (insn >> 12) & 0xf;
2173 rd0 = (insn >> 16) & 0xf;
2174 gen_op_iwmmxt_movq_M0_wRn(rd0);
2175 if (gen_iwmmxt_shift(insn, 0xff))
2177 switch ((insn >> 22) & 3) {
2181 gen_helper_iwmmxt_sllw(cpu_M0, cpu_env, cpu_M0, cpu_T[0]);
2184 gen_helper_iwmmxt_slll(cpu_M0, cpu_env, cpu_M0, cpu_T[0]);
2187 gen_helper_iwmmxt_sllq(cpu_M0, cpu_env, cpu_M0, cpu_T[0]);
2190 gen_op_iwmmxt_movq_wRn_M0(wrd);
2191 gen_op_iwmmxt_set_mup();
2192 gen_op_iwmmxt_set_cup();
2194 case 0x304: case 0x704: case 0xb04: case 0xf04: /* WROR */
2195 case 0x314: case 0x714: case 0xb14: case 0xf14:
2196 wrd = (insn >> 12) & 0xf;
2197 rd0 = (insn >> 16) & 0xf;
2198 gen_op_iwmmxt_movq_M0_wRn(rd0);
2199 switch ((insn >> 22) & 3) {
2203 if (gen_iwmmxt_shift(insn, 0xf))
2205 gen_helper_iwmmxt_rorw(cpu_M0, cpu_env, cpu_M0, cpu_T[0]);
2208 if (gen_iwmmxt_shift(insn, 0x1f))
2210 gen_helper_iwmmxt_rorl(cpu_M0, cpu_env, cpu_M0, cpu_T[0]);
2213 if (gen_iwmmxt_shift(insn, 0x3f))
2215 gen_helper_iwmmxt_rorq(cpu_M0, cpu_env, cpu_M0, cpu_T[0]);
2218 gen_op_iwmmxt_movq_wRn_M0(wrd);
2219 gen_op_iwmmxt_set_mup();
2220 gen_op_iwmmxt_set_cup();
2222 case 0x116: case 0x316: case 0x516: case 0x716: /* WMIN */
2223 case 0x916: case 0xb16: case 0xd16: case 0xf16:
2224 wrd = (insn >> 12) & 0xf;
2225 rd0 = (insn >> 16) & 0xf;
2226 rd1 = (insn >> 0) & 0xf;
2227 gen_op_iwmmxt_movq_M0_wRn(rd0);
2228 switch ((insn >> 22) & 3) {
2230 if (insn & (1 << 21))
2231 gen_op_iwmmxt_minsb_M0_wRn(rd1);
2233 gen_op_iwmmxt_minub_M0_wRn(rd1);
2236 if (insn & (1 << 21))
2237 gen_op_iwmmxt_minsw_M0_wRn(rd1);
2239 gen_op_iwmmxt_minuw_M0_wRn(rd1);
2242 if (insn & (1 << 21))
2243 gen_op_iwmmxt_minsl_M0_wRn(rd1);
2245 gen_op_iwmmxt_minul_M0_wRn(rd1);
2250 gen_op_iwmmxt_movq_wRn_M0(wrd);
2251 gen_op_iwmmxt_set_mup();
2253 case 0x016: case 0x216: case 0x416: case 0x616: /* WMAX */
2254 case 0x816: case 0xa16: case 0xc16: case 0xe16:
2255 wrd = (insn >> 12) & 0xf;
2256 rd0 = (insn >> 16) & 0xf;
2257 rd1 = (insn >> 0) & 0xf;
2258 gen_op_iwmmxt_movq_M0_wRn(rd0);
2259 switch ((insn >> 22) & 3) {
2261 if (insn & (1 << 21))
2262 gen_op_iwmmxt_maxsb_M0_wRn(rd1);
2264 gen_op_iwmmxt_maxub_M0_wRn(rd1);
2267 if (insn & (1 << 21))
2268 gen_op_iwmmxt_maxsw_M0_wRn(rd1);
2270 gen_op_iwmmxt_maxuw_M0_wRn(rd1);
2273 if (insn & (1 << 21))
2274 gen_op_iwmmxt_maxsl_M0_wRn(rd1);
2276 gen_op_iwmmxt_maxul_M0_wRn(rd1);
2281 gen_op_iwmmxt_movq_wRn_M0(wrd);
2282 gen_op_iwmmxt_set_mup();
2284 case 0x002: case 0x102: case 0x202: case 0x302: /* WALIGNI */
2285 case 0x402: case 0x502: case 0x602: case 0x702:
2286 wrd = (insn >> 12) & 0xf;
2287 rd0 = (insn >> 16) & 0xf;
2288 rd1 = (insn >> 0) & 0xf;
2289 gen_op_iwmmxt_movq_M0_wRn(rd0);
2290 gen_op_movl_T0_im((insn >> 20) & 3);
2291 gen_op_iwmmxt_align_M0_T0_wRn(rd1);
2292 gen_op_iwmmxt_movq_wRn_M0(wrd);
2293 gen_op_iwmmxt_set_mup();
2295 case 0x01a: case 0x11a: case 0x21a: case 0x31a: /* WSUB */
2296 case 0x41a: case 0x51a: case 0x61a: case 0x71a:
2297 case 0x81a: case 0x91a: case 0xa1a: case 0xb1a:
2298 case 0xc1a: case 0xd1a: case 0xe1a: case 0xf1a:
2299 wrd = (insn >> 12) & 0xf;
2300 rd0 = (insn >> 16) & 0xf;
2301 rd1 = (insn >> 0) & 0xf;
2302 gen_op_iwmmxt_movq_M0_wRn(rd0);
2303 switch ((insn >> 20) & 0xf) {
2305 gen_op_iwmmxt_subnb_M0_wRn(rd1);
2308 gen_op_iwmmxt_subub_M0_wRn(rd1);
2311 gen_op_iwmmxt_subsb_M0_wRn(rd1);
2314 gen_op_iwmmxt_subnw_M0_wRn(rd1);
2317 gen_op_iwmmxt_subuw_M0_wRn(rd1);
2320 gen_op_iwmmxt_subsw_M0_wRn(rd1);
2323 gen_op_iwmmxt_subnl_M0_wRn(rd1);
2326 gen_op_iwmmxt_subul_M0_wRn(rd1);
2329 gen_op_iwmmxt_subsl_M0_wRn(rd1);
2334 gen_op_iwmmxt_movq_wRn_M0(wrd);
2335 gen_op_iwmmxt_set_mup();
2336 gen_op_iwmmxt_set_cup();
2338 case 0x01e: case 0x11e: case 0x21e: case 0x31e: /* WSHUFH */
2339 case 0x41e: case 0x51e: case 0x61e: case 0x71e:
2340 case 0x81e: case 0x91e: case 0xa1e: case 0xb1e:
2341 case 0xc1e: case 0xd1e: case 0xe1e: case 0xf1e:
2342 wrd = (insn >> 12) & 0xf;
2343 rd0 = (insn >> 16) & 0xf;
2344 gen_op_iwmmxt_movq_M0_wRn(rd0);
2345 gen_op_movl_T0_im(((insn >> 16) & 0xf0) | (insn & 0x0f));
2346 gen_helper_iwmmxt_shufh(cpu_M0, cpu_env, cpu_M0, cpu_T[0]);
2347 gen_op_iwmmxt_movq_wRn_M0(wrd);
2348 gen_op_iwmmxt_set_mup();
2349 gen_op_iwmmxt_set_cup();
2351 case 0x018: case 0x118: case 0x218: case 0x318: /* WADD */
2352 case 0x418: case 0x518: case 0x618: case 0x718:
2353 case 0x818: case 0x918: case 0xa18: case 0xb18:
2354 case 0xc18: case 0xd18: case 0xe18: case 0xf18:
2355 wrd = (insn >> 12) & 0xf;
2356 rd0 = (insn >> 16) & 0xf;
2357 rd1 = (insn >> 0) & 0xf;
2358 gen_op_iwmmxt_movq_M0_wRn(rd0);
2359 switch ((insn >> 20) & 0xf) {
2361 gen_op_iwmmxt_addnb_M0_wRn(rd1);
2364 gen_op_iwmmxt_addub_M0_wRn(rd1);
2367 gen_op_iwmmxt_addsb_M0_wRn(rd1);
2370 gen_op_iwmmxt_addnw_M0_wRn(rd1);
2373 gen_op_iwmmxt_adduw_M0_wRn(rd1);
2376 gen_op_iwmmxt_addsw_M0_wRn(rd1);
2379 gen_op_iwmmxt_addnl_M0_wRn(rd1);
2382 gen_op_iwmmxt_addul_M0_wRn(rd1);
2385 gen_op_iwmmxt_addsl_M0_wRn(rd1);
2390 gen_op_iwmmxt_movq_wRn_M0(wrd);
2391 gen_op_iwmmxt_set_mup();
2392 gen_op_iwmmxt_set_cup();
2394 case 0x008: case 0x108: case 0x208: case 0x308: /* WPACK */
2395 case 0x408: case 0x508: case 0x608: case 0x708:
2396 case 0x808: case 0x908: case 0xa08: case 0xb08:
2397 case 0xc08: case 0xd08: case 0xe08: case 0xf08:
2398 wrd = (insn >> 12) & 0xf;
2399 rd0 = (insn >> 16) & 0xf;
2400 rd1 = (insn >> 0) & 0xf;
2401 gen_op_iwmmxt_movq_M0_wRn(rd0);
2402 if (!(insn & (1 << 20)))
2404 switch ((insn >> 22) & 3) {
2408 if (insn & (1 << 21))
2409 gen_op_iwmmxt_packsw_M0_wRn(rd1);
2411 gen_op_iwmmxt_packuw_M0_wRn(rd1);
2414 if (insn & (1 << 21))
2415 gen_op_iwmmxt_packsl_M0_wRn(rd1);
2417 gen_op_iwmmxt_packul_M0_wRn(rd1);
2420 if (insn & (1 << 21))
2421 gen_op_iwmmxt_packsq_M0_wRn(rd1);
2423 gen_op_iwmmxt_packuq_M0_wRn(rd1);
2426 gen_op_iwmmxt_movq_wRn_M0(wrd);
2427 gen_op_iwmmxt_set_mup();
2428 gen_op_iwmmxt_set_cup();
2430 case 0x201: case 0x203: case 0x205: case 0x207:
2431 case 0x209: case 0x20b: case 0x20d: case 0x20f:
2432 case 0x211: case 0x213: case 0x215: case 0x217:
2433 case 0x219: case 0x21b: case 0x21d: case 0x21f:
2434 wrd = (insn >> 5) & 0xf;
2435 rd0 = (insn >> 12) & 0xf;
2436 rd1 = (insn >> 0) & 0xf;
2437 if (rd0 == 0xf || rd1 == 0xf)
2439 gen_op_iwmmxt_movq_M0_wRn(wrd);
2440 switch ((insn >> 16) & 0xf) {
2441 case 0x0: /* TMIA */
2442 gen_movl_T0_reg(s, rd0);
2443 gen_movl_T1_reg(s, rd1);
2444 gen_op_iwmmxt_muladdsl_M0_T0_T1();
2446 case 0x8: /* TMIAPH */
2447 gen_movl_T0_reg(s, rd0);
2448 gen_movl_T1_reg(s, rd1);
2449 gen_op_iwmmxt_muladdsw_M0_T0_T1();
2451 case 0xc: case 0xd: case 0xe: case 0xf: /* TMIAxy */
2452 gen_movl_T1_reg(s, rd0);
2453 if (insn & (1 << 16))
2454 gen_op_shrl_T1_im(16);
2455 gen_op_movl_T0_T1();
2456 gen_movl_T1_reg(s, rd1);
2457 if (insn & (1 << 17))
2458 gen_op_shrl_T1_im(16);
2459 gen_op_iwmmxt_muladdswl_M0_T0_T1();
2464 gen_op_iwmmxt_movq_wRn_M0(wrd);
2465 gen_op_iwmmxt_set_mup();
2474 /* Disassemble an XScale DSP instruction. Returns nonzero if an error occured
2475 (ie. an undefined instruction). */
2476 static int disas_dsp_insn(CPUState *env, DisasContext *s, uint32_t insn)
2478 int acc, rd0, rd1, rdhi, rdlo;
2480 if ((insn & 0x0ff00f10) == 0x0e200010) {
2481 /* Multiply with Internal Accumulate Format */
2482 rd0 = (insn >> 12) & 0xf;
2484 acc = (insn >> 5) & 7;
2489 switch ((insn >> 16) & 0xf) {
2491 gen_movl_T0_reg(s, rd0);
2492 gen_movl_T1_reg(s, rd1);
2493 gen_op_iwmmxt_muladdsl_M0_T0_T1();
2495 case 0x8: /* MIAPH */
2496 gen_movl_T0_reg(s, rd0);
2497 gen_movl_T1_reg(s, rd1);
2498 gen_op_iwmmxt_muladdsw_M0_T0_T1();
2500 case 0xc: /* MIABB */
2501 case 0xd: /* MIABT */
2502 case 0xe: /* MIATB */
2503 case 0xf: /* MIATT */
2504 gen_movl_T1_reg(s, rd0);
2505 if (insn & (1 << 16))
2506 gen_op_shrl_T1_im(16);
2507 gen_op_movl_T0_T1();
2508 gen_movl_T1_reg(s, rd1);
2509 if (insn & (1 << 17))
2510 gen_op_shrl_T1_im(16);
2511 gen_op_iwmmxt_muladdswl_M0_T0_T1();
2517 gen_op_iwmmxt_movq_wRn_M0(acc);
2521 if ((insn & 0x0fe00ff8) == 0x0c400000) {
2522 /* Internal Accumulator Access Format */
2523 rdhi = (insn >> 16) & 0xf;
2524 rdlo = (insn >> 12) & 0xf;
2530 if (insn & ARM_CP_RW_BIT) { /* MRA */
2531 gen_iwmmxt_movl_T0_T1_wRn(acc);
2532 gen_movl_reg_T0(s, rdlo);
2533 gen_op_movl_T0_im((1 << (40 - 32)) - 1);
2534 gen_op_andl_T0_T1();
2535 gen_movl_reg_T0(s, rdhi);
2537 gen_movl_T0_reg(s, rdlo);
2538 gen_movl_T1_reg(s, rdhi);
2539 gen_iwmmxt_movl_wRn_T0_T1(acc);
2547 /* Disassemble system coprocessor instruction. Return nonzero if
2548 instruction is not defined. */
2549 static int disas_cp_insn(CPUState *env, DisasContext *s, uint32_t insn)
2552 uint32_t rd = (insn >> 12) & 0xf;
2553 uint32_t cp = (insn >> 8) & 0xf;
2558 if (insn & ARM_CP_RW_BIT) {
2559 if (!env->cp[cp].cp_read)
2561 gen_set_pc_im(s->pc);
2563 gen_helper_get_cp(tmp, cpu_env, tcg_const_i32(insn));
2564 store_reg(s, rd, tmp);
2566 if (!env->cp[cp].cp_write)
2568 gen_set_pc_im(s->pc);
2569 tmp = load_reg(s, rd);
2570 gen_helper_set_cp(cpu_env, tcg_const_i32(insn), tmp);
2576 static int cp15_user_ok(uint32_t insn)
2578 int cpn = (insn >> 16) & 0xf;
2579 int cpm = insn & 0xf;
2580 int op = ((insn >> 5) & 7) | ((insn >> 18) & 0x38);
2582 if (cpn == 13 && cpm == 0) {
2584 if (op == 2 || (op == 3 && (insn & ARM_CP_RW_BIT)))
2588 /* ISB, DSB, DMB. */
2589 if ((cpm == 5 && op == 4)
2590 || (cpm == 10 && (op == 4 || op == 5)))
2596 /* Disassemble system coprocessor (cp15) instruction. Return nonzero if
2597 instruction is not defined. */
2598 static int disas_cp15_insn(CPUState *env, DisasContext *s, uint32_t insn)
2603 /* M profile cores use memory mapped registers instead of cp15. */
2604 if (arm_feature(env, ARM_FEATURE_M))
2607 if ((insn & (1 << 25)) == 0) {
2608 if (insn & (1 << 20)) {
2612 /* mcrr. Used for block cache operations, so implement as no-op. */
2615 if ((insn & (1 << 4)) == 0) {
2619 if (IS_USER(s) && !cp15_user_ok(insn)) {
2622 if ((insn & 0x0fff0fff) == 0x0e070f90
2623 || (insn & 0x0fff0fff) == 0x0e070f58) {
2624 /* Wait for interrupt. */
2625 gen_set_pc_im(s->pc);
2626 s->is_jmp = DISAS_WFI;
2629 rd = (insn >> 12) & 0xf;
2630 if (insn & ARM_CP_RW_BIT) {
2632 gen_helper_get_cp15(tmp, cpu_env, tcg_const_i32(insn));
2633 /* If the destination register is r15 then sets condition codes. */
2635 store_reg(s, rd, tmp);
2639 tmp = load_reg(s, rd);
2640 gen_helper_set_cp15(cpu_env, tcg_const_i32(insn), tmp);
2642 /* Normally we would always end the TB here, but Linux
2643 * arch/arm/mach-pxa/sleep.S expects two instructions following
2644 * an MMU enable to execute from cache. Imitate this behaviour. */
2645 if (!arm_feature(env, ARM_FEATURE_XSCALE) ||
2646 (insn & 0x0fff0fff) != 0x0e010f10)
2652 #define VFP_REG_SHR(x, n) (((n) > 0) ? (x) >> (n) : (x) << -(n))
2653 #define VFP_SREG(insn, bigbit, smallbit) \
2654 ((VFP_REG_SHR(insn, bigbit - 1) & 0x1e) | (((insn) >> (smallbit)) & 1))
2655 #define VFP_DREG(reg, insn, bigbit, smallbit) do { \
2656 if (arm_feature(env, ARM_FEATURE_VFP3)) { \
2657 reg = (((insn) >> (bigbit)) & 0x0f) \
2658 | (((insn) >> ((smallbit) - 4)) & 0x10); \
2660 if (insn & (1 << (smallbit))) \
2662 reg = ((insn) >> (bigbit)) & 0x0f; \
2665 #define VFP_SREG_D(insn) VFP_SREG(insn, 12, 22)
2666 #define VFP_DREG_D(reg, insn) VFP_DREG(reg, insn, 12, 22)
2667 #define VFP_SREG_N(insn) VFP_SREG(insn, 16, 7)
2668 #define VFP_DREG_N(reg, insn) VFP_DREG(reg, insn, 16, 7)
2669 #define VFP_SREG_M(insn) VFP_SREG(insn, 0, 5)
2670 #define VFP_DREG_M(reg, insn) VFP_DREG(reg, insn, 0, 5)
2672 /* Move between integer and VFP cores. */
2673 static TCGv gen_vfp_mrs(void)
2675 TCGv tmp = new_tmp();
2676 tcg_gen_mov_i32(tmp, cpu_F0s);
2680 static void gen_vfp_msr(TCGv tmp)
2682 tcg_gen_mov_i32(cpu_F0s, tmp);
2687 vfp_enabled(CPUState * env)
2689 return ((env->vfp.xregs[ARM_VFP_FPEXC] & (1 << 30)) != 0);
2692 static void gen_neon_dup_u8(TCGv var, int shift)
2694 TCGv tmp = new_tmp();
2696 tcg_gen_shri_i32(var, var, shift);
2697 tcg_gen_ext8u_i32(var, var);
2698 tcg_gen_shli_i32(tmp, var, 8);
2699 tcg_gen_or_i32(var, var, tmp);
2700 tcg_gen_shli_i32(tmp, var, 16);
2701 tcg_gen_or_i32(var, var, tmp);
2705 static void gen_neon_dup_low16(TCGv var)
2707 TCGv tmp = new_tmp();
2708 tcg_gen_ext16u_i32(var, var);
2709 tcg_gen_shli_i32(tmp, var, 16);
2710 tcg_gen_or_i32(var, var, tmp);
2714 static void gen_neon_dup_high16(TCGv var)
2716 TCGv tmp = new_tmp();
2717 tcg_gen_andi_i32(var, var, 0xffff0000);
2718 tcg_gen_shri_i32(tmp, var, 16);
2719 tcg_gen_or_i32(var, var, tmp);
2723 /* Disassemble a VFP instruction. Returns nonzero if an error occured
2724 (ie. an undefined instruction). */
2725 static int disas_vfp_insn(CPUState * env, DisasContext *s, uint32_t insn)
2727 uint32_t rd, rn, rm, op, i, n, offset, delta_d, delta_m, bank_mask;
2732 if (!arm_feature(env, ARM_FEATURE_VFP))
2735 if (!vfp_enabled(env)) {
2736 /* VFP disabled. Only allow fmxr/fmrx to/from some control regs. */
2737 if ((insn & 0x0fe00fff) != 0x0ee00a10)
2739 rn = (insn >> 16) & 0xf;
2740 if (rn != ARM_VFP_FPSID && rn != ARM_VFP_FPEXC
2741 && rn != ARM_VFP_MVFR1 && rn != ARM_VFP_MVFR0)
2744 dp = ((insn & 0xf00) == 0xb00);
2745 switch ((insn >> 24) & 0xf) {
2747 if (insn & (1 << 4)) {
2748 /* single register transfer */
2749 rd = (insn >> 12) & 0xf;
2754 VFP_DREG_N(rn, insn);
2757 if (insn & 0x00c00060
2758 && !arm_feature(env, ARM_FEATURE_NEON))
2761 pass = (insn >> 21) & 1;
2762 if (insn & (1 << 22)) {
2764 offset = ((insn >> 5) & 3) * 8;
2765 } else if (insn & (1 << 5)) {
2767 offset = (insn & (1 << 6)) ? 16 : 0;
2772 if (insn & ARM_CP_RW_BIT) {
2774 tmp = neon_load_reg(rn, pass);
2778 tcg_gen_shri_i32(tmp, tmp, offset);
2779 if (insn & (1 << 23))
2785 if (insn & (1 << 23)) {
2787 tcg_gen_shri_i32(tmp, tmp, 16);
2793 tcg_gen_sari_i32(tmp, tmp, 16);
2802 store_reg(s, rd, tmp);
2805 tmp = load_reg(s, rd);
2806 if (insn & (1 << 23)) {
2809 gen_neon_dup_u8(tmp, 0);
2810 } else if (size == 1) {
2811 gen_neon_dup_low16(tmp);
2814 tcg_gen_mov_i32(tmp2, tmp);
2815 neon_store_reg(rn, 0, tmp2);
2816 neon_store_reg(rn, 0, tmp);
2821 tmp2 = neon_load_reg(rn, pass);
2822 gen_bfi(tmp, tmp2, tmp, offset, 0xff);
2826 tmp2 = neon_load_reg(rn, pass);
2827 gen_bfi(tmp, tmp2, tmp, offset, 0xffff);
2833 neon_store_reg(rn, pass, tmp);
2837 if ((insn & 0x6f) != 0x00)
2839 rn = VFP_SREG_N(insn);
2840 if (insn & ARM_CP_RW_BIT) {
2842 if (insn & (1 << 21)) {
2843 /* system register */
2848 /* VFP2 allows access to FSID from userspace.
2849 VFP3 restricts all id registers to privileged
2852 && arm_feature(env, ARM_FEATURE_VFP3))
2854 tmp = load_cpu_field(vfp.xregs[rn]);
2859 tmp = load_cpu_field(vfp.xregs[rn]);
2861 case ARM_VFP_FPINST:
2862 case ARM_VFP_FPINST2:
2863 /* Not present in VFP3. */
2865 || arm_feature(env, ARM_FEATURE_VFP3))
2867 tmp = load_cpu_field(vfp.xregs[rn]);
2871 tmp = load_cpu_field(vfp.xregs[ARM_VFP_FPSCR]);
2872 tcg_gen_andi_i32(tmp, tmp, 0xf0000000);
2875 gen_helper_vfp_get_fpscr(tmp, cpu_env);
2881 || !arm_feature(env, ARM_FEATURE_VFP3))
2883 tmp = load_cpu_field(vfp.xregs[rn]);
2889 gen_mov_F0_vreg(0, rn);
2890 tmp = gen_vfp_mrs();
2893 /* Set the 4 flag bits in the CPSR. */
2897 store_reg(s, rd, tmp);
2901 tmp = load_reg(s, rd);
2902 if (insn & (1 << 21)) {
2904 /* system register */
2909 /* Writes are ignored. */
2912 gen_helper_vfp_set_fpscr(cpu_env, tmp);
2919 store_cpu_field(tmp, vfp.xregs[rn]);
2922 case ARM_VFP_FPINST:
2923 case ARM_VFP_FPINST2:
2924 store_cpu_field(tmp, vfp.xregs[rn]);
2931 gen_mov_vreg_F0(0, rn);
2936 /* data processing */
2937 /* The opcode is in bits 23, 21, 20 and 6. */
2938 op = ((insn >> 20) & 8) | ((insn >> 19) & 6) | ((insn >> 6) & 1);
2942 rn = ((insn >> 15) & 0x1e) | ((insn >> 7) & 1);
2944 /* rn is register number */
2945 VFP_DREG_N(rn, insn);
2948 if (op == 15 && (rn == 15 || rn > 17)) {
2949 /* Integer or single precision destination. */
2950 rd = VFP_SREG_D(insn);
2952 VFP_DREG_D(rd, insn);
2955 if (op == 15 && (rn == 16 || rn == 17)) {
2956 /* Integer source. */
2957 rm = ((insn << 1) & 0x1e) | ((insn >> 5) & 1);
2959 VFP_DREG_M(rm, insn);
2962 rn = VFP_SREG_N(insn);
2963 if (op == 15 && rn == 15) {
2964 /* Double precision destination. */
2965 VFP_DREG_D(rd, insn);
2967 rd = VFP_SREG_D(insn);
2969 rm = VFP_SREG_M(insn);
2972 veclen = env->vfp.vec_len;
2973 if (op == 15 && rn > 3)
2976 /* Shut up compiler warnings. */
2987 /* Figure out what type of vector operation this is. */
2988 if ((rd & bank_mask) == 0) {
2993 delta_d = (env->vfp.vec_stride >> 1) + 1;
2995 delta_d = env->vfp.vec_stride + 1;
2997 if ((rm & bank_mask) == 0) {
2998 /* mixed scalar/vector */
3007 /* Load the initial operands. */
3012 /* Integer source */
3013 gen_mov_F0_vreg(0, rm);
3018 gen_mov_F0_vreg(dp, rd);
3019 gen_mov_F1_vreg(dp, rm);
3023 /* Compare with zero */
3024 gen_mov_F0_vreg(dp, rd);
3031 /* Source and destination the same. */
3032 gen_mov_F0_vreg(dp, rd);
3035 /* One source operand. */
3036 gen_mov_F0_vreg(dp, rm);
3040 /* Two source operands. */
3041 gen_mov_F0_vreg(dp, rn);
3042 gen_mov_F1_vreg(dp, rm);
3046 /* Perform the calculation. */
3048 case 0: /* mac: fd + (fn * fm) */
3050 gen_mov_F1_vreg(dp, rd);
3053 case 1: /* nmac: fd - (fn * fm) */
3056 gen_mov_F1_vreg(dp, rd);
3059 case 2: /* msc: -fd + (fn * fm) */
3061 gen_mov_F1_vreg(dp, rd);
3064 case 3: /* nmsc: -fd - (fn * fm) */
3066 gen_mov_F1_vreg(dp, rd);
3070 case 4: /* mul: fn * fm */
3073 case 5: /* nmul: -(fn * fm) */
3077 case 6: /* add: fn + fm */
3080 case 7: /* sub: fn - fm */
3083 case 8: /* div: fn / fm */
3086 case 14: /* fconst */
3087 if (!arm_feature(env, ARM_FEATURE_VFP3))
3090 n = (insn << 12) & 0x80000000;
3091 i = ((insn >> 12) & 0x70) | (insn & 0xf);
3098 tcg_gen_movi_i64(cpu_F0d, ((uint64_t)n) << 32);
3105 tcg_gen_movi_i32(cpu_F0s, n);
3108 case 15: /* extension space */
3131 case 11: /* cmpez */
3135 case 15: /* single<->double conversion */
3137 gen_helper_vfp_fcvtsd(cpu_F0s, cpu_F0d, cpu_env);
3139 gen_helper_vfp_fcvtds(cpu_F0d, cpu_F0s, cpu_env);
3141 case 16: /* fuito */
3144 case 17: /* fsito */
3147 case 20: /* fshto */
3148 if (!arm_feature(env, ARM_FEATURE_VFP3))
3150 gen_vfp_shto(dp, rm);
3152 case 21: /* fslto */
3153 if (!arm_feature(env, ARM_FEATURE_VFP3))
3155 gen_vfp_slto(dp, rm);
3157 case 22: /* fuhto */
3158 if (!arm_feature(env, ARM_FEATURE_VFP3))
3160 gen_vfp_uhto(dp, rm);
3162 case 23: /* fulto */
3163 if (!arm_feature(env, ARM_FEATURE_VFP3))
3165 gen_vfp_ulto(dp, rm);
3167 case 24: /* ftoui */
3170 case 25: /* ftouiz */
3173 case 26: /* ftosi */
3176 case 27: /* ftosiz */
3179 case 28: /* ftosh */
3180 if (!arm_feature(env, ARM_FEATURE_VFP3))
3182 gen_vfp_tosh(dp, rm);
3184 case 29: /* ftosl */
3185 if (!arm_feature(env, ARM_FEATURE_VFP3))
3187 gen_vfp_tosl(dp, rm);
3189 case 30: /* ftouh */
3190 if (!arm_feature(env, ARM_FEATURE_VFP3))
3192 gen_vfp_touh(dp, rm);
3194 case 31: /* ftoul */
3195 if (!arm_feature(env, ARM_FEATURE_VFP3))
3197 gen_vfp_toul(dp, rm);
3199 default: /* undefined */
3200 printf ("rn:%d\n", rn);
3204 default: /* undefined */
3205 printf ("op:%d\n", op);
3209 /* Write back the result. */
3210 if (op == 15 && (rn >= 8 && rn <= 11))
3211 ; /* Comparison, do nothing. */
3212 else if (op == 15 && rn > 17)
3213 /* Integer result. */
3214 gen_mov_vreg_F0(0, rd);
3215 else if (op == 15 && rn == 15)
3217 gen_mov_vreg_F0(!dp, rd);
3219 gen_mov_vreg_F0(dp, rd);
3221 /* break out of the loop if we have finished */
3225 if (op == 15 && delta_m == 0) {
3226 /* single source one-many */
3228 rd = ((rd + delta_d) & (bank_mask - 1))
3230 gen_mov_vreg_F0(dp, rd);
3234 /* Setup the next operands. */
3236 rd = ((rd + delta_d) & (bank_mask - 1))
3240 /* One source operand. */
3241 rm = ((rm + delta_m) & (bank_mask - 1))
3243 gen_mov_F0_vreg(dp, rm);
3245 /* Two source operands. */
3246 rn = ((rn + delta_d) & (bank_mask - 1))
3248 gen_mov_F0_vreg(dp, rn);
3250 rm = ((rm + delta_m) & (bank_mask - 1))
3252 gen_mov_F1_vreg(dp, rm);
3260 if (dp && (insn & 0x03e00000) == 0x00400000) {
3261 /* two-register transfer */
3262 rn = (insn >> 16) & 0xf;
3263 rd = (insn >> 12) & 0xf;
3265 VFP_DREG_M(rm, insn);
3267 rm = VFP_SREG_M(insn);
3270 if (insn & ARM_CP_RW_BIT) {
3273 gen_mov_F0_vreg(0, rm * 2);
3274 tmp = gen_vfp_mrs();
3275 store_reg(s, rd, tmp);
3276 gen_mov_F0_vreg(0, rm * 2 + 1);
3277 tmp = gen_vfp_mrs();
3278 store_reg(s, rn, tmp);
3280 gen_mov_F0_vreg(0, rm);
3281 tmp = gen_vfp_mrs();
3282 store_reg(s, rn, tmp);
3283 gen_mov_F0_vreg(0, rm + 1);
3284 tmp = gen_vfp_mrs();
3285 store_reg(s, rd, tmp);
3290 tmp = load_reg(s, rd);
3292 gen_mov_vreg_F0(0, rm * 2);
3293 tmp = load_reg(s, rn);
3295 gen_mov_vreg_F0(0, rm * 2 + 1);
3297 tmp = load_reg(s, rn);
3299 gen_mov_vreg_F0(0, rm);
3300 tmp = load_reg(s, rd);
3302 gen_mov_vreg_F0(0, rm + 1);
3307 rn = (insn >> 16) & 0xf;
3309 VFP_DREG_D(rd, insn);
3311 rd = VFP_SREG_D(insn);
3312 if (s->thumb && rn == 15) {
3313 gen_op_movl_T1_im(s->pc & ~2);
3315 gen_movl_T1_reg(s, rn);
3317 if ((insn & 0x01200000) == 0x01000000) {
3318 /* Single load/store */
3319 offset = (insn & 0xff) << 2;
3320 if ((insn & (1 << 23)) == 0)
3322 gen_op_addl_T1_im(offset);
3323 if (insn & (1 << 20)) {
3325 gen_mov_vreg_F0(dp, rd);
3327 gen_mov_F0_vreg(dp, rd);
3331 /* load/store multiple */
3333 n = (insn >> 1) & 0x7f;
3337 if (insn & (1 << 24)) /* pre-decrement */
3338 gen_op_addl_T1_im(-((insn & 0xff) << 2));
3344 for (i = 0; i < n; i++) {
3345 if (insn & ARM_CP_RW_BIT) {
3348 gen_mov_vreg_F0(dp, rd + i);
3351 gen_mov_F0_vreg(dp, rd + i);
3354 gen_op_addl_T1_im(offset);
3356 if (insn & (1 << 21)) {
3358 if (insn & (1 << 24))
3359 offset = -offset * n;
3360 else if (dp && (insn & 1))
3366 gen_op_addl_T1_im(offset);
3367 gen_movl_reg_T1(s, rn);
3373 /* Should never happen. */
3379 static inline void gen_goto_tb(DisasContext *s, int n, uint32_t dest)
3381 TranslationBlock *tb;
3384 if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK)) {
3386 gen_set_pc_im(dest);
3387 tcg_gen_exit_tb((long)tb + n);
3389 gen_set_pc_im(dest);
3394 static inline void gen_jmp (DisasContext *s, uint32_t dest)
3396 if (__builtin_expect(s->singlestep_enabled, 0)) {
3397 /* An indirect jump so that we still trigger the debug exception. */
3402 gen_goto_tb(s, 0, dest);
3403 s->is_jmp = DISAS_TB_JUMP;
3407 static inline void gen_mulxy(TCGv t0, TCGv t1, int x, int y)
3410 tcg_gen_sari_i32(t0, t0, 16);
3414 tcg_gen_sari_i32(t1, t1, 16);
3417 tcg_gen_mul_i32(t0, t0, t1);
3420 /* Return the mask of PSR bits set by a MSR instruction. */
3421 static uint32_t msr_mask(CPUState *env, DisasContext *s, int flags, int spsr) {
3425 if (flags & (1 << 0))
3427 if (flags & (1 << 1))
3429 if (flags & (1 << 2))
3431 if (flags & (1 << 3))
3434 /* Mask out undefined bits. */
3435 mask &= ~CPSR_RESERVED;
3436 if (!arm_feature(env, ARM_FEATURE_V6))
3437 mask &= ~(CPSR_E | CPSR_GE);
3438 if (!arm_feature(env, ARM_FEATURE_THUMB2))
3440 /* Mask out execution state bits. */
3443 /* Mask out privileged bits. */
3449 /* Returns nonzero if access to the PSR is not permitted. */
3450 static int gen_set_psr_T0(DisasContext *s, uint32_t mask, int spsr)
3454 /* ??? This is also undefined in system mode. */
3458 tmp = load_cpu_field(spsr);
3459 tcg_gen_andi_i32(tmp, tmp, ~mask);
3460 tcg_gen_andi_i32(cpu_T[0], cpu_T[0], mask);
3461 tcg_gen_or_i32(tmp, tmp, cpu_T[0]);
3462 store_cpu_field(tmp, spsr);
3464 gen_set_cpsr(cpu_T[0], mask);
3470 /* Generate an old-style exception return. */
3471 static void gen_exception_return(DisasContext *s)
3474 gen_movl_reg_T0(s, 15);
3475 tmp = load_cpu_field(spsr);
3476 gen_set_cpsr(tmp, 0xffffffff);
3478 s->is_jmp = DISAS_UPDATE;
3481 /* Generate a v6 exception return. Marks both values as dead. */
3482 static void gen_rfe(DisasContext *s, TCGv pc, TCGv cpsr)
3484 gen_set_cpsr(cpsr, 0xffffffff);
3486 store_reg(s, 15, pc);
3487 s->is_jmp = DISAS_UPDATE;
3491 gen_set_condexec (DisasContext *s)
3493 if (s->condexec_mask) {
3494 uint32_t val = (s->condexec_cond << 4) | (s->condexec_mask >> 1);
3495 TCGv tmp = new_tmp();
3496 tcg_gen_movi_i32(tmp, val);
3497 store_cpu_field(tmp, condexec_bits);
3501 static void gen_nop_hint(DisasContext *s, int val)
3505 gen_set_pc_im(s->pc);
3506 s->is_jmp = DISAS_WFI;
3510 /* TODO: Implement SEV and WFE. May help SMP performance. */
3516 /* These macros help make the code more readable when migrating from the
3517 old dyngen helpers. They should probably be removed when
3518 T0/T1 are removed. */
3519 #define CPU_T001 cpu_T[0], cpu_T[0], cpu_T[1]
3520 #define CPU_T0E01 cpu_T[0], cpu_env, cpu_T[0], cpu_T[1]
3522 #define CPU_V001 cpu_V0, cpu_V0, cpu_V1
3524 static inline int gen_neon_add(int size)
3527 case 0: gen_helper_neon_add_u8(CPU_T001); break;
3528 case 1: gen_helper_neon_add_u16(CPU_T001); break;
3529 case 2: gen_op_addl_T0_T1(); break;
3535 static inline void gen_neon_rsb(int size)
3538 case 0: gen_helper_neon_sub_u8(cpu_T[0], cpu_T[1], cpu_T[0]); break;
3539 case 1: gen_helper_neon_sub_u16(cpu_T[0], cpu_T[1], cpu_T[0]); break;
3540 case 2: gen_op_rsbl_T0_T1(); break;
3545 /* 32-bit pairwise ops end up the same as the elementwise versions. */
3546 #define gen_helper_neon_pmax_s32 gen_helper_neon_max_s32
3547 #define gen_helper_neon_pmax_u32 gen_helper_neon_max_u32
3548 #define gen_helper_neon_pmin_s32 gen_helper_neon_min_s32
3549 #define gen_helper_neon_pmin_u32 gen_helper_neon_min_u32
3551 /* FIXME: This is wrong. They set the wrong overflow bit. */
3552 #define gen_helper_neon_qadd_s32(a, e, b, c) gen_helper_add_saturate(a, b, c)
3553 #define gen_helper_neon_qadd_u32(a, e, b, c) gen_helper_add_usaturate(a, b, c)
3554 #define gen_helper_neon_qsub_s32(a, e, b, c) gen_helper_sub_saturate(a, b, c)
3555 #define gen_helper_neon_qsub_u32(a, e, b, c) gen_helper_sub_usaturate(a, b, c)
3557 #define GEN_NEON_INTEGER_OP_ENV(name) do { \
3558 switch ((size << 1) | u) { \
3560 gen_helper_neon_##name##_s8(cpu_T[0], cpu_env, cpu_T[0], cpu_T[1]); \
3563 gen_helper_neon_##name##_u8(cpu_T[0], cpu_env, cpu_T[0], cpu_T[1]); \
3566 gen_helper_neon_##name##_s16(cpu_T[0], cpu_env, cpu_T[0], cpu_T[1]); \
3569 gen_helper_neon_##name##_u16(cpu_T[0], cpu_env, cpu_T[0], cpu_T[1]); \
3572 gen_helper_neon_##name##_s32(cpu_T[0], cpu_env, cpu_T[0], cpu_T[1]); \
3575 gen_helper_neon_##name##_u32(cpu_T[0], cpu_env, cpu_T[0], cpu_T[1]); \
3577 default: return 1; \
3580 #define GEN_NEON_INTEGER_OP(name) do { \
3581 switch ((size << 1) | u) { \
3583 gen_helper_neon_##name##_s8(cpu_T[0], cpu_T[0], cpu_T[1]); \
3586 gen_helper_neon_##name##_u8(cpu_T[0], cpu_T[0], cpu_T[1]); \
3589 gen_helper_neon_##name##_s16(cpu_T[0], cpu_T[0], cpu_T[1]); \
3592 gen_helper_neon_##name##_u16(cpu_T[0], cpu_T[0], cpu_T[1]); \
3595 gen_helper_neon_##name##_s32(cpu_T[0], cpu_T[0], cpu_T[1]); \
3598 gen_helper_neon_##name##_u32(cpu_T[0], cpu_T[0], cpu_T[1]); \
3600 default: return 1; \
3604 gen_neon_movl_scratch_T0(int scratch)
3608 offset = offsetof(CPUARMState, vfp.scratch[scratch]);
3609 tcg_gen_st_i32(cpu_T[0], cpu_env, offset);
3613 gen_neon_movl_scratch_T1(int scratch)
3617 offset = offsetof(CPUARMState, vfp.scratch[scratch]);
3618 tcg_gen_st_i32(cpu_T[1], cpu_env, offset);
3622 gen_neon_movl_T0_scratch(int scratch)
3626 offset = offsetof(CPUARMState, vfp.scratch[scratch]);
3627 tcg_gen_ld_i32(cpu_T[0], cpu_env, offset);
3631 gen_neon_movl_T1_scratch(int scratch)
3635 offset = offsetof(CPUARMState, vfp.scratch[scratch]);
3636 tcg_gen_ld_i32(cpu_T[1], cpu_env, offset);
3639 static inline void gen_neon_get_scalar(int size, int reg)
3642 NEON_GET_REG(T0, reg >> 1, reg & 1);
3644 NEON_GET_REG(T0, reg >> 2, (reg >> 1) & 1);
3646 gen_neon_dup_low16(cpu_T[0]);
3648 gen_neon_dup_high16(cpu_T[0]);
3652 static void gen_neon_unzip(int reg, int q, int tmp, int size)
3656 for (n = 0; n < q + 1; n += 2) {
3657 NEON_GET_REG(T0, reg, n);
3658 NEON_GET_REG(T0, reg, n + n);
3660 case 0: gen_helper_neon_unzip_u8(); break;
3661 case 1: gen_helper_neon_zip_u16(); break; /* zip and unzip are the same. */
3662 case 2: /* no-op */; break;
3665 gen_neon_movl_scratch_T0(tmp + n);
3666 gen_neon_movl_scratch_T1(tmp + n + 1);
3674 } neon_ls_element_type[11] = {
3688 /* Translate a NEON load/store element instruction. Return nonzero if the
3689 instruction is invalid. */
3690 static int disas_neon_ls_insn(CPUState * env, DisasContext *s, uint32_t insn)
3706 if (!vfp_enabled(env))
3708 VFP_DREG_D(rd, insn);
3709 rn = (insn >> 16) & 0xf;
3711 load = (insn & (1 << 21)) != 0;
3712 if ((insn & (1 << 23)) == 0) {
3713 /* Load store all elements. */
3714 op = (insn >> 8) & 0xf;
3715 size = (insn >> 6) & 3;
3716 if (op > 10 || size == 3)
3718 nregs = neon_ls_element_type[op].nregs;
3719 interleave = neon_ls_element_type[op].interleave;
3720 gen_movl_T1_reg(s, rn);
3721 stride = (1 << size) * interleave;
3722 for (reg = 0; reg < nregs; reg++) {
3723 if (interleave > 2 || (interleave == 2 && nregs == 2)) {
3724 gen_movl_T1_reg(s, rn);
3725 gen_op_addl_T1_im((1 << size) * reg);
3726 } else if (interleave == 2 && nregs == 4 && reg == 2) {
3727 gen_movl_T1_reg(s, rn);
3728 gen_op_addl_T1_im(1 << size);
3730 for (pass = 0; pass < 2; pass++) {
3733 tmp = gen_ld32(cpu_T[1], IS_USER(s));
3734 neon_store_reg(rd, pass, tmp);
3736 tmp = neon_load_reg(rd, pass);
3737 gen_st32(tmp, cpu_T[1], IS_USER(s));
3739 gen_op_addl_T1_im(stride);
3740 } else if (size == 1) {
3742 tmp = gen_ld16u(cpu_T[1], IS_USER(s));
3743 gen_op_addl_T1_im(stride);
3744 tmp2 = gen_ld16u(cpu_T[1], IS_USER(s));
3745 gen_op_addl_T1_im(stride);
3746 gen_bfi(tmp, tmp, tmp2, 16, 0xffff);
3748 neon_store_reg(rd, pass, tmp);
3750 tmp = neon_load_reg(rd, pass);
3752 tcg_gen_shri_i32(tmp2, tmp, 16);
3753 gen_st16(tmp, cpu_T[1], IS_USER(s));
3754 gen_op_addl_T1_im(stride);
3755 gen_st16(tmp2, cpu_T[1], IS_USER(s));
3756 gen_op_addl_T1_im(stride);
3758 } else /* size == 0 */ {
3760 for (n = 0; n < 4; n++) {
3761 tmp = gen_ld8u(cpu_T[1], IS_USER(s));
3762 gen_op_addl_T1_im(stride);
3766 gen_bfi(tmp2, tmp2, tmp, n * 8, 0xff);
3770 neon_store_reg(rd, pass, tmp2);
3772 tmp2 = neon_load_reg(rd, pass);
3773 for (n = 0; n < 4; n++) {
3776 tcg_gen_mov_i32(tmp, tmp2);
3778 tcg_gen_shri_i32(tmp, tmp2, n * 8);
3780 gen_st8(tmp, cpu_T[1], IS_USER(s));
3781 gen_op_addl_T1_im(stride);
3787 rd += neon_ls_element_type[op].spacing;
3791 size = (insn >> 10) & 3;
3793 /* Load single element to all lanes. */
3796 size = (insn >> 6) & 3;
3797 nregs = ((insn >> 8) & 3) + 1;
3798 stride = (insn & (1 << 5)) ? 2 : 1;
3799 gen_movl_T1_reg(s, rn);
3800 for (reg = 0; reg < nregs; reg++) {
3803 tmp = gen_ld8u(cpu_T[1], IS_USER(s));
3804 gen_neon_dup_u8(tmp, 0);
3807 tmp = gen_ld16u(cpu_T[1], IS_USER(s));
3808 gen_neon_dup_low16(tmp);
3811 tmp = gen_ld32(cpu_T[0], IS_USER(s));
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));
3859 tmp2 = neon_load_reg(rd, pass);
3860 gen_bfi(tmp, tmp2, tmp, shift, size ? 0xffff : 0xff);
3863 neon_store_reg(rd, pass, tmp);
3864 } else { /* Store */
3865 tmp = neon_load_reg(rd, pass);
3867 tcg_gen_shri_i32(tmp, tmp, shift);
3870 gen_st8(tmp, cpu_T[1], IS_USER(s));
3873 gen_st16(tmp, cpu_T[1], IS_USER(s));
3876 gen_st32(tmp, cpu_T[1], IS_USER(s));
3881 gen_op_addl_T1_im(1 << size);
3883 stride = nregs * (1 << size);
3889 base = load_reg(s, rn);
3891 tcg_gen_addi_i32(base, base, stride);
3894 index = load_reg(s, rm);
3895 tcg_gen_add_i32(base, base, index);
3898 store_reg(s, rn, base);
3903 /* Bitwise select. dest = c ? t : f. Clobbers T and F. */
3904 static void gen_neon_bsl(TCGv dest, TCGv t, TCGv f, TCGv c)
3906 tcg_gen_and_i32(t, t, c);
3907 tcg_gen_bic_i32(f, f, c);
3908 tcg_gen_or_i32(dest, t, f);
3911 static inline void gen_neon_narrow(int size, TCGv dest, TCGv src)
3914 case 0: gen_helper_neon_narrow_u8(dest, src); break;
3915 case 1: gen_helper_neon_narrow_u16(dest, src); break;
3916 case 2: tcg_gen_trunc_i64_i32(dest, src); break;
3921 static inline void gen_neon_narrow_sats(int size, TCGv dest, TCGv src)
3924 case 0: gen_helper_neon_narrow_sat_s8(dest, cpu_env, src); break;
3925 case 1: gen_helper_neon_narrow_sat_s16(dest, cpu_env, src); break;
3926 case 2: gen_helper_neon_narrow_sat_s32(dest, cpu_env, src); break;
3931 static inline void gen_neon_narrow_satu(int size, TCGv dest, TCGv src)
3934 case 0: gen_helper_neon_narrow_sat_u8(dest, cpu_env, src); break;
3935 case 1: gen_helper_neon_narrow_sat_u16(dest, cpu_env, src); break;
3936 case 2: gen_helper_neon_narrow_sat_u32(dest, cpu_env, src); break;
3941 static inline void gen_neon_shift_narrow(int size, TCGv var, TCGv shift,
3947 case 1: gen_helper_neon_rshl_u16(var, var, shift); break;
3948 case 2: gen_helper_neon_rshl_u32(var, var, shift); break;
3953 case 1: gen_helper_neon_rshl_s16(var, var, shift); break;
3954 case 2: gen_helper_neon_rshl_s32(var, var, shift); break;
3961 case 1: gen_helper_neon_rshl_u16(var, var, shift); break;
3962 case 2: gen_helper_neon_rshl_u32(var, var, shift); break;
3967 case 1: gen_helper_neon_shl_s16(var, var, shift); break;
3968 case 2: gen_helper_neon_shl_s32(var, var, shift); break;
3975 static inline void gen_neon_widen(TCGv dest, TCGv src, int size, int u)
3979 case 0: gen_helper_neon_widen_u8(dest, src); break;
3980 case 1: gen_helper_neon_widen_u16(dest, src); break;
3981 case 2: tcg_gen_extu_i32_i64(dest, src); break;
3986 case 0: gen_helper_neon_widen_s8(dest, src); break;
3987 case 1: gen_helper_neon_widen_s16(dest, src); break;
3988 case 2: tcg_gen_ext_i32_i64(dest, src); break;
3995 static inline void gen_neon_addl(int size)
3998 case 0: gen_helper_neon_addl_u16(CPU_V001); break;
3999 case 1: gen_helper_neon_addl_u32(CPU_V001); break;
4000 case 2: tcg_gen_add_i64(CPU_V001); break;
4005 static inline void gen_neon_subl(int size)
4008 case 0: gen_helper_neon_subl_u16(CPU_V001); break;
4009 case 1: gen_helper_neon_subl_u32(CPU_V001); break;
4010 case 2: tcg_gen_sub_i64(CPU_V001); break;
4015 static inline void gen_neon_negl(TCGv var, int size)
4018 case 0: gen_helper_neon_negl_u16(var, var); break;
4019 case 1: gen_helper_neon_negl_u32(var, var); break;
4020 case 2: gen_helper_neon_negl_u64(var, var); break;
4025 static inline void gen_neon_addl_saturate(TCGv op0, TCGv op1, int size)
4028 case 1: gen_helper_neon_addl_saturate_s32(op0, cpu_env, op0, op1); break;
4029 case 2: gen_helper_neon_addl_saturate_s64(op0, cpu_env, op0, op1); break;
4034 static inline void gen_neon_mull(TCGv dest, TCGv a, TCGv b, int size, int u)
4038 switch ((size << 1) | u) {
4039 case 0: gen_helper_neon_mull_s8(dest, a, b); break;
4040 case 1: gen_helper_neon_mull_u8(dest, a, b); break;
4041 case 2: gen_helper_neon_mull_s16(dest, a, b); break;
4042 case 3: gen_helper_neon_mull_u16(dest, a, b); break;
4044 tmp = gen_muls_i64_i32(a, b);
4045 tcg_gen_mov_i64(dest, tmp);
4048 tmp = gen_mulu_i64_i32(a, b);
4049 tcg_gen_mov_i64(dest, tmp);
4059 /* Translate a NEON data processing instruction. Return nonzero if the
4060 instruction is invalid.
4061 We process data in a mixture of 32-bit and 64-bit chunks.
4062 Mostly we use 32-bit chunks so we can use normal scalar instructions. */
4064 static int disas_neon_data_insn(CPUState * env, DisasContext *s, uint32_t insn)
4081 if (!vfp_enabled(env))
4083 q = (insn & (1 << 6)) != 0;
4084 u = (insn >> 24) & 1;
4085 VFP_DREG_D(rd, insn);
4086 VFP_DREG_N(rn, insn);
4087 VFP_DREG_M(rm, insn);
4088 size = (insn >> 20) & 3;
4089 if ((insn & (1 << 23)) == 0) {
4090 /* Three register same length. */
4091 op = ((insn >> 7) & 0x1e) | ((insn >> 4) & 1);
4092 if (size == 3 && (op == 1 || op == 5 || op == 8 || op == 9
4093 || op == 10 || op == 11 || op == 16)) {
4094 /* 64-bit element instructions. */
4095 for (pass = 0; pass < (q ? 2 : 1); pass++) {
4096 neon_load_reg64(cpu_V0, rn + pass);
4097 neon_load_reg64(cpu_V1, rm + pass);
4101 gen_helper_neon_add_saturate_u64(CPU_V001);
4103 gen_helper_neon_add_saturate_s64(CPU_V001);
4108 gen_helper_neon_sub_saturate_u64(CPU_V001);
4110 gen_helper_neon_sub_saturate_s64(CPU_V001);
4115 gen_helper_neon_shl_u64(cpu_V0, cpu_V1, cpu_V0);
4117 gen_helper_neon_shl_s64(cpu_V0, cpu_V1, cpu_V0);
4122 gen_helper_neon_qshl_u64(cpu_V0, cpu_env,
4125 gen_helper_neon_qshl_s64(cpu_V1, cpu_env,
4129 case 10: /* VRSHL */
4131 gen_helper_neon_rshl_u64(cpu_V0, cpu_V1, cpu_V0);
4133 gen_helper_neon_rshl_s64(cpu_V0, cpu_V1, cpu_V0);
4136 case 11: /* VQRSHL */
4138 gen_helper_neon_qrshl_u64(cpu_V0, cpu_env,
4141 gen_helper_neon_qrshl_s64(cpu_V0, cpu_env,
4147 tcg_gen_sub_i64(CPU_V001);
4149 tcg_gen_add_i64(CPU_V001);
4155 neon_store_reg64(cpu_V0, rd + pass);
4162 case 10: /* VRSHL */
4163 case 11: /* VQRSHL */
4166 /* Shift instruction operands are reversed. */
4173 case 20: /* VPMAX */
4174 case 21: /* VPMIN */
4175 case 23: /* VPADD */
4178 case 26: /* VPADD (float) */
4179 pairwise = (u && size < 2);
4181 case 30: /* VPMIN/VPMAX (float) */
4188 for (pass = 0; pass < (q ? 4 : 2); pass++) {
4197 NEON_GET_REG(T0, rn, n);
4198 NEON_GET_REG(T1, rn, n + 1);
4200 NEON_GET_REG(T0, rm, n);
4201 NEON_GET_REG(T1, rm, n + 1);
4205 NEON_GET_REG(T0, rn, pass);
4206 NEON_GET_REG(T1, rm, pass);
4210 GEN_NEON_INTEGER_OP(hadd);
4213 GEN_NEON_INTEGER_OP_ENV(qadd);
4215 case 2: /* VRHADD */
4216 GEN_NEON_INTEGER_OP(rhadd);
4218 case 3: /* Logic ops. */
4219 switch ((u << 2) | size) {
4221 gen_op_andl_T0_T1();
4224 gen_op_bicl_T0_T1();
4234 gen_op_xorl_T0_T1();
4237 tmp = neon_load_reg(rd, pass);
4238 gen_neon_bsl(cpu_T[0], cpu_T[0], cpu_T[1], tmp);
4242 tmp = neon_load_reg(rd, pass);
4243 gen_neon_bsl(cpu_T[0], cpu_T[0], tmp, cpu_T[1]);
4247 tmp = neon_load_reg(rd, pass);
4248 gen_neon_bsl(cpu_T[0], tmp, cpu_T[0], cpu_T[1]);
4254 GEN_NEON_INTEGER_OP(hsub);
4257 GEN_NEON_INTEGER_OP_ENV(qsub);
4260 GEN_NEON_INTEGER_OP(cgt);
4263 GEN_NEON_INTEGER_OP(cge);
4266 GEN_NEON_INTEGER_OP(shl);
4269 GEN_NEON_INTEGER_OP_ENV(qshl);
4271 case 10: /* VRSHL */
4272 GEN_NEON_INTEGER_OP(rshl);
4274 case 11: /* VQRSHL */
4275 GEN_NEON_INTEGER_OP_ENV(qrshl);
4278 GEN_NEON_INTEGER_OP(max);
4281 GEN_NEON_INTEGER_OP(min);
4284 GEN_NEON_INTEGER_OP(abd);
4287 GEN_NEON_INTEGER_OP(abd);
4288 NEON_GET_REG(T1, rd, pass);
4292 if (!u) { /* VADD */
4293 if (gen_neon_add(size))
4297 case 0: gen_helper_neon_sub_u8(CPU_T001); break;
4298 case 1: gen_helper_neon_sub_u16(CPU_T001); break;
4299 case 2: gen_op_subl_T0_T1(); break;
4305 if (!u) { /* VTST */
4307 case 0: gen_helper_neon_tst_u8(CPU_T001); break;
4308 case 1: gen_helper_neon_tst_u16(CPU_T001); break;
4309 case 2: gen_helper_neon_tst_u32(CPU_T001); break;
4314 case 0: gen_helper_neon_ceq_u8(CPU_T001); break;
4315 case 1: gen_helper_neon_ceq_u16(CPU_T001); break;
4316 case 2: gen_helper_neon_ceq_u32(CPU_T001); break;
4321 case 18: /* Multiply. */
4323 case 0: gen_helper_neon_mul_u8(CPU_T001); break;
4324 case 1: gen_helper_neon_mul_u16(CPU_T001); break;
4325 case 2: gen_op_mul_T0_T1(); break;
4328 NEON_GET_REG(T1, rd, pass);
4336 if (u) { /* polynomial */
4337 gen_helper_neon_mul_p8(CPU_T001);
4338 } else { /* Integer */
4340 case 0: gen_helper_neon_mul_u8(CPU_T001); break;
4341 case 1: gen_helper_neon_mul_u16(CPU_T001); break;
4342 case 2: gen_op_mul_T0_T1(); break;
4347 case 20: /* VPMAX */
4348 GEN_NEON_INTEGER_OP(pmax);
4350 case 21: /* VPMIN */
4351 GEN_NEON_INTEGER_OP(pmin);
4353 case 22: /* Hultiply high. */
4354 if (!u) { /* VQDMULH */
4356 case 1: gen_helper_neon_qdmulh_s16(CPU_T0E01); break;
4357 case 2: gen_helper_neon_qdmulh_s32(CPU_T0E01); break;
4360 } else { /* VQRDHMUL */
4362 case 1: gen_helper_neon_qrdmulh_s16(CPU_T0E01); break;
4363 case 2: gen_helper_neon_qrdmulh_s32(CPU_T0E01); break;
4368 case 23: /* VPADD */
4372 case 0: gen_helper_neon_padd_u8(CPU_T001); break;
4373 case 1: gen_helper_neon_padd_u16(CPU_T001); break;
4374 case 2: gen_op_addl_T0_T1(); break;
4378 case 26: /* Floating point arithnetic. */
4379 switch ((u << 2) | size) {
4381 gen_helper_neon_add_f32(CPU_T001);
4384 gen_helper_neon_sub_f32(CPU_T001);
4387 gen_helper_neon_add_f32(CPU_T001);
4390 gen_helper_neon_abd_f32(CPU_T001);
4396 case 27: /* Float multiply. */
4397 gen_helper_neon_mul_f32(CPU_T001);
4399 NEON_GET_REG(T1, rd, pass);
4401 gen_helper_neon_add_f32(CPU_T001);
4403 gen_helper_neon_sub_f32(cpu_T[0], cpu_T[1], cpu_T[0]);
4407 case 28: /* Float compare. */
4409 gen_helper_neon_ceq_f32(CPU_T001);
4412 gen_helper_neon_cge_f32(CPU_T001);
4414 gen_helper_neon_cgt_f32(CPU_T001);
4417 case 29: /* Float compare absolute. */
4421 gen_helper_neon_acge_f32(CPU_T001);
4423 gen_helper_neon_acgt_f32(CPU_T001);
4425 case 30: /* Float min/max. */
4427 gen_helper_neon_max_f32(CPU_T001);
4429 gen_helper_neon_min_f32(CPU_T001);
4433 gen_helper_recps_f32(cpu_T[0], cpu_T[0], cpu_T[1], cpu_env);
4435 gen_helper_rsqrts_f32(cpu_T[0], cpu_T[0], cpu_T[1], cpu_env);
4440 /* Save the result. For elementwise operations we can put it
4441 straight into the destination register. For pairwise operations
4442 we have to be careful to avoid clobbering the source operands. */
4443 if (pairwise && rd == rm) {
4444 gen_neon_movl_scratch_T0(pass);
4446 NEON_SET_REG(T0, rd, pass);
4450 if (pairwise && rd == rm) {
4451 for (pass = 0; pass < (q ? 4 : 2); pass++) {
4452 gen_neon_movl_T0_scratch(pass);
4453 NEON_SET_REG(T0, rd, pass);
4456 /* End of 3 register same size operations. */
4457 } else if (insn & (1 << 4)) {
4458 if ((insn & 0x00380080) != 0) {
4459 /* Two registers and shift. */
4460 op = (insn >> 8) & 0xf;
4461 if (insn & (1 << 7)) {
4466 while ((insn & (1 << (size + 19))) == 0)
4469 shift = (insn >> 16) & ((1 << (3 + size)) - 1);
4470 /* To avoid excessive dumplication of ops we implement shift
4471 by immediate using the variable shift operations. */
4473 /* Shift by immediate:
4474 VSHR, VSRA, VRSHR, VRSRA, VSRI, VSHL, VQSHL, VQSHLU. */
4475 /* Right shifts are encoded as N - shift, where N is the
4476 element size in bits. */
4478 shift = shift - (1 << (size + 3));
4486 imm = (uint8_t) shift;
4491 imm = (uint16_t) shift;
4502 for (pass = 0; pass < count; pass++) {
4504 neon_load_reg64(cpu_V0, rm + pass);
4505 tcg_gen_movi_i64(cpu_V1, imm);
4510 gen_helper_neon_shl_u64(cpu_V0, cpu_V0, cpu_V1);
4512 gen_helper_neon_shl_s64(cpu_V0, cpu_V0, cpu_V1);
4517 gen_helper_neon_rshl_u64(cpu_V0, cpu_V0, cpu_V1);
4519 gen_helper_neon_rshl_s64(cpu_V0, cpu_V0, cpu_V1);
4524 gen_helper_neon_shl_u64(cpu_V0, cpu_V0, cpu_V1);
4526 case 5: /* VSHL, VSLI */
4527 gen_helper_neon_shl_u64(cpu_V0, cpu_V0, cpu_V1);
4531 gen_helper_neon_qshl_u64(cpu_V0, cpu_env, cpu_V0, cpu_V1);
4533 gen_helper_neon_qshl_s64(cpu_V0, cpu_env, cpu_V0, cpu_V1);
4535 case 7: /* VQSHLU */
4536 gen_helper_neon_qshl_u64(cpu_V0, cpu_env, cpu_V0, cpu_V1);
4539 if (op == 1 || op == 3) {
4541 neon_load_reg64(cpu_V0, rd + pass);
4542 tcg_gen_add_i64(cpu_V0, cpu_V0, cpu_V1);
4543 } else if (op == 4 || (op == 5 && u)) {
4545 cpu_abort(env, "VS[LR]I.64 not implemented");
4547 neon_store_reg64(cpu_V0, rd + pass);
4548 } else { /* size < 3 */
4549 /* Operands in T0 and T1. */
4550 gen_op_movl_T1_im(imm);
4551 NEON_GET_REG(T0, rm, pass);
4555 GEN_NEON_INTEGER_OP(shl);
4559 GEN_NEON_INTEGER_OP(rshl);
4564 GEN_NEON_INTEGER_OP(shl);
4566 case 5: /* VSHL, VSLI */
4568 case 0: gen_helper_neon_shl_u8(CPU_T001); break;
4569 case 1: gen_helper_neon_shl_u16(CPU_T001); break;
4570 case 2: gen_helper_neon_shl_u32(CPU_T001); break;
4575 GEN_NEON_INTEGER_OP_ENV(qshl);
4577 case 7: /* VQSHLU */
4579 case 0: gen_helper_neon_qshl_u8(CPU_T0E01); break;
4580 case 1: gen_helper_neon_qshl_u16(CPU_T0E01); break;
4581 case 2: gen_helper_neon_qshl_u32(CPU_T0E01); break;
4587 if (op == 1 || op == 3) {
4589 NEON_GET_REG(T1, rd, pass);
4591 } else if (op == 4 || (op == 5 && u)) {
4596 imm = 0xff >> -shift;
4598 imm = (uint8_t)(0xff << shift);
4604 imm = 0xffff >> -shift;
4606 imm = (uint16_t)(0xffff << shift);
4611 imm = 0xffffffffu >> -shift;
4613 imm = 0xffffffffu << shift;
4618 tmp = neon_load_reg(rd, pass);
4619 tcg_gen_andi_i32(cpu_T[0], cpu_T[0], imm);
4620 tcg_gen_andi_i32(tmp, tmp, ~imm);
4621 tcg_gen_or_i32(cpu_T[0], cpu_T[0], tmp);
4623 NEON_SET_REG(T0, rd, pass);
4626 } else if (op < 10) {
4627 /* Shift by immediate and narrow:
4628 VSHRN, VRSHRN, VQSHRN, VQRSHRN. */
4629 shift = shift - (1 << (size + 3));
4633 imm = (uint16_t)shift;
4635 tmp2 = tcg_const_i32(imm);
4638 imm = (uint32_t)shift;
4639 tmp2 = tcg_const_i32(imm);
4641 tmp2 = tcg_const_i64(shift);
4647 for (pass = 0; pass < 2; pass++) {
4649 neon_load_reg64(cpu_V0, rm + pass);
4652 gen_helper_neon_rshl_u64(cpu_V0, cpu_V0, tmp2);
4654 gen_helper_neon_rshl_s64(cpu_V0, cpu_V0, tmp2);
4657 gen_helper_neon_shl_u64(cpu_V0, cpu_V0, tmp2);
4659 gen_helper_neon_shl_s64(cpu_V0, cpu_V0, tmp2);
4662 tmp = neon_load_reg(rm + pass, 0);
4663 gen_neon_shift_narrow(size, tmp, tmp2, q, u);
4664 tcg_gen_extu_i32_i64(cpu_V0, tmp);
4666 tmp = neon_load_reg(rm + pass, 1);
4667 gen_neon_shift_narrow(size, tmp, tmp2, q, u);
4668 tcg_gen_extu_i32_i64(cpu_V1, tmp);
4670 tcg_gen_shli_i64(cpu_V1, cpu_V1, 32);
4671 tcg_gen_or_i64(cpu_V0, cpu_V0, cpu_V1);
4674 if (op == 8 && !u) {
4675 gen_neon_narrow(size - 1, tmp, cpu_V0);
4678 gen_neon_narrow_sats(size - 1, tmp, cpu_V0);
4680 gen_neon_narrow_satu(size - 1, tmp, cpu_V0);
4685 neon_store_reg(rd, 0, tmp2);
4686 neon_store_reg(rd, 1, tmp);
4689 } else if (op == 10) {
4693 tmp = neon_load_reg(rm, 0);
4694 tmp2 = neon_load_reg(rm, 1);
4695 for (pass = 0; pass < 2; pass++) {
4699 gen_neon_widen(cpu_V0, tmp, size, u);
4702 /* The shift is less than the width of the source
4703 type, so we can just shift the whole register. */
4704 tcg_gen_shli_i64(cpu_V0, cpu_V0, shift);
4705 if (size < 2 || !u) {
4708 imm = (0xffu >> (8 - shift));
4711 imm = 0xffff >> (16 - shift);
4713 imm64 = imm | (((uint64_t)imm) << 32);
4714 tcg_gen_andi_i64(cpu_V0, cpu_V0, imm64);
4717 neon_store_reg64(cpu_V0, rd + pass);
4719 } else if (op == 15 || op == 16) {
4720 /* VCVT fixed-point. */
4721 for (pass = 0; pass < (q ? 4 : 2); pass++) {
4722 tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, pass));
4725 gen_vfp_ulto(0, shift);
4727 gen_vfp_slto(0, shift);
4730 gen_vfp_toul(0, shift);
4732 gen_vfp_tosl(0, shift);
4734 tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, pass));
4739 } else { /* (insn & 0x00380080) == 0 */
4742 op = (insn >> 8) & 0xf;
4743 /* One register and immediate. */
4744 imm = (u << 7) | ((insn >> 12) & 0x70) | (insn & 0xf);
4745 invert = (insn & (1 << 5)) != 0;
4763 imm = (imm << 8) | (imm << 24);
4766 imm = (imm < 8) | 0xff;
4769 imm = (imm << 16) | 0xffff;
4772 imm |= (imm << 8) | (imm << 16) | (imm << 24);
4777 imm = ((imm & 0x80) << 24) | ((imm & 0x3f) << 19)
4778 | ((imm & 0x40) ? (0x1f << 25) : (1 << 30));
4784 if (op != 14 || !invert)
4785 gen_op_movl_T1_im(imm);
4787 for (pass = 0; pass < (q ? 4 : 2); pass++) {
4788 if (op & 1 && op < 12) {
4789 tmp = neon_load_reg(rd, pass);
4791 /* The immediate value has already been inverted, so
4793 tcg_gen_andi_i32(tmp, tmp, imm);
4795 tcg_gen_ori_i32(tmp, tmp, imm);
4800 if (op == 14 && invert) {
4803 for (n = 0; n < 4; n++) {
4804 if (imm & (1 << (n + (pass & 1) * 4)))
4805 val |= 0xff << (n * 8);
4807 tcg_gen_movi_i32(tmp, val);
4809 tcg_gen_movi_i32(tmp, imm);
4812 neon_store_reg(rd, pass, tmp);
4815 } else { /* (insn & 0x00800010 == 0x00800010) */
4817 op = (insn >> 8) & 0xf;
4818 if ((insn & (1 << 6)) == 0) {
4819 /* Three registers of different lengths. */
4823 /* prewiden, src1_wide, src2_wide */
4824 static const int neon_3reg_wide[16][3] = {
4825 {1, 0, 0}, /* VADDL */
4826 {1, 1, 0}, /* VADDW */
4827 {1, 0, 0}, /* VSUBL */
4828 {1, 1, 0}, /* VSUBW */
4829 {0, 1, 1}, /* VADDHN */
4830 {0, 0, 0}, /* VABAL */
4831 {0, 1, 1}, /* VSUBHN */
4832 {0, 0, 0}, /* VABDL */
4833 {0, 0, 0}, /* VMLAL */
4834 {0, 0, 0}, /* VQDMLAL */
4835 {0, 0, 0}, /* VMLSL */
4836 {0, 0, 0}, /* VQDMLSL */
4837 {0, 0, 0}, /* Integer VMULL */
4838 {0, 0, 0}, /* VQDMULL */
4839 {0, 0, 0} /* Polynomial VMULL */
4842 prewiden = neon_3reg_wide[op][0];
4843 src1_wide = neon_3reg_wide[op][1];
4844 src2_wide = neon_3reg_wide[op][2];
4846 if (size == 0 && (op == 9 || op == 11 || op == 13))
4849 /* Avoid overlapping operands. Wide source operands are
4850 always aligned so will never overlap with wide
4851 destinations in problematic ways. */
4852 if (rd == rm && !src2_wide) {
4853 NEON_GET_REG(T0, rm, 1);
4854 gen_neon_movl_scratch_T0(2);
4855 } else if (rd == rn && !src1_wide) {
4856 NEON_GET_REG(T0, rn, 1);
4857 gen_neon_movl_scratch_T0(2);
4859 for (pass = 0; pass < 2; pass++) {
4861 neon_load_reg64(cpu_V0, rn + pass);
4863 if (pass == 1 && rd == rn) {
4864 gen_neon_movl_T0_scratch(2);
4866 tcg_gen_mov_i32(tmp, cpu_T[0]);
4868 tmp = neon_load_reg(rn, pass);
4871 gen_neon_widen(cpu_V0, tmp, size, u);
4875 neon_load_reg64(cpu_V1, rm + pass);
4877 if (pass == 1 && rd == rm) {
4878 gen_neon_movl_T0_scratch(2);
4880 tcg_gen_mov_i32(tmp2, cpu_T[0]);
4882 tmp2 = neon_load_reg(rm, pass);
4885 gen_neon_widen(cpu_V1, tmp2, size, u);
4889 case 0: case 1: case 4: /* VADDL, VADDW, VADDHN, VRADDHN */
4890 gen_neon_addl(size);
4892 case 2: case 3: case 6: /* VSUBL, VSUBW, VSUBHL, VRSUBHL */
4893 gen_neon_subl(size);
4895 case 5: case 7: /* VABAL, VABDL */
4896 switch ((size << 1) | u) {
4898 gen_helper_neon_abdl_s16(cpu_V0, tmp, tmp2);
4901 gen_helper_neon_abdl_u16(cpu_V0, tmp, tmp2);
4904 gen_helper_neon_abdl_s32(cpu_V0, tmp, tmp2);
4907 gen_helper_neon_abdl_u32(cpu_V0, tmp, tmp2);
4910 gen_helper_neon_abdl_s64(cpu_V0, tmp, tmp2);
4913 gen_helper_neon_abdl_u64(cpu_V0, tmp, tmp2);
4920 case 8: case 9: case 10: case 11: case 12: case 13:
4921 /* VMLAL, VQDMLAL, VMLSL, VQDMLSL, VMULL, VQDMULL */
4922 gen_neon_mull(cpu_V0, tmp, tmp2, size, u);
4924 case 14: /* Polynomial VMULL */
4925 cpu_abort(env, "Polynomial VMULL not implemented");
4927 default: /* 15 is RESERVED. */
4930 if (op == 5 || op == 13 || (op >= 8 && op <= 11)) {
4932 if (op == 10 || op == 11) {
4933 gen_neon_negl(cpu_V0, size);
4937 neon_load_reg64(cpu_V1, rd + pass);
4941 case 5: case 8: case 10: /* VABAL, VMLAL, VMLSL */
4942 gen_neon_addl(size);
4944 case 9: case 11: /* VQDMLAL, VQDMLSL */
4945 gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
4946 gen_neon_addl_saturate(cpu_V0, cpu_V1, size);
4949 case 13: /* VQDMULL */
4950 gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
4955 neon_store_reg64(cpu_V0, rd + pass);
4956 } else if (op == 4 || op == 6) {
4957 /* Narrowing operation. */
4962 gen_helper_neon_narrow_high_u8(tmp, cpu_V0);
4965 gen_helper_neon_narrow_high_u16(tmp, cpu_V0);
4968 tcg_gen_shri_i64(cpu_V0, cpu_V0, 32);
4969 tcg_gen_trunc_i64_i32(tmp, cpu_V0);
4976 gen_helper_neon_narrow_round_high_u8(tmp, cpu_V0);
4979 gen_helper_neon_narrow_round_high_u16(tmp, cpu_V0);
4982 tcg_gen_addi_i64(cpu_V0, cpu_V0, 1u << 31);
4983 tcg_gen_shri_i64(cpu_V0, cpu_V0, 32);
4984 tcg_gen_trunc_i64_i32(tmp, cpu_V0);
4992 neon_store_reg(rd, 0, tmp3);
4993 neon_store_reg(rd, 1, tmp);
4996 /* Write back the result. */
4997 neon_store_reg64(cpu_V0, rd + pass);
5001 /* Two registers and a scalar. */
5003 case 0: /* Integer VMLA scalar */
5004 case 1: /* Float VMLA scalar */
5005 case 4: /* Integer VMLS scalar */
5006 case 5: /* Floating point VMLS scalar */
5007 case 8: /* Integer VMUL scalar */
5008 case 9: /* Floating point VMUL scalar */
5009 case 12: /* VQDMULH scalar */
5010 case 13: /* VQRDMULH scalar */
5011 gen_neon_get_scalar(size, rm);
5012 gen_neon_movl_scratch_T0(0);
5013 for (pass = 0; pass < (u ? 4 : 2); pass++) {
5015 gen_neon_movl_T0_scratch(0);
5016 NEON_GET_REG(T1, rn, pass);
5019 gen_helper_neon_qdmulh_s16(CPU_T0E01);
5021 gen_helper_neon_qdmulh_s32(CPU_T0E01);
5023 } else if (op == 13) {
5025 gen_helper_neon_qrdmulh_s16(CPU_T0E01);
5027 gen_helper_neon_qrdmulh_s32(CPU_T0E01);
5029 } else if (op & 1) {
5030 gen_helper_neon_mul_f32(CPU_T001);
5033 case 0: gen_helper_neon_mul_u8(CPU_T001); break;
5034 case 1: gen_helper_neon_mul_u16(CPU_T001); break;
5035 case 2: gen_op_mul_T0_T1(); break;
5041 NEON_GET_REG(T1, rd, pass);
5047 gen_helper_neon_add_f32(CPU_T001);
5053 gen_helper_neon_sub_f32(cpu_T[0], cpu_T[1], cpu_T[0]);
5059 NEON_SET_REG(T0, rd, pass);
5062 case 2: /* VMLAL sclar */
5063 case 3: /* VQDMLAL scalar */
5064 case 6: /* VMLSL scalar */
5065 case 7: /* VQDMLSL scalar */
5066 case 10: /* VMULL scalar */
5067 case 11: /* VQDMULL scalar */
5068 if (size == 0 && (op == 3 || op == 7 || op == 11))
5071 gen_neon_get_scalar(size, rm);
5072 NEON_GET_REG(T1, rn, 1);
5074 for (pass = 0; pass < 2; pass++) {
5076 tmp = neon_load_reg(rn, 0);
5079 tcg_gen_mov_i32(tmp, cpu_T[1]);
5082 tcg_gen_mov_i32(tmp2, cpu_T[0]);
5083 gen_neon_mull(cpu_V0, tmp, tmp2, size, u);
5084 if (op == 6 || op == 7) {
5085 gen_neon_negl(cpu_V0, size);
5088 neon_load_reg64(cpu_V1, rd + pass);
5092 gen_neon_addl(size);
5095 gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
5096 gen_neon_addl_saturate(cpu_V0, cpu_V1, size);
5102 gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
5107 neon_store_reg64(cpu_V0, rd + pass);
5110 default: /* 14 and 15 are RESERVED */
5114 } else { /* size == 3 */
5117 imm = (insn >> 8) & 0xf;
5124 neon_load_reg64(cpu_V0, rn);
5126 neon_load_reg64(cpu_V1, rn + 1);
5128 } else if (imm == 8) {
5129 neon_load_reg64(cpu_V0, rn + 1);
5131 neon_load_reg64(cpu_V1, rm);
5134 tmp = tcg_temp_new(TCG_TYPE_I64);
5136 neon_load_reg64(cpu_V0, rn);
5137 neon_load_reg64(tmp, rn + 1);
5139 neon_load_reg64(cpu_V0, rn + 1);
5140 neon_load_reg64(tmp, rm);
5142 tcg_gen_shri_i64(cpu_V0, cpu_V0, (imm & 7) * 8);
5143 tcg_gen_shli_i64(cpu_V1, tmp, 64 - ((imm & 7) * 8));
5144 tcg_gen_or_i64(cpu_V0, cpu_V0, cpu_V1);
5146 neon_load_reg64(cpu_V1, rm);
5148 neon_load_reg64(cpu_V1, rm + 1);
5151 tcg_gen_shli_i64(cpu_V1, cpu_V1, 64 - (imm * 8));
5152 tcg_gen_shri_i64(tmp, tmp, imm * 8);
5153 tcg_gen_or_i64(cpu_V1, cpu_V1, tmp);
5155 neon_load_reg64(cpu_V0, rn);
5156 tcg_gen_shri_i32(cpu_V0, cpu_V0, imm * 8);
5157 neon_load_reg64(cpu_V1, rm);
5158 tcg_gen_shli_i32(cpu_V1, cpu_V1, 64 - (imm * 8));
5159 tcg_gen_or_i64(cpu_V0, cpu_V0, cpu_V1);
5161 neon_store_reg64(cpu_V0, rd);
5163 neon_store_reg64(cpu_V1, rd + 1);
5165 } else if ((insn & (1 << 11)) == 0) {
5166 /* Two register misc. */
5167 op = ((insn >> 12) & 0x30) | ((insn >> 7) & 0xf);
5168 size = (insn >> 18) & 3;
5170 case 0: /* VREV64 */
5173 for (pass = 0; pass < (q ? 2 : 1); pass++) {
5174 NEON_GET_REG(T0, rm, pass * 2);
5175 NEON_GET_REG(T1, rm, pass * 2 + 1);
5177 case 0: tcg_gen_bswap_i32(cpu_T[0], cpu_T[0]); break;
5178 case 1: gen_swap_half(cpu_T[0]); break;
5179 case 2: /* no-op */ break;
5182 NEON_SET_REG(T0, rd, pass * 2 + 1);
5184 NEON_SET_REG(T1, rd, pass * 2);
5186 gen_op_movl_T0_T1();
5188 case 0: tcg_gen_bswap_i32(cpu_T[0], cpu_T[0]); break;
5189 case 1: gen_swap_half(cpu_T[0]); break;
5192 NEON_SET_REG(T0, rd, pass * 2);
5196 case 4: case 5: /* VPADDL */
5197 case 12: case 13: /* VPADAL */
5200 for (pass = 0; pass < q + 1; pass++) {
5201 tmp = neon_load_reg(rm, pass * 2);
5202 gen_neon_widen(cpu_V0, tmp, size, op & 1);
5203 tmp = neon_load_reg(rm, pass * 2 + 1);
5204 gen_neon_widen(cpu_V1, tmp, size, op & 1);
5206 case 0: gen_helper_neon_paddl_u16(CPU_V001); break;
5207 case 1: gen_helper_neon_paddl_u32(CPU_V001); break;
5208 case 2: tcg_gen_add_i64(CPU_V001); break;
5213 neon_load_reg64(cpu_V1, rd + pass);
5214 gen_neon_addl(size);
5216 neon_store_reg64(cpu_V0, rd + pass);
5221 for (n = 0; n < (q ? 4 : 2); n += 2) {
5222 NEON_GET_REG(T0, rm, n);
5223 NEON_GET_REG(T1, rd, n + 1);
5224 NEON_SET_REG(T1, rm, n);
5225 NEON_SET_REG(T0, rd, n + 1);
5233 Rd A3 A2 A1 A0 B2 B0 A2 A0
5234 Rm B3 B2 B1 B0 B3 B1 A3 A1
5238 gen_neon_unzip(rd, q, 0, size);
5239 gen_neon_unzip(rm, q, 4, size);
5241 static int unzip_order_q[8] =
5242 {0, 2, 4, 6, 1, 3, 5, 7};
5243 for (n = 0; n < 8; n++) {
5244 int reg = (n < 4) ? rd : rm;
5245 gen_neon_movl_T0_scratch(unzip_order_q[n]);
5246 NEON_SET_REG(T0, reg, n % 4);
5249 static int unzip_order[4] =
5251 for (n = 0; n < 4; n++) {
5252 int reg = (n < 2) ? rd : rm;
5253 gen_neon_movl_T0_scratch(unzip_order[n]);
5254 NEON_SET_REG(T0, reg, n % 2);
5260 Rd A3 A2 A1 A0 B1 A1 B0 A0
5261 Rm B3 B2 B1 B0 B3 A3 B2 A2
5265 count = (q ? 4 : 2);
5266 for (n = 0; n < count; n++) {
5267 NEON_GET_REG(T0, rd, n);
5268 NEON_GET_REG(T1, rd, n);
5270 case 0: gen_helper_neon_zip_u8(); break;
5271 case 1: gen_helper_neon_zip_u16(); break;
5272 case 2: /* no-op */; break;
5275 gen_neon_movl_scratch_T0(n * 2);
5276 gen_neon_movl_scratch_T1(n * 2 + 1);
5278 for (n = 0; n < count * 2; n++) {
5279 int reg = (n < count) ? rd : rm;
5280 gen_neon_movl_T0_scratch(n);
5281 NEON_SET_REG(T0, reg, n % count);
5284 case 36: case 37: /* VMOVN, VQMOVUN, VQMOVN */
5287 for (pass = 0; pass < 2; pass++) {
5288 neon_load_reg64(cpu_V0, rm + pass);
5290 if (op == 36 && q == 0) {
5291 gen_neon_narrow(size, tmp, cpu_V0);
5293 gen_neon_narrow_satu(size, tmp, cpu_V0);
5295 gen_neon_narrow_sats(size, tmp, cpu_V0);
5300 neon_store_reg(rd, 0, tmp2);
5301 neon_store_reg(rd, 1, tmp);
5305 case 38: /* VSHLL */
5308 tmp = neon_load_reg(rm, 0);
5309 tmp2 = neon_load_reg(rm, 1);
5310 for (pass = 0; pass < 2; pass++) {
5313 gen_neon_widen(cpu_V0, tmp, size, 1);
5314 neon_store_reg64(cpu_V0, rd + pass);
5319 for (pass = 0; pass < (q ? 4 : 2); pass++) {
5320 if (op == 30 || op == 31 || op >= 58) {
5321 tcg_gen_ld_f32(cpu_F0s, cpu_env,
5322 neon_reg_offset(rm, pass));
5324 NEON_GET_REG(T0, rm, pass);
5327 case 1: /* VREV32 */
5329 case 0: tcg_gen_bswap_i32(cpu_T[0], cpu_T[0]); break;
5330 case 1: gen_swap_half(cpu_T[0]); break;
5334 case 2: /* VREV16 */
5337 gen_rev16(cpu_T[0]);
5341 case 0: gen_helper_neon_cls_s8(cpu_T[0], cpu_T[0]); break;
5342 case 1: gen_helper_neon_cls_s16(cpu_T[0], cpu_T[0]); break;
5343 case 2: gen_helper_neon_cls_s32(cpu_T[0], cpu_T[0]); break;
5349 case 0: gen_helper_neon_clz_u8(cpu_T[0], cpu_T[0]); break;
5350 case 1: gen_helper_neon_clz_u16(cpu_T[0], cpu_T[0]); break;
5351 case 2: gen_helper_clz(cpu_T[0], cpu_T[0]); break;
5358 gen_helper_neon_cnt_u8(cpu_T[0], cpu_T[0]);
5365 case 14: /* VQABS */
5367 case 0: gen_helper_neon_qabs_s8(cpu_T[0], cpu_env, cpu_T[0]); break;
5368 case 1: gen_helper_neon_qabs_s16(cpu_T[0], cpu_env, cpu_T[0]); break;
5369 case 2: gen_helper_neon_qabs_s32(cpu_T[0], cpu_env, cpu_T[0]); break;
5373 case 15: /* VQNEG */
5375 case 0: gen_helper_neon_qneg_s8(cpu_T[0], cpu_env, cpu_T[0]); break;
5376 case 1: gen_helper_neon_qneg_s16(cpu_T[0], cpu_env, cpu_T[0]); break;
5377 case 2: gen_helper_neon_qneg_s32(cpu_T[0], cpu_env, cpu_T[0]); break;
5381 case 16: case 19: /* VCGT #0, VCLE #0 */
5382 gen_op_movl_T1_im(0);
5384 case 0: gen_helper_neon_cgt_s8(CPU_T001); break;
5385 case 1: gen_helper_neon_cgt_s16(CPU_T001); break;
5386 case 2: gen_helper_neon_cgt_s32(CPU_T001); break;
5392 case 17: case 20: /* VCGE #0, VCLT #0 */
5393 gen_op_movl_T1_im(0);
5395 case 0: gen_helper_neon_cge_s8(CPU_T001); break;
5396 case 1: gen_helper_neon_cge_s16(CPU_T001); break;
5397 case 2: gen_helper_neon_cge_s32(CPU_T001); break;
5403 case 18: /* VCEQ #0 */
5404 gen_op_movl_T1_im(0);
5406 case 0: gen_helper_neon_ceq_u8(CPU_T001); break;
5407 case 1: gen_helper_neon_ceq_u16(CPU_T001); break;
5408 case 2: gen_helper_neon_ceq_u32(CPU_T001); break;
5414 case 0: gen_helper_neon_abs_s8(cpu_T[0], cpu_T[0]); break;
5415 case 1: gen_helper_neon_abs_s16(cpu_T[0], cpu_T[0]); break;
5416 case 2: tcg_gen_abs_i32(cpu_T[0], cpu_T[0]); break;
5421 gen_op_movl_T1_im(0);
5426 case 24: case 27: /* Float VCGT #0, Float VCLE #0 */
5427 gen_op_movl_T1_im(0);
5428 gen_helper_neon_cgt_f32(CPU_T001);
5432 case 25: case 28: /* Float VCGE #0, Float VCLT #0 */
5433 gen_op_movl_T1_im(0);
5434 gen_helper_neon_cge_f32(CPU_T001);
5438 case 26: /* Float VCEQ #0 */
5439 gen_op_movl_T1_im(0);
5440 gen_helper_neon_ceq_f32(CPU_T001);
5442 case 30: /* Float VABS */
5445 case 31: /* Float VNEG */
5449 NEON_GET_REG(T1, rd, pass);
5450 NEON_SET_REG(T1, rm, pass);
5453 NEON_GET_REG(T1, rd, pass);
5455 case 0: gen_helper_neon_trn_u8(); break;
5456 case 1: gen_helper_neon_trn_u16(); break;
5460 NEON_SET_REG(T1, rm, pass);
5462 case 56: /* Integer VRECPE */
5463 gen_helper_recpe_u32(cpu_T[0], cpu_T[0], cpu_env);
5465 case 57: /* Integer VRSQRTE */
5466 gen_helper_rsqrte_u32(cpu_T[0], cpu_T[0], cpu_env);
5468 case 58: /* Float VRECPE */
5469 gen_helper_recpe_f32(cpu_F0s, cpu_F0s, cpu_env);
5471 case 59: /* Float VRSQRTE */
5472 gen_helper_rsqrte_f32(cpu_F0s, cpu_F0s, cpu_env);
5474 case 60: /* VCVT.F32.S32 */
5477 case 61: /* VCVT.F32.U32 */
5480 case 62: /* VCVT.S32.F32 */
5483 case 63: /* VCVT.U32.F32 */
5487 /* Reserved: 21, 29, 39-56 */
5490 if (op == 30 || op == 31 || op >= 58) {
5491 tcg_gen_st_f32(cpu_F0s, cpu_env,
5492 neon_reg_offset(rd, pass));
5494 NEON_SET_REG(T0, rd, pass);
5499 } else if ((insn & (1 << 10)) == 0) {
5501 n = (insn >> 5) & 0x18;
5502 if (insn & (1 << 6)) {
5503 tmp = neon_load_reg(rd, 0);
5506 tcg_gen_movi_i32(tmp, 0);
5508 tmp2 = neon_load_reg(rm, 0);
5509 gen_helper_neon_tbl(tmp2, tmp2, tmp, tcg_const_i32(rn),
5511 if (insn & (1 << 6)) {
5512 tmp = neon_load_reg(rd, 1);
5515 tcg_gen_movi_i32(tmp, 0);
5517 tmp3 = neon_load_reg(rm, 1);
5518 gen_helper_neon_tbl(tmp3, tmp3, tmp, tcg_const_i32(rn),
5520 neon_store_reg(rd, 0, tmp2);
5521 neon_store_reg(rd, 1, tmp2);
5522 } else if ((insn & 0x380) == 0) {
5524 if (insn & (1 << 19)) {
5525 NEON_SET_REG(T0, rm, 1);
5527 NEON_SET_REG(T0, rm, 0);
5529 if (insn & (1 << 16)) {
5530 gen_neon_dup_u8(cpu_T[0], ((insn >> 17) & 3) * 8);
5531 } else if (insn & (1 << 17)) {
5532 if ((insn >> 18) & 1)
5533 gen_neon_dup_high16(cpu_T[0]);
5535 gen_neon_dup_low16(cpu_T[0]);
5537 for (pass = 0; pass < (q ? 4 : 2); pass++) {
5538 NEON_SET_REG(T0, rd, pass);
5548 static int disas_coproc_insn(CPUState * env, DisasContext *s, uint32_t insn)
5552 cpnum = (insn >> 8) & 0xf;
5553 if (arm_feature(env, ARM_FEATURE_XSCALE)
5554 && ((env->cp15.c15_cpar ^ 0x3fff) & (1 << cpnum)))
5560 if (arm_feature(env, ARM_FEATURE_IWMMXT)) {
5561 return disas_iwmmxt_insn(env, s, insn);
5562 } else if (arm_feature(env, ARM_FEATURE_XSCALE)) {
5563 return disas_dsp_insn(env, s, insn);
5568 return disas_vfp_insn (env, s, insn);
5570 return disas_cp15_insn (env, s, insn);
5572 /* Unknown coprocessor. See if the board has hooked it. */
5573 return disas_cp_insn (env, s, insn);
5578 /* Store a 64-bit value to a register pair. Clobbers val. */
5579 static void gen_storeq_reg(DisasContext *s, int rlow, int rhigh, TCGv val)
5583 tcg_gen_trunc_i64_i32(tmp, val);
5584 store_reg(s, rlow, tmp);
5586 tcg_gen_shri_i64(val, val, 32);
5587 tcg_gen_trunc_i64_i32(tmp, val);
5588 store_reg(s, rhigh, tmp);
5591 /* load a 32-bit value from a register and perform a 64-bit accumulate. */
5592 static void gen_addq_lo(DisasContext *s, TCGv val, int rlow)
5597 /* Load 64-bit value rd:rn. */
5598 tmp = tcg_temp_new(TCG_TYPE_I64);
5599 tmp2 = load_reg(s, rlow);
5600 tcg_gen_extu_i32_i64(tmp, tmp2);
5602 tcg_gen_add_i64(val, val, tmp);
5605 /* load and add a 64-bit value from a register pair. */
5606 static void gen_addq(DisasContext *s, TCGv val, int rlow, int rhigh)
5611 /* Load 64-bit value rd:rn. */
5612 tmp = tcg_temp_new(TCG_TYPE_I64);
5613 tmp2 = load_reg(s, rhigh);
5614 tcg_gen_extu_i32_i64(tmp, tmp2);
5616 tcg_gen_shli_i64(tmp, tmp, 32);
5617 tcg_gen_add_i64(val, val, tmp);
5619 tmp2 = load_reg(s, rlow);
5620 tcg_gen_extu_i32_i64(tmp, tmp2);
5622 tcg_gen_add_i64(val, val, tmp);
5625 /* Set N and Z flags from a 64-bit value. */
5626 static void gen_logicq_cc(TCGv val)
5628 TCGv tmp = new_tmp();
5629 gen_helper_logicq_cc(tmp, val);
5634 static void disas_arm_insn(CPUState * env, DisasContext *s)
5636 unsigned int cond, insn, val, op1, i, shift, rm, rs, rn, rd, sh;
5642 insn = ldl_code(s->pc);
5645 /* M variants do not implement ARM mode. */
5650 /* Unconditional instructions. */
5651 if (((insn >> 25) & 7) == 1) {
5652 /* NEON Data processing. */
5653 if (!arm_feature(env, ARM_FEATURE_NEON))
5656 if (disas_neon_data_insn(env, s, insn))
5660 if ((insn & 0x0f100000) == 0x04000000) {
5661 /* NEON load/store. */
5662 if (!arm_feature(env, ARM_FEATURE_NEON))
5665 if (disas_neon_ls_insn(env, s, insn))
5669 if ((insn & 0x0d70f000) == 0x0550f000)
5671 else if ((insn & 0x0ffffdff) == 0x01010000) {
5674 if (insn & (1 << 9)) {
5675 /* BE8 mode not implemented. */
5679 } else if ((insn & 0x0fffff00) == 0x057ff000) {
5680 switch ((insn >> 4) & 0xf) {
5683 gen_helper_clrex(cpu_env);
5689 /* We don't emulate caches so these are a no-op. */
5694 } else if ((insn & 0x0e5fffe0) == 0x084d0500) {
5700 op1 = (insn & 0x1f);
5701 if (op1 == (env->uncached_cpsr & CPSR_M)) {
5702 addr = load_reg(s, 13);
5705 gen_helper_get_r13_banked(addr, cpu_env, tcg_const_i32(op1));
5707 i = (insn >> 23) & 3;
5709 case 0: offset = -4; break; /* DA */
5710 case 1: offset = -8; break; /* DB */
5711 case 2: offset = 0; break; /* IA */
5712 case 3: offset = 4; break; /* IB */
5716 tcg_gen_addi_i32(addr, addr, offset);
5717 tmp = load_reg(s, 14);
5718 gen_st32(tmp, addr, 0);
5720 gen_helper_cpsr_read(tmp);
5721 tcg_gen_addi_i32(addr, addr, 4);
5722 gen_st32(tmp, addr, 0);
5723 if (insn & (1 << 21)) {
5724 /* Base writeback. */
5726 case 0: offset = -8; break;
5727 case 1: offset = -4; break;
5728 case 2: offset = 4; break;
5729 case 3: offset = 0; break;
5733 tcg_gen_addi_i32(addr, tmp, offset);
5734 if (op1 == (env->uncached_cpsr & CPSR_M)) {
5735 gen_movl_reg_T1(s, 13);
5737 gen_helper_set_r13_banked(cpu_env, tcg_const_i32(op1), cpu_T[1]);
5742 } else if ((insn & 0x0e5fffe0) == 0x081d0a00) {
5748 rn = (insn >> 16) & 0xf;
5749 addr = load_reg(s, rn);
5750 i = (insn >> 23) & 3;
5752 case 0: offset = -4; break; /* DA */
5753 case 1: offset = -8; break; /* DB */
5754 case 2: offset = 0; break; /* IA */
5755 case 3: offset = 4; break; /* IB */
5759 tcg_gen_addi_i32(addr, addr, offset);
5760 /* Load PC into tmp and CPSR into tmp2. */
5761 tmp = gen_ld32(addr, 0);
5762 tcg_gen_addi_i32(addr, addr, 4);
5763 tmp2 = gen_ld32(addr, 0);
5764 if (insn & (1 << 21)) {
5765 /* Base writeback. */
5767 case 0: offset = -8; break;
5768 case 1: offset = -4; break;
5769 case 2: offset = 4; break;
5770 case 3: offset = 0; break;
5774 tcg_gen_addi_i32(addr, addr, offset);
5775 store_reg(s, rn, addr);
5779 gen_rfe(s, tmp, tmp2);
5780 } else if ((insn & 0x0e000000) == 0x0a000000) {
5781 /* branch link and change to thumb (blx <offset>) */
5784 val = (uint32_t)s->pc;
5786 tcg_gen_movi_i32(tmp, val);
5787 store_reg(s, 14, tmp);
5788 /* Sign-extend the 24-bit offset */
5789 offset = (((int32_t)insn) << 8) >> 8;
5790 /* offset * 4 + bit24 * 2 + (thumb bit) */
5791 val += (offset << 2) | ((insn >> 23) & 2) | 1;
5792 /* pipeline offset */
5796 } else if ((insn & 0x0e000f00) == 0x0c000100) {
5797 if (arm_feature(env, ARM_FEATURE_IWMMXT)) {
5798 /* iWMMXt register transfer. */
5799 if (env->cp15.c15_cpar & (1 << 1))
5800 if (!disas_iwmmxt_insn(env, s, insn))
5803 } else if ((insn & 0x0fe00000) == 0x0c400000) {
5804 /* Coprocessor double register transfer. */
5805 } else if ((insn & 0x0f000010) == 0x0e000010) {
5806 /* Additional coprocessor register transfer. */
5807 } else if ((insn & 0x0ff10010) == 0x01000000) {
5810 /* cps (privileged) */
5814 if (insn & (1 << 19)) {
5815 if (insn & (1 << 8))
5817 if (insn & (1 << 7))
5819 if (insn & (1 << 6))
5821 if (insn & (1 << 18))
5824 if (insn & (1 << 14)) {
5826 val |= (insn & 0x1f);
5829 gen_op_movl_T0_im(val);
5830 gen_set_psr_T0(s, mask, 0);
5837 /* if not always execute, we generate a conditional jump to
5839 s->condlabel = gen_new_label();
5840 gen_test_cc(cond ^ 1, s->condlabel);
5843 if ((insn & 0x0f900000) == 0x03000000) {
5844 if ((insn & (1 << 21)) == 0) {
5846 rd = (insn >> 12) & 0xf;
5847 val = ((insn >> 4) & 0xf000) | (insn & 0xfff);
5848 if ((insn & (1 << 22)) == 0) {
5851 tcg_gen_movi_i32(tmp, val);
5854 tmp = load_reg(s, rd);
5855 tcg_gen_ext16u_i32(tmp, tmp);
5856 tcg_gen_ori_i32(tmp, tmp, val << 16);
5858 store_reg(s, rd, tmp);
5860 if (((insn >> 12) & 0xf) != 0xf)
5862 if (((insn >> 16) & 0xf) == 0) {
5863 gen_nop_hint(s, insn & 0xff);
5865 /* CPSR = immediate */
5867 shift = ((insn >> 8) & 0xf) * 2;
5869 val = (val >> shift) | (val << (32 - shift));
5870 gen_op_movl_T0_im(val);
5871 i = ((insn & (1 << 22)) != 0);
5872 if (gen_set_psr_T0(s, msr_mask(env, s, (insn >> 16) & 0xf, i), i))
5876 } else if ((insn & 0x0f900000) == 0x01000000
5877 && (insn & 0x00000090) != 0x00000090) {
5878 /* miscellaneous instructions */
5879 op1 = (insn >> 21) & 3;
5880 sh = (insn >> 4) & 0xf;
5883 case 0x0: /* move program status register */
5886 gen_movl_T0_reg(s, rm);
5887 i = ((op1 & 2) != 0);
5888 if (gen_set_psr_T0(s, msr_mask(env, s, (insn >> 16) & 0xf, i), i))
5892 rd = (insn >> 12) & 0xf;
5896 tmp = load_cpu_field(spsr);
5899 gen_helper_cpsr_read(tmp);
5901 store_reg(s, rd, tmp);
5906 /* branch/exchange thumb (bx). */
5907 tmp = load_reg(s, rm);
5909 } else if (op1 == 3) {
5911 rd = (insn >> 12) & 0xf;
5912 tmp = load_reg(s, rm);
5913 gen_helper_clz(tmp, tmp);
5914 store_reg(s, rd, tmp);
5922 /* Trivial implementation equivalent to bx. */
5923 tmp = load_reg(s, rm);
5933 /* branch link/exchange thumb (blx) */
5934 tmp = load_reg(s, rm);
5936 tcg_gen_movi_i32(tmp2, s->pc);
5937 store_reg(s, 14, tmp2);
5940 case 0x5: /* saturating add/subtract */
5941 rd = (insn >> 12) & 0xf;
5942 rn = (insn >> 16) & 0xf;
5943 tmp = load_reg(s, rn);
5944 tmp2 = load_reg(s, rn);
5946 gen_helper_double_saturate(tmp2, tmp2);
5948 gen_helper_sub_saturate(tmp, tmp, tmp2);
5950 gen_helper_add_saturate(tmp, tmp, tmp2);
5952 store_reg(s, rd, tmp);
5955 gen_set_condexec(s);
5956 gen_set_pc_im(s->pc - 4);
5957 gen_exception(EXCP_BKPT);
5958 s->is_jmp = DISAS_JUMP;
5960 case 0x8: /* signed multiply */
5964 rs = (insn >> 8) & 0xf;
5965 rn = (insn >> 12) & 0xf;
5966 rd = (insn >> 16) & 0xf;
5968 /* (32 * 16) >> 16 */
5969 tmp = load_reg(s, rm);
5970 tmp2 = load_reg(s, rs);
5972 tcg_gen_sari_i32(tmp2, tmp2, 16);
5975 tmp2 = gen_muls_i64_i32(tmp, tmp2);
5976 tcg_gen_shri_i64(tmp2, tmp2, 16);
5978 tcg_gen_trunc_i64_i32(tmp, tmp2);
5979 if ((sh & 2) == 0) {
5980 tmp2 = load_reg(s, rn);
5981 gen_helper_add_setq(tmp, tmp, tmp2);
5984 store_reg(s, rd, tmp);
5987 tmp = load_reg(s, rm);
5988 tmp2 = load_reg(s, rs);
5989 gen_mulxy(tmp, tmp2, sh & 2, sh & 4);
5992 tmp = tcg_temp_new(TCG_TYPE_I64);
5993 tcg_gen_ext_i32_i64(tmp, cpu_T[0]);
5994 gen_addq(s, tmp, rn, rd);
5995 gen_storeq_reg(s, rn, rd, tmp);
5998 tmp2 = load_reg(s, rn);
5999 gen_helper_add_setq(tmp, tmp, tmp2);
6002 store_reg(s, rd, tmp);
6009 } else if (((insn & 0x0e000000) == 0 &&
6010 (insn & 0x00000090) != 0x90) ||
6011 ((insn & 0x0e000000) == (1 << 25))) {
6012 int set_cc, logic_cc, shiftop;
6014 op1 = (insn >> 21) & 0xf;
6015 set_cc = (insn >> 20) & 1;
6016 logic_cc = table_logic_cc[op1] & set_cc;
6018 /* data processing instruction */
6019 if (insn & (1 << 25)) {
6020 /* immediate operand */
6022 shift = ((insn >> 8) & 0xf) * 2;
6024 val = (val >> shift) | (val << (32 - shift));
6025 gen_op_movl_T1_im(val);
6026 if (logic_cc && shift)
6027 gen_set_CF_bit31(cpu_T[1]);
6031 gen_movl_T1_reg(s, rm);
6032 shiftop = (insn >> 5) & 3;
6033 if (!(insn & (1 << 4))) {
6034 shift = (insn >> 7) & 0x1f;
6035 gen_arm_shift_im(cpu_T[1], shiftop, shift, logic_cc);
6037 rs = (insn >> 8) & 0xf;
6038 tmp = load_reg(s, rs);
6039 gen_arm_shift_reg(cpu_T[1], shiftop, tmp, logic_cc);
6042 if (op1 != 0x0f && op1 != 0x0d) {
6043 rn = (insn >> 16) & 0xf;
6044 gen_movl_T0_reg(s, rn);
6046 rd = (insn >> 12) & 0xf;
6049 gen_op_andl_T0_T1();
6050 gen_movl_reg_T0(s, rd);
6052 gen_op_logic_T0_cc();
6055 gen_op_xorl_T0_T1();
6056 gen_movl_reg_T0(s, rd);
6058 gen_op_logic_T0_cc();
6061 if (set_cc && rd == 15) {
6062 /* SUBS r15, ... is used for exception return. */
6065 gen_op_subl_T0_T1_cc();
6066 gen_exception_return(s);
6069 gen_op_subl_T0_T1_cc();
6071 gen_op_subl_T0_T1();
6072 gen_movl_reg_T0(s, rd);
6077 gen_op_rsbl_T0_T1_cc();
6079 gen_op_rsbl_T0_T1();
6080 gen_movl_reg_T0(s, rd);
6084 gen_op_addl_T0_T1_cc();
6086 gen_op_addl_T0_T1();
6087 gen_movl_reg_T0(s, rd);
6091 gen_op_adcl_T0_T1_cc();
6094 gen_movl_reg_T0(s, rd);
6098 gen_op_sbcl_T0_T1_cc();
6101 gen_movl_reg_T0(s, rd);
6105 gen_op_rscl_T0_T1_cc();
6108 gen_movl_reg_T0(s, rd);
6112 gen_op_andl_T0_T1();
6113 gen_op_logic_T0_cc();
6118 gen_op_xorl_T0_T1();
6119 gen_op_logic_T0_cc();
6124 gen_op_subl_T0_T1_cc();
6129 gen_op_addl_T0_T1_cc();
6134 gen_movl_reg_T0(s, rd);
6136 gen_op_logic_T0_cc();
6139 if (logic_cc && rd == 15) {
6140 /* MOVS r15, ... is used for exception return. */
6143 gen_op_movl_T0_T1();
6144 gen_exception_return(s);
6146 gen_movl_reg_T1(s, rd);
6148 gen_op_logic_T1_cc();
6152 gen_op_bicl_T0_T1();
6153 gen_movl_reg_T0(s, rd);
6155 gen_op_logic_T0_cc();
6160 gen_movl_reg_T1(s, rd);
6162 gen_op_logic_T1_cc();
6166 /* other instructions */
6167 op1 = (insn >> 24) & 0xf;
6171 /* multiplies, extra load/stores */
6172 sh = (insn >> 5) & 3;
6175 rd = (insn >> 16) & 0xf;
6176 rn = (insn >> 12) & 0xf;
6177 rs = (insn >> 8) & 0xf;
6179 op1 = (insn >> 20) & 0xf;
6181 case 0: case 1: case 2: case 3: case 6:
6183 tmp = load_reg(s, rs);
6184 tmp2 = load_reg(s, rm);
6185 tcg_gen_mul_i32(tmp, tmp, tmp2);
6187 if (insn & (1 << 22)) {
6188 /* Subtract (mls) */
6190 tmp2 = load_reg(s, rn);
6191 tcg_gen_sub_i32(tmp, tmp2, tmp);
6193 } else if (insn & (1 << 21)) {
6195 tmp2 = load_reg(s, rn);
6196 tcg_gen_add_i32(tmp, tmp, tmp2);
6199 if (insn & (1 << 20))
6201 store_reg(s, rd, tmp);
6205 tmp = load_reg(s, rs);
6206 tmp2 = load_reg(s, rm);
6207 if (insn & (1 << 22))
6208 tmp = gen_muls_i64_i32(tmp, tmp2);
6210 tmp = gen_mulu_i64_i32(tmp, tmp2);
6211 if (insn & (1 << 21)) /* mult accumulate */
6212 gen_addq(s, tmp, rn, rd);
6213 if (!(insn & (1 << 23))) { /* double accumulate */
6215 gen_addq_lo(s, tmp, rn);
6216 gen_addq_lo(s, tmp, rd);
6218 if (insn & (1 << 20))
6220 gen_storeq_reg(s, rn, rd, tmp);
6224 rn = (insn >> 16) & 0xf;
6225 rd = (insn >> 12) & 0xf;
6226 if (insn & (1 << 23)) {
6227 /* load/store exclusive */
6228 gen_movl_T1_reg(s, rn);
6230 if (insn & (1 << 20)) {
6231 gen_helper_mark_exclusive(cpu_env, cpu_T[1]);
6232 tmp = gen_ld32(addr, IS_USER(s));
6233 store_reg(s, rd, tmp);
6235 int label = gen_new_label();
6237 gen_helper_test_exclusive(cpu_T[0], cpu_env, addr);
6238 tcg_gen_brcondi_i32(TCG_COND_NE, cpu_T[0],
6240 tmp = load_reg(s,rm);
6241 gen_st32(tmp, cpu_T[1], IS_USER(s));
6242 gen_set_label(label);
6243 gen_movl_reg_T0(s, rd);
6246 /* SWP instruction */
6249 /* ??? This is not really atomic. However we know
6250 we never have multiple CPUs running in parallel,
6251 so it is good enough. */
6252 addr = load_reg(s, rn);
6253 tmp = load_reg(s, rm);
6254 if (insn & (1 << 22)) {
6255 tmp2 = gen_ld8u(addr, IS_USER(s));
6256 gen_st8(tmp, addr, IS_USER(s));
6258 tmp2 = gen_ld32(addr, IS_USER(s));
6259 gen_st32(tmp, addr, IS_USER(s));
6262 store_reg(s, rd, tmp2);
6268 /* Misc load/store */
6269 rn = (insn >> 16) & 0xf;
6270 rd = (insn >> 12) & 0xf;
6271 addr = load_reg(s, rn);
6272 if (insn & (1 << 24))
6273 gen_add_datah_offset(s, insn, 0, addr);
6275 if (insn & (1 << 20)) {
6279 tmp = gen_ld16u(addr, IS_USER(s));
6282 tmp = gen_ld8s(addr, IS_USER(s));
6286 tmp = gen_ld16s(addr, IS_USER(s));
6290 } else if (sh & 2) {
6294 tmp = load_reg(s, rd);
6295 gen_st32(tmp, addr, IS_USER(s));
6296 tcg_gen_addi_i32(addr, addr, 4);
6297 tmp = load_reg(s, rd + 1);
6298 gen_st32(tmp, addr, IS_USER(s));
6302 tmp = gen_ld32(addr, IS_USER(s));
6303 store_reg(s, rd, tmp);
6304 tcg_gen_addi_i32(addr, addr, 4);
6305 tmp = gen_ld32(addr, IS_USER(s));
6309 address_offset = -4;
6312 tmp = load_reg(s, rd);
6313 gen_st16(tmp, addr, IS_USER(s));
6316 /* Perform base writeback before the loaded value to
6317 ensure correct behavior with overlapping index registers.
6318 ldrd with base writeback is is undefined if the
6319 destination and index registers overlap. */
6320 if (!(insn & (1 << 24))) {
6321 gen_add_datah_offset(s, insn, address_offset, addr);
6322 store_reg(s, rn, addr);
6323 } else if (insn & (1 << 21)) {
6325 tcg_gen_addi_i32(addr, addr, address_offset);
6326 store_reg(s, rn, addr);
6331 /* Complete the load. */
6332 store_reg(s, rd, tmp);
6341 if (insn & (1 << 4)) {
6343 /* Armv6 Media instructions. */
6345 rn = (insn >> 16) & 0xf;
6346 rd = (insn >> 12) & 0xf;
6347 rs = (insn >> 8) & 0xf;
6348 switch ((insn >> 23) & 3) {
6349 case 0: /* Parallel add/subtract. */
6350 op1 = (insn >> 20) & 7;
6351 tmp = load_reg(s, rn);
6352 tmp2 = load_reg(s, rm);
6353 sh = (insn >> 5) & 7;
6354 if ((op1 & 3) == 0 || sh == 5 || sh == 6)
6356 gen_arm_parallel_addsub(op1, sh, tmp, tmp2);
6358 store_reg(s, rd, tmp);
6361 if ((insn & 0x00700020) == 0) {
6362 /* Halfword pack. */
6363 tmp = load_reg(s, rn);
6364 tmp2 = load_reg(s, rm);
6365 shift = (insn >> 7) & 0x1f;
6367 tcg_gen_shli_i32(tmp2, tmp2, shift);
6368 if (insn & (1 << 6)) {
6370 tcg_gen_andi_i32(tmp, tmp, 0xffff0000);
6371 tcg_gen_ext16u_i32(tmp2, tmp2);
6374 tcg_gen_ext16u_i32(tmp, tmp);
6375 tcg_gen_andi_i32(tmp2, tmp2, 0xffff0000);
6377 tcg_gen_or_i32(tmp, tmp, tmp2);
6378 store_reg(s, rd, tmp);
6379 } else if ((insn & 0x00200020) == 0x00200000) {
6381 tmp = load_reg(s, rm);
6382 shift = (insn >> 7) & 0x1f;
6383 if (insn & (1 << 6)) {
6386 tcg_gen_sari_i32(tmp, tmp, shift);
6388 tcg_gen_shli_i32(tmp, tmp, shift);
6390 sh = (insn >> 16) & 0x1f;
6392 if (insn & (1 << 22))
6393 gen_helper_usat(tmp, tmp, tcg_const_i32(sh));
6395 gen_helper_ssat(tmp, tmp, tcg_const_i32(sh));
6397 store_reg(s, rd, tmp);
6398 } else if ((insn & 0x00300fe0) == 0x00200f20) {
6400 tmp = load_reg(s, rm);
6401 sh = (insn >> 16) & 0x1f;
6403 if (insn & (1 << 22))
6404 gen_helper_usat16(tmp, tmp, tcg_const_i32(sh));
6406 gen_helper_ssat16(tmp, tmp, tcg_const_i32(sh));
6408 store_reg(s, rd, tmp);
6409 } else if ((insn & 0x00700fe0) == 0x00000fa0) {
6411 tmp = load_reg(s, rn);
6412 tmp2 = load_reg(s, rm);
6414 tcg_gen_ld_i32(tmp3, cpu_env, offsetof(CPUState, GE));
6415 gen_helper_sel_flags(tmp, tmp3, tmp, tmp2);
6418 store_reg(s, rd, tmp);
6419 } else if ((insn & 0x000003e0) == 0x00000060) {
6420 tmp = load_reg(s, rm);
6421 shift = (insn >> 10) & 3;
6422 /* ??? In many cases it's not neccessary to do a
6423 rotate, a shift is sufficient. */
6425 tcg_gen_rori_i32(tmp, tmp, shift * 8);
6426 op1 = (insn >> 20) & 7;
6428 case 0: gen_sxtb16(tmp); break;
6429 case 2: gen_sxtb(tmp); break;
6430 case 3: gen_sxth(tmp); break;
6431 case 4: gen_uxtb16(tmp); break;
6432 case 6: gen_uxtb(tmp); break;
6433 case 7: gen_uxth(tmp); break;
6434 default: goto illegal_op;
6437 tmp2 = load_reg(s, rn);
6438 if ((op1 & 3) == 0) {
6439 gen_add16(tmp, tmp2);
6441 tcg_gen_add_i32(tmp, tmp, tmp2);
6445 store_reg(s, rd, tmp);
6446 } else if ((insn & 0x003f0f60) == 0x003f0f20) {
6448 tmp = load_reg(s, rm);
6449 if (insn & (1 << 22)) {
6450 if (insn & (1 << 7)) {
6454 gen_helper_rbit(tmp, tmp);
6457 if (insn & (1 << 7))
6460 tcg_gen_bswap_i32(tmp, tmp);
6462 store_reg(s, rd, tmp);
6467 case 2: /* Multiplies (Type 3). */
6468 tmp = load_reg(s, rm);
6469 tmp2 = load_reg(s, rs);
6470 if (insn & (1 << 20)) {
6471 /* Signed multiply most significant [accumulate]. */
6472 tmp2 = gen_muls_i64_i32(tmp, tmp2);
6473 if (insn & (1 << 5))
6474 tcg_gen_addi_i64(tmp2, tmp2, 0x80000000u);
6475 tcg_gen_shri_i64(tmp2, tmp2, 32);
6477 tcg_gen_trunc_i64_i32(tmp, tmp2);
6479 tmp2 = load_reg(s, rn);
6480 if (insn & (1 << 6)) {
6481 tcg_gen_sub_i32(tmp, tmp, tmp2);
6483 tcg_gen_add_i32(tmp, tmp, tmp2);
6487 store_reg(s, rd, tmp);
6489 if (insn & (1 << 5))
6490 gen_swap_half(tmp2);
6491 gen_smul_dual(tmp, tmp2);
6492 /* This addition cannot overflow. */
6493 if (insn & (1 << 6)) {
6494 tcg_gen_sub_i32(tmp, tmp, tmp2);
6496 tcg_gen_add_i32(tmp, tmp, tmp2);
6499 if (insn & (1 << 22)) {
6500 /* smlald, smlsld */
6501 tmp2 = tcg_temp_new(TCG_TYPE_I64);
6502 tcg_gen_ext_i32_i64(tmp2, tmp);
6504 gen_addq(s, tmp2, rn, rd);
6505 gen_storeq_reg(s, rn, rd, tmp2);
6507 /* smuad, smusd, smlad, smlsd */
6510 tmp2 = load_reg(s, rn);
6511 gen_helper_add_setq(tmp, tmp, tmp2);
6514 store_reg(s, rd, tmp);
6519 op1 = ((insn >> 17) & 0x38) | ((insn >> 5) & 7);
6521 case 0: /* Unsigned sum of absolute differences. */
6523 tmp = load_reg(s, rm);
6524 tmp2 = load_reg(s, rs);
6525 gen_helper_usad8(tmp, tmp, tmp2);
6528 tmp2 = load_reg(s, rn);
6529 tcg_gen_add_i32(tmp, tmp, tmp2);
6532 store_reg(s, rd, tmp);
6534 case 0x20: case 0x24: case 0x28: case 0x2c:
6535 /* Bitfield insert/clear. */
6537 shift = (insn >> 7) & 0x1f;
6538 i = (insn >> 16) & 0x1f;
6542 tcg_gen_movi_i32(tmp, 0);
6544 tmp = load_reg(s, rm);
6547 tmp2 = load_reg(s, rd);
6548 gen_bfi(tmp, tmp2, tmp, shift, (1u << i) - 1);
6551 store_reg(s, rd, tmp);
6553 case 0x12: case 0x16: case 0x1a: case 0x1e: /* sbfx */
6554 case 0x32: case 0x36: case 0x3a: case 0x3e: /* ubfx */
6555 tmp = load_reg(s, rm);
6556 shift = (insn >> 7) & 0x1f;
6557 i = ((insn >> 16) & 0x1f) + 1;
6562 gen_ubfx(tmp, shift, (1u << i) - 1);
6564 gen_sbfx(tmp, shift, i);
6567 store_reg(s, rd, tmp);
6577 /* Check for undefined extension instructions
6578 * per the ARM Bible IE:
6579 * xxxx 0111 1111 xxxx xxxx xxxx 1111 xxxx
6581 sh = (0xf << 20) | (0xf << 4);
6582 if (op1 == 0x7 && ((insn & sh) == sh))
6586 /* load/store byte/word */
6587 rn = (insn >> 16) & 0xf;
6588 rd = (insn >> 12) & 0xf;
6589 tmp2 = load_reg(s, rn);
6590 i = (IS_USER(s) || (insn & 0x01200000) == 0x00200000);
6591 if (insn & (1 << 24))
6592 gen_add_data_offset(s, insn, tmp2);
6593 if (insn & (1 << 20)) {
6596 if (insn & (1 << 22)) {
6597 tmp = gen_ld8u(tmp2, i);
6599 tmp = gen_ld32(tmp2, i);
6603 tmp = load_reg(s, rd);
6604 if (insn & (1 << 22))
6605 gen_st8(tmp, tmp2, i);
6607 gen_st32(tmp, tmp2, i);
6609 if (!(insn & (1 << 24))) {
6610 gen_add_data_offset(s, insn, tmp2);
6611 store_reg(s, rn, tmp2);
6612 } else if (insn & (1 << 21)) {
6613 store_reg(s, rn, tmp2);
6617 if (insn & (1 << 20)) {
6618 /* Complete the load. */
6622 store_reg(s, rd, tmp);
6628 int j, n, user, loaded_base;
6630 /* load/store multiple words */
6631 /* XXX: store correct base if write back */
6633 if (insn & (1 << 22)) {
6635 goto illegal_op; /* only usable in supervisor mode */
6637 if ((insn & (1 << 15)) == 0)
6640 rn = (insn >> 16) & 0xf;
6641 addr = load_reg(s, rn);
6643 /* compute total size */
6647 if (insn & (1 << i))
6650 /* XXX: test invalid n == 0 case ? */
6651 if (insn & (1 << 23)) {
6652 if (insn & (1 << 24)) {
6654 tcg_gen_addi_i32(addr, addr, 4);
6656 /* post increment */
6659 if (insn & (1 << 24)) {
6661 tcg_gen_addi_i32(addr, addr, -(n * 4));
6663 /* post decrement */
6665 tcg_gen_addi_i32(addr, addr, -((n - 1) * 4));
6670 if (insn & (1 << i)) {
6671 if (insn & (1 << 20)) {
6673 tmp = gen_ld32(addr, IS_USER(s));
6677 gen_helper_set_user_reg(tcg_const_i32(i), tmp);
6679 } else if (i == rn) {
6683 store_reg(s, i, tmp);
6688 /* special case: r15 = PC + 8 */
6689 val = (long)s->pc + 4;
6691 tcg_gen_movi_i32(tmp, val);
6694 gen_helper_get_user_reg(tmp, tcg_const_i32(i));
6696 tmp = load_reg(s, i);
6698 gen_st32(tmp, addr, IS_USER(s));
6701 /* no need to add after the last transfer */
6703 tcg_gen_addi_i32(addr, addr, 4);
6706 if (insn & (1 << 21)) {
6708 if (insn & (1 << 23)) {
6709 if (insn & (1 << 24)) {
6712 /* post increment */
6713 tcg_gen_addi_i32(addr, addr, 4);
6716 if (insn & (1 << 24)) {
6719 tcg_gen_addi_i32(addr, addr, -((n - 1) * 4));
6721 /* post decrement */
6722 tcg_gen_addi_i32(addr, addr, -(n * 4));
6725 store_reg(s, rn, addr);
6730 store_reg(s, rn, loaded_var);
6732 if ((insn & (1 << 22)) && !user) {
6733 /* Restore CPSR from SPSR. */
6734 tmp = load_cpu_field(spsr);
6735 gen_set_cpsr(tmp, 0xffffffff);
6737 s->is_jmp = DISAS_UPDATE;
6746 /* branch (and link) */
6747 val = (int32_t)s->pc;
6748 if (insn & (1 << 24)) {
6750 tcg_gen_movi_i32(tmp, val);
6751 store_reg(s, 14, tmp);
6753 offset = (((int32_t)insn << 8) >> 8);
6754 val += (offset << 2) + 4;
6762 if (disas_coproc_insn(env, s, insn))
6767 gen_set_pc_im(s->pc);
6768 s->is_jmp = DISAS_SWI;
6772 gen_set_condexec(s);
6773 gen_set_pc_im(s->pc - 4);
6774 gen_exception(EXCP_UDEF);
6775 s->is_jmp = DISAS_JUMP;
6781 /* Return true if this is a Thumb-2 logical op. */
6783 thumb2_logic_op(int op)
6788 /* Generate code for a Thumb-2 data processing operation. If CONDS is nonzero
6789 then set condition code flags based on the result of the operation.
6790 If SHIFTER_OUT is nonzero then set the carry flag for logical operations
6791 to the high bit of T1.
6792 Returns zero if the opcode is valid. */
6795 gen_thumb2_data_op(DisasContext *s, int op, int conds, uint32_t shifter_out)
6802 gen_op_andl_T0_T1();
6806 gen_op_bicl_T0_T1();
6819 gen_op_xorl_T0_T1();
6824 gen_op_addl_T0_T1_cc();
6826 gen_op_addl_T0_T1();
6830 gen_op_adcl_T0_T1_cc();
6836 gen_op_sbcl_T0_T1_cc();
6842 gen_op_subl_T0_T1_cc();
6844 gen_op_subl_T0_T1();
6848 gen_op_rsbl_T0_T1_cc();
6850 gen_op_rsbl_T0_T1();
6852 default: /* 5, 6, 7, 9, 12, 15. */
6856 gen_op_logic_T0_cc();
6858 gen_set_CF_bit31(cpu_T[1]);
6863 /* Translate a 32-bit thumb instruction. Returns nonzero if the instruction
6865 static int disas_thumb2_insn(CPUState *env, DisasContext *s, uint16_t insn_hw1)
6867 uint32_t insn, imm, shift, offset;
6868 uint32_t rd, rn, rm, rs;
6878 if (!(arm_feature(env, ARM_FEATURE_THUMB2)
6879 || arm_feature (env, ARM_FEATURE_M))) {
6880 /* Thumb-1 cores may need to treat bl and blx as a pair of
6881 16-bit instructions to get correct prefetch abort behavior. */
6883 if ((insn & (1 << 12)) == 0) {
6884 /* Second half of blx. */
6885 offset = ((insn & 0x7ff) << 1);
6886 tmp = load_reg(s, 14);
6887 tcg_gen_addi_i32(tmp, tmp, offset);
6888 tcg_gen_andi_i32(tmp, tmp, 0xfffffffc);
6891 tcg_gen_movi_i32(tmp2, s->pc | 1);
6892 store_reg(s, 14, tmp2);
6896 if (insn & (1 << 11)) {
6897 /* Second half of bl. */
6898 offset = ((insn & 0x7ff) << 1) | 1;
6899 tmp = load_reg(s, 14);
6900 tcg_gen_addi_i32(tmp, tmp, offset);
6903 tcg_gen_movi_i32(tmp2, s->pc | 1);
6904 store_reg(s, 14, tmp2);
6908 if ((s->pc & ~TARGET_PAGE_MASK) == 0) {
6909 /* Instruction spans a page boundary. Implement it as two
6910 16-bit instructions in case the second half causes an
6912 offset = ((int32_t)insn << 21) >> 9;
6913 gen_op_movl_T0_im(s->pc + 2 + offset);
6914 gen_movl_reg_T0(s, 14);
6917 /* Fall through to 32-bit decode. */
6920 insn = lduw_code(s->pc);
6922 insn |= (uint32_t)insn_hw1 << 16;
6924 if ((insn & 0xf800e800) != 0xf000e800) {
6928 rn = (insn >> 16) & 0xf;
6929 rs = (insn >> 12) & 0xf;
6930 rd = (insn >> 8) & 0xf;
6932 switch ((insn >> 25) & 0xf) {
6933 case 0: case 1: case 2: case 3:
6934 /* 16-bit instructions. Should never happen. */
6937 if (insn & (1 << 22)) {
6938 /* Other load/store, table branch. */
6939 if (insn & 0x01200000) {
6940 /* Load/store doubleword. */
6943 tcg_gen_movi_i32(addr, s->pc & ~3);
6945 addr = load_reg(s, rn);
6947 offset = (insn & 0xff) * 4;
6948 if ((insn & (1 << 23)) == 0)
6950 if (insn & (1 << 24)) {
6951 tcg_gen_addi_i32(addr, addr, offset);
6954 if (insn & (1 << 20)) {
6956 tmp = gen_ld32(addr, IS_USER(s));
6957 store_reg(s, rs, tmp);
6958 tcg_gen_addi_i32(addr, addr, 4);
6959 tmp = gen_ld32(addr, IS_USER(s));
6960 store_reg(s, rd, tmp);
6963 tmp = load_reg(s, rs);
6964 gen_st32(tmp, addr, IS_USER(s));
6965 tcg_gen_addi_i32(addr, addr, 4);
6966 tmp = load_reg(s, rd);
6967 gen_st32(tmp, addr, IS_USER(s));
6969 if (insn & (1 << 21)) {
6970 /* Base writeback. */
6973 tcg_gen_addi_i32(addr, addr, offset - 4);
6974 store_reg(s, rn, addr);
6978 } else if ((insn & (1 << 23)) == 0) {
6979 /* Load/store exclusive word. */
6980 gen_movl_T1_reg(s, rn);
6982 if (insn & (1 << 20)) {
6983 gen_helper_mark_exclusive(cpu_env, cpu_T[1]);
6984 tmp = gen_ld32(addr, IS_USER(s));
6985 store_reg(s, rd, tmp);
6987 int label = gen_new_label();
6988 gen_helper_test_exclusive(cpu_T[0], cpu_env, addr);
6989 tcg_gen_brcondi_i32(TCG_COND_NE, cpu_T[0],
6991 tmp = load_reg(s, rs);
6992 gen_st32(tmp, cpu_T[1], IS_USER(s));
6993 gen_set_label(label);
6994 gen_movl_reg_T0(s, rd);
6996 } else if ((insn & (1 << 6)) == 0) {
7000 tcg_gen_movi_i32(addr, s->pc);
7002 addr = load_reg(s, rn);
7004 tmp = load_reg(s, rm);
7005 tcg_gen_add_i32(addr, addr, tmp);
7006 if (insn & (1 << 4)) {
7008 tcg_gen_add_i32(addr, addr, tmp);
7010 tmp = gen_ld16u(addr, IS_USER(s));
7013 tmp = gen_ld8u(addr, IS_USER(s));
7016 tcg_gen_shli_i32(tmp, tmp, 1);
7017 tcg_gen_addi_i32(tmp, tmp, s->pc);
7018 store_reg(s, 15, tmp);
7020 /* Load/store exclusive byte/halfword/doubleword. */
7021 /* ??? These are not really atomic. However we know
7022 we never have multiple CPUs running in parallel,
7023 so it is good enough. */
7024 op = (insn >> 4) & 0x3;
7025 /* Must use a global reg for the address because we have
7026 a conditional branch in the store instruction. */
7027 gen_movl_T1_reg(s, rn);
7029 if (insn & (1 << 20)) {
7030 gen_helper_mark_exclusive(cpu_env, addr);
7033 tmp = gen_ld8u(addr, IS_USER(s));
7036 tmp = gen_ld16u(addr, IS_USER(s));
7039 tmp = gen_ld32(addr, IS_USER(s));
7040 tcg_gen_addi_i32(addr, addr, 4);
7041 tmp2 = gen_ld32(addr, IS_USER(s));
7042 store_reg(s, rd, tmp2);
7047 store_reg(s, rs, tmp);
7049 int label = gen_new_label();
7050 /* Must use a global that is not killed by the branch. */
7051 gen_helper_test_exclusive(cpu_T[0], cpu_env, addr);
7052 tcg_gen_brcondi_i32(TCG_COND_NE, cpu_T[0], 0, label);
7053 tmp = load_reg(s, rs);
7056 gen_st8(tmp, addr, IS_USER(s));
7059 gen_st16(tmp, addr, IS_USER(s));
7062 gen_st32(tmp, addr, IS_USER(s));
7063 tcg_gen_addi_i32(addr, addr, 4);
7064 tmp = load_reg(s, rd);
7065 gen_st32(tmp, addr, IS_USER(s));
7070 gen_set_label(label);
7071 gen_movl_reg_T0(s, rm);
7075 /* Load/store multiple, RFE, SRS. */
7076 if (((insn >> 23) & 1) == ((insn >> 24) & 1)) {
7077 /* Not available in user mode. */
7080 if (insn & (1 << 20)) {
7082 addr = load_reg(s, rn);
7083 if ((insn & (1 << 24)) == 0)
7084 tcg_gen_addi_i32(addr, addr, -8);
7085 /* Load PC into tmp and CPSR into tmp2. */
7086 tmp = gen_ld32(addr, 0);
7087 tcg_gen_addi_i32(addr, addr, 4);
7088 tmp2 = gen_ld32(addr, 0);
7089 if (insn & (1 << 21)) {
7090 /* Base writeback. */
7091 if (insn & (1 << 24)) {
7092 tcg_gen_addi_i32(addr, addr, 4);
7094 tcg_gen_addi_i32(addr, addr, -4);
7096 store_reg(s, rn, addr);
7100 gen_rfe(s, tmp, tmp2);
7104 if (op == (env->uncached_cpsr & CPSR_M)) {
7105 addr = load_reg(s, 13);
7108 gen_helper_get_r13_banked(addr, cpu_env, tcg_const_i32(op));
7110 if ((insn & (1 << 24)) == 0) {
7111 tcg_gen_addi_i32(addr, addr, -8);
7113 tmp = load_reg(s, 14);
7114 gen_st32(tmp, addr, 0);
7115 tcg_gen_addi_i32(addr, addr, 4);
7117 gen_helper_cpsr_read(tmp);
7118 gen_st32(tmp, addr, 0);
7119 if (insn & (1 << 21)) {
7120 if ((insn & (1 << 24)) == 0) {
7121 tcg_gen_addi_i32(addr, addr, -4);
7123 tcg_gen_addi_i32(addr, addr, 4);
7125 if (op == (env->uncached_cpsr & CPSR_M)) {
7126 store_reg(s, 13, addr);
7128 gen_helper_set_r13_banked(cpu_env,
7129 tcg_const_i32(op), addr);
7137 /* Load/store multiple. */
7138 addr = load_reg(s, rn);
7140 for (i = 0; i < 16; i++) {
7141 if (insn & (1 << i))
7144 if (insn & (1 << 24)) {
7145 tcg_gen_addi_i32(addr, addr, -offset);
7148 for (i = 0; i < 16; i++) {
7149 if ((insn & (1 << i)) == 0)
7151 if (insn & (1 << 20)) {
7153 tmp = gen_ld32(addr, IS_USER(s));
7157 store_reg(s, i, tmp);
7161 tmp = load_reg(s, i);
7162 gen_st32(tmp, addr, IS_USER(s));
7164 tcg_gen_addi_i32(addr, addr, 4);
7166 if (insn & (1 << 21)) {
7167 /* Base register writeback. */
7168 if (insn & (1 << 24)) {
7169 tcg_gen_addi_i32(addr, addr, -offset);
7171 /* Fault if writeback register is in register list. */
7172 if (insn & (1 << rn))
7174 store_reg(s, rn, addr);
7181 case 5: /* Data processing register constant shift. */
7183 gen_op_movl_T0_im(0);
7185 gen_movl_T0_reg(s, rn);
7186 gen_movl_T1_reg(s, rm);
7187 op = (insn >> 21) & 0xf;
7188 shiftop = (insn >> 4) & 3;
7189 shift = ((insn >> 6) & 3) | ((insn >> 10) & 0x1c);
7190 conds = (insn & (1 << 20)) != 0;
7191 logic_cc = (conds && thumb2_logic_op(op));
7192 gen_arm_shift_im(cpu_T[1], shiftop, shift, logic_cc);
7193 if (gen_thumb2_data_op(s, op, conds, 0))
7196 gen_movl_reg_T0(s, rd);
7198 case 13: /* Misc data processing. */
7199 op = ((insn >> 22) & 6) | ((insn >> 7) & 1);
7200 if (op < 4 && (insn & 0xf000) != 0xf000)
7203 case 0: /* Register controlled shift. */
7204 tmp = load_reg(s, rn);
7205 tmp2 = load_reg(s, rm);
7206 if ((insn & 0x70) != 0)
7208 op = (insn >> 21) & 3;
7209 logic_cc = (insn & (1 << 20)) != 0;
7210 gen_arm_shift_reg(tmp, op, tmp2, logic_cc);
7213 store_reg(s, rd, tmp);
7215 case 1: /* Sign/zero extend. */
7216 tmp = load_reg(s, rm);
7217 shift = (insn >> 4) & 3;
7218 /* ??? In many cases it's not neccessary to do a
7219 rotate, a shift is sufficient. */
7221 tcg_gen_rori_i32(tmp, tmp, shift * 8);
7222 op = (insn >> 20) & 7;
7224 case 0: gen_sxth(tmp); break;
7225 case 1: gen_uxth(tmp); break;
7226 case 2: gen_sxtb16(tmp); break;
7227 case 3: gen_uxtb16(tmp); break;
7228 case 4: gen_sxtb(tmp); break;
7229 case 5: gen_uxtb(tmp); break;
7230 default: goto illegal_op;
7233 tmp2 = load_reg(s, rn);
7234 if ((op >> 1) == 1) {
7235 gen_add16(tmp, tmp2);
7237 tcg_gen_add_i32(tmp, tmp, tmp2);
7241 store_reg(s, rd, tmp);
7243 case 2: /* SIMD add/subtract. */
7244 op = (insn >> 20) & 7;
7245 shift = (insn >> 4) & 7;
7246 if ((op & 3) == 3 || (shift & 3) == 3)
7248 tmp = load_reg(s, rn);
7249 tmp2 = load_reg(s, rm);
7250 gen_thumb2_parallel_addsub(op, shift, tmp, tmp2);
7252 store_reg(s, rd, tmp);
7254 case 3: /* Other data processing. */
7255 op = ((insn >> 17) & 0x38) | ((insn >> 4) & 7);
7257 /* Saturating add/subtract. */
7258 tmp = load_reg(s, rn);
7259 tmp2 = load_reg(s, rm);
7261 gen_helper_double_saturate(tmp, tmp);
7263 gen_helper_sub_saturate(tmp, tmp2, tmp);
7265 gen_helper_add_saturate(tmp, tmp, tmp2);
7268 tmp = load_reg(s, rn);
7270 case 0x0a: /* rbit */
7271 gen_helper_rbit(tmp, tmp);
7273 case 0x08: /* rev */
7274 tcg_gen_bswap_i32(tmp, tmp);
7276 case 0x09: /* rev16 */
7279 case 0x0b: /* revsh */
7282 case 0x10: /* sel */
7283 tmp2 = load_reg(s, rm);
7285 tcg_gen_ld_i32(tmp3, cpu_env, offsetof(CPUState, GE));
7286 gen_helper_sel_flags(tmp, tmp3, tmp, tmp2);
7290 case 0x18: /* clz */
7291 gen_helper_clz(tmp, tmp);
7297 store_reg(s, rd, tmp);
7299 case 4: case 5: /* 32-bit multiply. Sum of absolute differences. */
7300 op = (insn >> 4) & 0xf;
7301 tmp = load_reg(s, rn);
7302 tmp2 = load_reg(s, rm);
7303 switch ((insn >> 20) & 7) {
7304 case 0: /* 32 x 32 -> 32 */
7305 tcg_gen_mul_i32(tmp, tmp, tmp2);
7308 tmp2 = load_reg(s, rs);
7310 tcg_gen_sub_i32(tmp, tmp2, tmp);
7312 tcg_gen_add_i32(tmp, tmp, tmp2);
7316 case 1: /* 16 x 16 -> 32 */
7317 gen_mulxy(tmp, tmp2, op & 2, op & 1);
7320 tmp2 = load_reg(s, rs);
7321 gen_helper_add_setq(tmp, tmp, tmp2);
7325 case 2: /* Dual multiply add. */
7326 case 4: /* Dual multiply subtract. */
7328 gen_swap_half(tmp2);
7329 gen_smul_dual(tmp, tmp2);
7330 /* This addition cannot overflow. */
7331 if (insn & (1 << 22)) {
7332 tcg_gen_sub_i32(tmp, tmp, tmp2);
7334 tcg_gen_add_i32(tmp, tmp, tmp2);
7339 tmp2 = load_reg(s, rs);
7340 gen_helper_add_setq(tmp, tmp, tmp2);
7344 case 3: /* 32 * 16 -> 32msb */
7346 tcg_gen_sari_i32(tmp2, tmp2, 16);
7349 tmp2 = gen_muls_i64_i32(tmp, tmp2);
7350 tcg_gen_shri_i64(tmp2, tmp2, 16);
7352 tcg_gen_trunc_i64_i32(tmp, tmp2);
7355 tmp2 = load_reg(s, rs);
7356 gen_helper_add_setq(tmp, tmp, tmp2);
7360 case 5: case 6: /* 32 * 32 -> 32msb */
7361 gen_imull(tmp, tmp2);
7362 if (insn & (1 << 5)) {
7363 gen_roundqd(tmp, tmp2);
7370 tmp2 = load_reg(s, rs);
7371 if (insn & (1 << 21)) {
7372 tcg_gen_add_i32(tmp, tmp, tmp2);
7374 tcg_gen_sub_i32(tmp, tmp2, tmp);
7379 case 7: /* Unsigned sum of absolute differences. */
7380 gen_helper_usad8(tmp, tmp, tmp2);
7383 tmp2 = load_reg(s, rs);
7384 tcg_gen_add_i32(tmp, tmp, tmp2);
7389 store_reg(s, rd, tmp);
7391 case 6: case 7: /* 64-bit multiply, Divide. */
7392 op = ((insn >> 4) & 0xf) | ((insn >> 16) & 0x70);
7393 tmp = load_reg(s, rn);
7394 tmp2 = load_reg(s, rm);
7395 if ((op & 0x50) == 0x10) {
7397 if (!arm_feature(env, ARM_FEATURE_DIV))
7400 gen_helper_udiv(tmp, tmp, tmp2);
7402 gen_helper_sdiv(tmp, tmp, tmp2);
7404 store_reg(s, rd, tmp);
7405 } else if ((op & 0xe) == 0xc) {
7406 /* Dual multiply accumulate long. */
7408 gen_swap_half(tmp2);
7409 gen_smul_dual(tmp, tmp2);
7411 tcg_gen_sub_i32(tmp, tmp, tmp2);
7413 tcg_gen_add_i32(tmp, tmp, tmp2);
7416 tmp2 = tcg_temp_new(TCG_TYPE_I64);
7417 gen_addq(s, tmp, rs, rd);
7418 gen_storeq_reg(s, rs, rd, tmp);
7421 /* Unsigned 64-bit multiply */
7422 tmp = gen_mulu_i64_i32(tmp, tmp2);
7426 gen_mulxy(tmp, tmp2, op & 2, op & 1);
7428 tmp2 = tcg_temp_new(TCG_TYPE_I64);
7429 tcg_gen_ext_i32_i64(tmp2, tmp);
7433 /* Signed 64-bit multiply */
7434 tmp = gen_muls_i64_i32(tmp, tmp2);
7439 gen_addq_lo(s, tmp, rs);
7440 gen_addq_lo(s, tmp, rd);
7441 } else if (op & 0x40) {
7442 /* 64-bit accumulate. */
7443 gen_addq(s, tmp, rs, rd);
7445 gen_storeq_reg(s, rs, rd, tmp);
7450 case 6: case 7: case 14: case 15:
7452 if (((insn >> 24) & 3) == 3) {
7453 /* Translate into the equivalent ARM encoding. */
7454 insn = (insn & 0xe2ffffff) | ((insn & (1 << 28)) >> 4);
7455 if (disas_neon_data_insn(env, s, insn))
7458 if (insn & (1 << 28))
7460 if (disas_coproc_insn (env, s, insn))
7464 case 8: case 9: case 10: case 11:
7465 if (insn & (1 << 15)) {
7466 /* Branches, misc control. */
7467 if (insn & 0x5000) {
7468 /* Unconditional branch. */
7469 /* signextend(hw1[10:0]) -> offset[:12]. */
7470 offset = ((int32_t)insn << 5) >> 9 & ~(int32_t)0xfff;
7471 /* hw1[10:0] -> offset[11:1]. */
7472 offset |= (insn & 0x7ff) << 1;
7473 /* (~hw2[13, 11] ^ offset[24]) -> offset[23,22]
7474 offset[24:22] already have the same value because of the
7475 sign extension above. */
7476 offset ^= ((~insn) & (1 << 13)) << 10;
7477 offset ^= ((~insn) & (1 << 11)) << 11;
7479 if (insn & (1 << 14)) {
7480 /* Branch and link. */
7481 gen_op_movl_T1_im(s->pc | 1);
7482 gen_movl_reg_T1(s, 14);
7486 if (insn & (1 << 12)) {
7491 offset &= ~(uint32_t)2;
7492 gen_bx_im(s, offset);
7494 } else if (((insn >> 23) & 7) == 7) {
7496 if (insn & (1 << 13))
7499 if (insn & (1 << 26)) {
7500 /* Secure monitor call (v6Z) */
7501 goto illegal_op; /* not implemented. */
7503 op = (insn >> 20) & 7;
7505 case 0: /* msr cpsr. */
7507 tmp = load_reg(s, rn);
7508 addr = tcg_const_i32(insn & 0xff);
7509 gen_helper_v7m_msr(cpu_env, addr, tmp);
7514 case 1: /* msr spsr. */
7517 gen_movl_T0_reg(s, rn);
7518 if (gen_set_psr_T0(s,
7519 msr_mask(env, s, (insn >> 8) & 0xf, op == 1),
7523 case 2: /* cps, nop-hint. */
7524 if (((insn >> 8) & 7) == 0) {
7525 gen_nop_hint(s, insn & 0xff);
7527 /* Implemented as NOP in user mode. */
7532 if (insn & (1 << 10)) {
7533 if (insn & (1 << 7))
7535 if (insn & (1 << 6))
7537 if (insn & (1 << 5))
7539 if (insn & (1 << 9))
7540 imm = CPSR_A | CPSR_I | CPSR_F;
7542 if (insn & (1 << 8)) {
7544 imm |= (insn & 0x1f);
7547 gen_op_movl_T0_im(imm);
7548 gen_set_psr_T0(s, offset, 0);
7551 case 3: /* Special control operations. */
7552 op = (insn >> 4) & 0xf;
7555 gen_helper_clrex(cpu_env);
7560 /* These execute as NOPs. */
7568 /* Trivial implementation equivalent to bx. */
7569 tmp = load_reg(s, rn);
7572 case 5: /* Exception return. */
7573 /* Unpredictable in user mode. */
7575 case 6: /* mrs cpsr. */
7578 addr = tcg_const_i32(insn & 0xff);
7579 gen_helper_v7m_mrs(tmp, cpu_env, addr);
7581 gen_helper_cpsr_read(tmp);
7583 store_reg(s, rd, tmp);
7585 case 7: /* mrs spsr. */
7586 /* Not accessible in user mode. */
7587 if (IS_USER(s) || IS_M(env))
7589 tmp = load_cpu_field(spsr);
7590 store_reg(s, rd, tmp);
7595 /* Conditional branch. */
7596 op = (insn >> 22) & 0xf;
7597 /* Generate a conditional jump to next instruction. */
7598 s->condlabel = gen_new_label();
7599 gen_test_cc(op ^ 1, s->condlabel);
7602 /* offset[11:1] = insn[10:0] */
7603 offset = (insn & 0x7ff) << 1;
7604 /* offset[17:12] = insn[21:16]. */
7605 offset |= (insn & 0x003f0000) >> 4;
7606 /* offset[31:20] = insn[26]. */
7607 offset |= ((int32_t)((insn << 5) & 0x80000000)) >> 11;
7608 /* offset[18] = insn[13]. */
7609 offset |= (insn & (1 << 13)) << 5;
7610 /* offset[19] = insn[11]. */
7611 offset |= (insn & (1 << 11)) << 8;
7613 /* jump to the offset */
7614 gen_jmp(s, s->pc + offset);
7617 /* Data processing immediate. */
7618 if (insn & (1 << 25)) {
7619 if (insn & (1 << 24)) {
7620 if (insn & (1 << 20))
7622 /* Bitfield/Saturate. */
7623 op = (insn >> 21) & 7;
7625 shift = ((insn >> 6) & 3) | ((insn >> 10) & 0x1c);
7628 tcg_gen_movi_i32(tmp, 0);
7630 tmp = load_reg(s, rn);
7633 case 2: /* Signed bitfield extract. */
7635 if (shift + imm > 32)
7638 gen_sbfx(tmp, shift, imm);
7640 case 6: /* Unsigned bitfield extract. */
7642 if (shift + imm > 32)
7645 gen_ubfx(tmp, shift, (1u << imm) - 1);
7647 case 3: /* Bitfield insert/clear. */
7650 imm = imm + 1 - shift;
7652 tmp2 = load_reg(s, rd);
7653 gen_bfi(tmp, tmp2, tmp, shift, (1u << imm) - 1);
7659 default: /* Saturate. */
7662 tcg_gen_sari_i32(tmp, tmp, shift);
7664 tcg_gen_shli_i32(tmp, tmp, shift);
7666 tmp2 = tcg_const_i32(imm);
7669 if ((op & 1) && shift == 0)
7670 gen_helper_usat16(tmp, tmp, tmp2);
7672 gen_helper_usat(tmp, tmp, tmp2);
7675 if ((op & 1) && shift == 0)
7676 gen_helper_ssat16(tmp, tmp, tmp2);
7678 gen_helper_ssat(tmp, tmp, tmp2);
7682 store_reg(s, rd, tmp);
7684 imm = ((insn & 0x04000000) >> 15)
7685 | ((insn & 0x7000) >> 4) | (insn & 0xff);
7686 if (insn & (1 << 22)) {
7687 /* 16-bit immediate. */
7688 imm |= (insn >> 4) & 0xf000;
7689 if (insn & (1 << 23)) {
7691 tmp = load_reg(s, rd);
7692 tcg_gen_ext16u_i32(tmp, tmp);
7693 tcg_gen_ori_i32(tmp, tmp, imm << 16);
7697 tcg_gen_movi_i32(tmp, imm);
7700 /* Add/sub 12-bit immediate. */
7702 offset = s->pc & ~(uint32_t)3;
7703 if (insn & (1 << 23))
7708 tcg_gen_movi_i32(tmp, offset);
7710 tmp = load_reg(s, rn);
7711 if (insn & (1 << 23))
7712 tcg_gen_subi_i32(tmp, tmp, imm);
7714 tcg_gen_addi_i32(tmp, tmp, imm);
7717 store_reg(s, rd, tmp);
7720 int shifter_out = 0;
7721 /* modified 12-bit immediate. */
7722 shift = ((insn & 0x04000000) >> 23) | ((insn & 0x7000) >> 12);
7723 imm = (insn & 0xff);
7726 /* Nothing to do. */
7728 case 1: /* 00XY00XY */
7731 case 2: /* XY00XY00 */
7735 case 3: /* XYXYXYXY */
7739 default: /* Rotated constant. */
7740 shift = (shift << 1) | (imm >> 7);
7742 imm = imm << (32 - shift);
7746 gen_op_movl_T1_im(imm);
7747 rn = (insn >> 16) & 0xf;
7749 gen_op_movl_T0_im(0);
7751 gen_movl_T0_reg(s, rn);
7752 op = (insn >> 21) & 0xf;
7753 if (gen_thumb2_data_op(s, op, (insn & (1 << 20)) != 0,
7756 rd = (insn >> 8) & 0xf;
7758 gen_movl_reg_T0(s, rd);
7763 case 12: /* Load/store single data item. */
7768 if ((insn & 0x01100000) == 0x01000000) {
7769 if (disas_neon_ls_insn(env, s, insn))
7777 /* s->pc has already been incremented by 4. */
7778 imm = s->pc & 0xfffffffc;
7779 if (insn & (1 << 23))
7780 imm += insn & 0xfff;
7782 imm -= insn & 0xfff;
7783 tcg_gen_movi_i32(addr, imm);
7785 addr = load_reg(s, rn);
7786 if (insn & (1 << 23)) {
7787 /* Positive offset. */
7789 tcg_gen_addi_i32(addr, addr, imm);
7791 op = (insn >> 8) & 7;
7794 case 0: case 8: /* Shifted Register. */
7795 shift = (insn >> 4) & 0xf;
7798 tmp = load_reg(s, rm);
7800 tcg_gen_shli_i32(tmp, tmp, shift);
7801 tcg_gen_add_i32(addr, addr, tmp);
7804 case 4: /* Negative offset. */
7805 tcg_gen_addi_i32(addr, addr, -imm);
7807 case 6: /* User privilege. */
7808 tcg_gen_addi_i32(addr, addr, imm);
7811 case 1: /* Post-decrement. */
7814 case 3: /* Post-increment. */
7818 case 5: /* Pre-decrement. */
7821 case 7: /* Pre-increment. */
7822 tcg_gen_addi_i32(addr, addr, imm);
7830 op = ((insn >> 21) & 3) | ((insn >> 22) & 4);
7831 if (insn & (1 << 20)) {
7833 if (rs == 15 && op != 2) {
7836 /* Memory hint. Implemented as NOP. */
7839 case 0: tmp = gen_ld8u(addr, user); break;
7840 case 4: tmp = gen_ld8s(addr, user); break;
7841 case 1: tmp = gen_ld16u(addr, user); break;
7842 case 5: tmp = gen_ld16s(addr, user); break;
7843 case 2: tmp = gen_ld32(addr, user); break;
7844 default: goto illegal_op;
7849 store_reg(s, rs, tmp);
7856 tmp = load_reg(s, rs);
7858 case 0: gen_st8(tmp, addr, user); break;
7859 case 1: gen_st16(tmp, addr, user); break;
7860 case 2: gen_st32(tmp, addr, user); break;
7861 default: goto illegal_op;
7865 tcg_gen_addi_i32(addr, addr, imm);
7867 store_reg(s, rn, addr);
7881 static void disas_thumb_insn(CPUState *env, DisasContext *s)
7883 uint32_t val, insn, op, rm, rn, rd, shift, cond;
7890 if (s->condexec_mask) {
7891 cond = s->condexec_cond;
7892 s->condlabel = gen_new_label();
7893 gen_test_cc(cond ^ 1, s->condlabel);
7897 insn = lduw_code(s->pc);
7900 switch (insn >> 12) {
7903 op = (insn >> 11) & 3;
7906 rn = (insn >> 3) & 7;
7907 gen_movl_T0_reg(s, rn);
7908 if (insn & (1 << 10)) {
7910 gen_op_movl_T1_im((insn >> 6) & 7);
7913 rm = (insn >> 6) & 7;
7914 gen_movl_T1_reg(s, rm);
7916 if (insn & (1 << 9)) {
7917 if (s->condexec_mask)
7918 gen_op_subl_T0_T1();
7920 gen_op_subl_T0_T1_cc();
7922 if (s->condexec_mask)
7923 gen_op_addl_T0_T1();
7925 gen_op_addl_T0_T1_cc();
7927 gen_movl_reg_T0(s, rd);
7929 /* shift immediate */
7930 rm = (insn >> 3) & 7;
7931 shift = (insn >> 6) & 0x1f;
7932 tmp = load_reg(s, rm);
7933 gen_arm_shift_im(tmp, op, shift, s->condexec_mask == 0);
7934 if (!s->condexec_mask)
7936 store_reg(s, rd, tmp);
7940 /* arithmetic large immediate */
7941 op = (insn >> 11) & 3;
7942 rd = (insn >> 8) & 0x7;
7944 gen_op_movl_T0_im(insn & 0xff);
7946 gen_movl_T0_reg(s, rd);
7947 gen_op_movl_T1_im(insn & 0xff);
7951 if (!s->condexec_mask)
7952 gen_op_logic_T0_cc();
7955 gen_op_subl_T0_T1_cc();
7958 if (s->condexec_mask)
7959 gen_op_addl_T0_T1();
7961 gen_op_addl_T0_T1_cc();
7964 if (s->condexec_mask)
7965 gen_op_subl_T0_T1();
7967 gen_op_subl_T0_T1_cc();
7971 gen_movl_reg_T0(s, rd);
7974 if (insn & (1 << 11)) {
7975 rd = (insn >> 8) & 7;
7976 /* load pc-relative. Bit 1 of PC is ignored. */
7977 val = s->pc + 2 + ((insn & 0xff) * 4);
7978 val &= ~(uint32_t)2;
7980 tcg_gen_movi_i32(addr, val);
7981 tmp = gen_ld32(addr, IS_USER(s));
7983 store_reg(s, rd, tmp);
7986 if (insn & (1 << 10)) {
7987 /* data processing extended or blx */
7988 rd = (insn & 7) | ((insn >> 4) & 8);
7989 rm = (insn >> 3) & 0xf;
7990 op = (insn >> 8) & 3;
7993 gen_movl_T0_reg(s, rd);
7994 gen_movl_T1_reg(s, rm);
7995 gen_op_addl_T0_T1();
7996 gen_movl_reg_T0(s, rd);
7999 gen_movl_T0_reg(s, rd);
8000 gen_movl_T1_reg(s, rm);
8001 gen_op_subl_T0_T1_cc();
8003 case 2: /* mov/cpy */
8004 gen_movl_T0_reg(s, rm);
8005 gen_movl_reg_T0(s, rd);
8007 case 3:/* branch [and link] exchange thumb register */
8008 tmp = load_reg(s, rm);
8009 if (insn & (1 << 7)) {
8010 val = (uint32_t)s->pc | 1;
8012 tcg_gen_movi_i32(tmp2, val);
8013 store_reg(s, 14, tmp2);
8021 /* data processing register */
8023 rm = (insn >> 3) & 7;
8024 op = (insn >> 6) & 0xf;
8025 if (op == 2 || op == 3 || op == 4 || op == 7) {
8026 /* the shift/rotate ops want the operands backwards */
8035 if (op == 9) /* neg */
8036 gen_op_movl_T0_im(0);
8037 else if (op != 0xf) /* mvn doesn't read its first operand */
8038 gen_movl_T0_reg(s, rd);
8040 gen_movl_T1_reg(s, rm);
8043 gen_op_andl_T0_T1();
8044 if (!s->condexec_mask)
8045 gen_op_logic_T0_cc();
8048 gen_op_xorl_T0_T1();
8049 if (!s->condexec_mask)
8050 gen_op_logic_T0_cc();
8053 if (s->condexec_mask) {
8054 gen_helper_shl(cpu_T[1], cpu_T[1], cpu_T[0]);
8056 gen_helper_shl_cc(cpu_T[1], cpu_T[1], cpu_T[0]);
8057 gen_op_logic_T1_cc();
8061 if (s->condexec_mask) {
8062 gen_helper_shr(cpu_T[1], cpu_T[1], cpu_T[0]);
8064 gen_helper_shr_cc(cpu_T[1], cpu_T[1], cpu_T[0]);
8065 gen_op_logic_T1_cc();
8069 if (s->condexec_mask) {
8070 gen_helper_sar(cpu_T[1], cpu_T[1], cpu_T[0]);
8072 gen_helper_sar_cc(cpu_T[1], cpu_T[1], cpu_T[0]);
8073 gen_op_logic_T1_cc();
8077 if (s->condexec_mask)
8080 gen_op_adcl_T0_T1_cc();
8083 if (s->condexec_mask)
8086 gen_op_sbcl_T0_T1_cc();
8089 if (s->condexec_mask) {
8090 gen_helper_ror(cpu_T[1], cpu_T[1], cpu_T[0]);
8092 gen_helper_ror_cc(cpu_T[1], cpu_T[1], cpu_T[0]);
8093 gen_op_logic_T1_cc();
8097 gen_op_andl_T0_T1();
8098 gen_op_logic_T0_cc();
8102 if (s->condexec_mask)
8103 tcg_gen_neg_i32(cpu_T[0], cpu_T[1]);
8105 gen_op_subl_T0_T1_cc();
8108 gen_op_subl_T0_T1_cc();
8112 gen_op_addl_T0_T1_cc();
8117 if (!s->condexec_mask)
8118 gen_op_logic_T0_cc();
8121 gen_op_mull_T0_T1();
8122 if (!s->condexec_mask)
8123 gen_op_logic_T0_cc();
8126 gen_op_bicl_T0_T1();
8127 if (!s->condexec_mask)
8128 gen_op_logic_T0_cc();
8132 if (!s->condexec_mask)
8133 gen_op_logic_T1_cc();
8140 gen_movl_reg_T1(s, rm);
8142 gen_movl_reg_T0(s, rd);
8147 /* load/store register offset. */
8149 rn = (insn >> 3) & 7;
8150 rm = (insn >> 6) & 7;
8151 op = (insn >> 9) & 7;
8152 addr = load_reg(s, rn);
8153 tmp = load_reg(s, rm);
8154 tcg_gen_add_i32(addr, addr, tmp);
8157 if (op < 3) /* store */
8158 tmp = load_reg(s, rd);
8162 gen_st32(tmp, addr, IS_USER(s));
8165 gen_st16(tmp, addr, IS_USER(s));
8168 gen_st8(tmp, addr, IS_USER(s));
8171 tmp = gen_ld8s(addr, IS_USER(s));
8174 tmp = gen_ld32(addr, IS_USER(s));
8177 tmp = gen_ld16u(addr, IS_USER(s));
8180 tmp = gen_ld8u(addr, IS_USER(s));
8183 tmp = gen_ld16s(addr, IS_USER(s));
8186 if (op >= 3) /* load */
8187 store_reg(s, rd, tmp);
8192 /* load/store word immediate offset */
8194 rn = (insn >> 3) & 7;
8195 addr = load_reg(s, rn);
8196 val = (insn >> 4) & 0x7c;
8197 tcg_gen_addi_i32(addr, addr, val);
8199 if (insn & (1 << 11)) {
8201 tmp = gen_ld32(addr, IS_USER(s));
8202 store_reg(s, rd, tmp);
8205 tmp = load_reg(s, rd);
8206 gen_st32(tmp, addr, IS_USER(s));
8212 /* load/store byte immediate offset */
8214 rn = (insn >> 3) & 7;
8215 addr = load_reg(s, rn);
8216 val = (insn >> 6) & 0x1f;
8217 tcg_gen_addi_i32(addr, addr, val);
8219 if (insn & (1 << 11)) {
8221 tmp = gen_ld8u(addr, IS_USER(s));
8222 store_reg(s, rd, tmp);
8225 tmp = load_reg(s, rd);
8226 gen_st8(tmp, addr, IS_USER(s));
8232 /* load/store halfword immediate offset */
8234 rn = (insn >> 3) & 7;
8235 addr = load_reg(s, rn);
8236 val = (insn >> 5) & 0x3e;
8237 tcg_gen_addi_i32(addr, addr, val);
8239 if (insn & (1 << 11)) {
8241 tmp = gen_ld16u(addr, IS_USER(s));
8242 store_reg(s, rd, tmp);
8245 tmp = load_reg(s, rd);
8246 gen_st16(tmp, addr, IS_USER(s));
8252 /* load/store from stack */
8253 rd = (insn >> 8) & 7;
8254 addr = load_reg(s, 13);
8255 val = (insn & 0xff) * 4;
8256 tcg_gen_addi_i32(addr, addr, val);
8258 if (insn & (1 << 11)) {
8260 tmp = gen_ld32(addr, IS_USER(s));
8261 store_reg(s, rd, tmp);
8264 tmp = load_reg(s, rd);
8265 gen_st32(tmp, addr, IS_USER(s));
8271 /* add to high reg */
8272 rd = (insn >> 8) & 7;
8273 if (insn & (1 << 11)) {
8275 tmp = load_reg(s, 13);
8277 /* PC. bit 1 is ignored. */
8279 tcg_gen_movi_i32(tmp, (s->pc + 2) & ~(uint32_t)2);
8281 val = (insn & 0xff) * 4;
8282 tcg_gen_addi_i32(tmp, tmp, val);
8283 store_reg(s, rd, tmp);
8288 op = (insn >> 8) & 0xf;
8291 /* adjust stack pointer */
8292 tmp = load_reg(s, 13);
8293 val = (insn & 0x7f) * 4;
8294 if (insn & (1 << 7))
8295 val = -(int32_t)val;
8296 tcg_gen_addi_i32(tmp, tmp, val);
8297 store_reg(s, 13, tmp);
8300 case 2: /* sign/zero extend. */
8303 rm = (insn >> 3) & 7;
8304 tmp = load_reg(s, rm);
8305 switch ((insn >> 6) & 3) {
8306 case 0: gen_sxth(tmp); break;
8307 case 1: gen_sxtb(tmp); break;
8308 case 2: gen_uxth(tmp); break;
8309 case 3: gen_uxtb(tmp); break;
8311 store_reg(s, rd, tmp);
8313 case 4: case 5: case 0xc: case 0xd:
8315 addr = load_reg(s, 13);
8316 if (insn & (1 << 8))
8320 for (i = 0; i < 8; i++) {
8321 if (insn & (1 << i))
8324 if ((insn & (1 << 11)) == 0) {
8325 tcg_gen_addi_i32(addr, addr, -offset);
8327 for (i = 0; i < 8; i++) {
8328 if (insn & (1 << i)) {
8329 if (insn & (1 << 11)) {
8331 tmp = gen_ld32(addr, IS_USER(s));
8332 store_reg(s, i, tmp);
8335 tmp = load_reg(s, i);
8336 gen_st32(tmp, addr, IS_USER(s));
8338 /* advance to the next address. */
8339 tcg_gen_addi_i32(addr, addr, 4);
8342 if (insn & (1 << 8)) {
8343 if (insn & (1 << 11)) {
8345 tmp = gen_ld32(addr, IS_USER(s));
8346 /* don't set the pc until the rest of the instruction
8350 tmp = load_reg(s, 14);
8351 gen_st32(tmp, addr, IS_USER(s));
8353 tcg_gen_addi_i32(addr, addr, 4);
8355 if ((insn & (1 << 11)) == 0) {
8356 tcg_gen_addi_i32(addr, addr, -offset);
8358 /* write back the new stack pointer */
8359 store_reg(s, 13, addr);
8360 /* set the new PC value */
8361 if ((insn & 0x0900) == 0x0900)
8365 case 1: case 3: case 9: case 11: /* czb */
8367 tmp = load_reg(s, rm);
8368 s->condlabel = gen_new_label();
8370 if (insn & (1 << 11))
8371 tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 0, s->condlabel);
8373 tcg_gen_brcondi_i32(TCG_COND_NE, tmp, 0, s->condlabel);
8375 offset = ((insn & 0xf8) >> 2) | (insn & 0x200) >> 3;
8376 val = (uint32_t)s->pc + 2;
8381 case 15: /* IT, nop-hint. */
8382 if ((insn & 0xf) == 0) {
8383 gen_nop_hint(s, (insn >> 4) & 0xf);
8387 s->condexec_cond = (insn >> 4) & 0xe;
8388 s->condexec_mask = insn & 0x1f;
8389 /* No actual code generated for this insn, just setup state. */
8392 case 0xe: /* bkpt */
8393 gen_set_condexec(s);
8394 gen_set_pc_im(s->pc - 2);
8395 gen_exception(EXCP_BKPT);
8396 s->is_jmp = DISAS_JUMP;
8401 rn = (insn >> 3) & 0x7;
8403 tmp = load_reg(s, rn);
8404 switch ((insn >> 6) & 3) {
8405 case 0: tcg_gen_bswap_i32(tmp, tmp); break;
8406 case 1: gen_rev16(tmp); break;
8407 case 3: gen_revsh(tmp); break;
8408 default: goto illegal_op;
8410 store_reg(s, rd, tmp);
8418 tmp = tcg_const_i32((insn & (1 << 4)) != 0);
8421 addr = tcg_const_i32(16);
8422 gen_helper_v7m_msr(cpu_env, addr, tmp);
8426 addr = tcg_const_i32(17);
8427 gen_helper_v7m_msr(cpu_env, addr, tmp);
8431 if (insn & (1 << 4))
8432 shift = CPSR_A | CPSR_I | CPSR_F;
8436 val = ((insn & 7) << 6) & shift;
8437 gen_op_movl_T0_im(val);
8438 gen_set_psr_T0(s, shift, 0);
8448 /* load/store multiple */
8449 rn = (insn >> 8) & 0x7;
8450 addr = load_reg(s, rn);
8451 for (i = 0; i < 8; i++) {
8452 if (insn & (1 << i)) {
8453 if (insn & (1 << 11)) {
8455 tmp = gen_ld32(addr, IS_USER(s));
8456 store_reg(s, i, tmp);
8459 tmp = load_reg(s, i);
8460 gen_st32(tmp, addr, IS_USER(s));
8462 /* advance to the next address */
8463 tcg_gen_addi_i32(addr, addr, 4);
8466 /* Base register writeback. */
8467 if ((insn & (1 << rn)) == 0) {
8468 store_reg(s, rn, addr);
8475 /* conditional branch or swi */
8476 cond = (insn >> 8) & 0xf;
8482 gen_set_condexec(s);
8483 gen_set_pc_im(s->pc);
8484 s->is_jmp = DISAS_SWI;
8487 /* generate a conditional jump to next instruction */
8488 s->condlabel = gen_new_label();
8489 gen_test_cc(cond ^ 1, s->condlabel);
8491 gen_movl_T1_reg(s, 15);
8493 /* jump to the offset */
8494 val = (uint32_t)s->pc + 2;
8495 offset = ((int32_t)insn << 24) >> 24;
8501 if (insn & (1 << 11)) {
8502 if (disas_thumb2_insn(env, s, insn))
8506 /* unconditional branch */
8507 val = (uint32_t)s->pc;
8508 offset = ((int32_t)insn << 21) >> 21;
8509 val += (offset << 1) + 2;
8514 if (disas_thumb2_insn(env, s, insn))
8520 gen_set_condexec(s);
8521 gen_set_pc_im(s->pc - 4);
8522 gen_exception(EXCP_UDEF);
8523 s->is_jmp = DISAS_JUMP;
8527 gen_set_condexec(s);
8528 gen_set_pc_im(s->pc - 2);
8529 gen_exception(EXCP_UDEF);
8530 s->is_jmp = DISAS_JUMP;
8533 /* generate intermediate code in gen_opc_buf and gen_opparam_buf for
8534 basic block 'tb'. If search_pc is TRUE, also generate PC
8535 information for each intermediate instruction. */
8536 static inline int gen_intermediate_code_internal(CPUState *env,
8537 TranslationBlock *tb,
8540 DisasContext dc1, *dc = &dc1;
8541 uint16_t *gen_opc_end;
8543 target_ulong pc_start;
8544 uint32_t next_page_start;
8548 /* generate intermediate code */
8550 memset(temps, 0, sizeof(temps));
8556 gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
8558 dc->is_jmp = DISAS_NEXT;
8560 dc->singlestep_enabled = env->singlestep_enabled;
8562 dc->thumb = env->thumb;
8563 dc->condexec_mask = (env->condexec_bits & 0xf) << 1;
8564 dc->condexec_cond = env->condexec_bits >> 4;
8566 #if !defined(CONFIG_USER_ONLY)
8568 dc->user = ((env->v7m.exception == 0) && (env->v7m.control & 1));
8570 dc->user = (env->uncached_cpsr & 0x1f) == ARM_CPU_MODE_USR;
8573 cpu_F0s = tcg_temp_new(TCG_TYPE_I32);
8574 cpu_F1s = tcg_temp_new(TCG_TYPE_I32);
8575 cpu_F0d = tcg_temp_new(TCG_TYPE_I64);
8576 cpu_F1d = tcg_temp_new(TCG_TYPE_I64);
8579 /* FIXME: cpu_M0 can probably be the same as cpu_V0. */
8580 cpu_M0 = tcg_temp_new(TCG_TYPE_I64);
8581 next_page_start = (pc_start & TARGET_PAGE_MASK) + TARGET_PAGE_SIZE;
8584 max_insns = tb->cflags & CF_COUNT_MASK;
8586 max_insns = CF_COUNT_MASK;
8589 /* Reset the conditional execution bits immediately. This avoids
8590 complications trying to do it at the end of the block. */
8591 if (env->condexec_bits)
8593 TCGv tmp = new_tmp();
8594 tcg_gen_movi_i32(tmp, 0);
8595 store_cpu_field(tmp, condexec_bits);
8598 #ifdef CONFIG_USER_ONLY
8599 /* Intercept jump to the magic kernel page. */
8600 if (dc->pc >= 0xffff0000) {
8601 /* We always get here via a jump, so know we are not in a
8602 conditional execution block. */
8603 gen_exception(EXCP_KERNEL_TRAP);
8604 dc->is_jmp = DISAS_UPDATE;
8608 if (dc->pc >= 0xfffffff0 && IS_M(env)) {
8609 /* We always get here via a jump, so know we are not in a
8610 conditional execution block. */
8611 gen_exception(EXCP_EXCEPTION_EXIT);
8615 if (env->nb_breakpoints > 0) {
8616 for(j = 0; j < env->nb_breakpoints; j++) {
8617 if (env->breakpoints[j] == dc->pc) {
8618 gen_set_condexec(dc);
8619 gen_set_pc_im(dc->pc);
8620 gen_exception(EXCP_DEBUG);
8621 dc->is_jmp = DISAS_JUMP;
8622 /* Advance PC so that clearing the breakpoint will
8623 invalidate this TB. */
8625 goto done_generating;
8631 j = gen_opc_ptr - gen_opc_buf;
8635 gen_opc_instr_start[lj++] = 0;
8637 gen_opc_pc[lj] = dc->pc;
8638 gen_opc_instr_start[lj] = 1;
8639 gen_opc_icount[lj] = num_insns;
8642 if (num_insns + 1 == max_insns && (tb->cflags & CF_LAST_IO))
8646 disas_thumb_insn(env, dc);
8647 if (dc->condexec_mask) {
8648 dc->condexec_cond = (dc->condexec_cond & 0xe)
8649 | ((dc->condexec_mask >> 4) & 1);
8650 dc->condexec_mask = (dc->condexec_mask << 1) & 0x1f;
8651 if (dc->condexec_mask == 0) {
8652 dc->condexec_cond = 0;
8656 disas_arm_insn(env, dc);
8659 fprintf(stderr, "Internal resource leak before %08x\n", dc->pc);
8663 if (dc->condjmp && !dc->is_jmp) {
8664 gen_set_label(dc->condlabel);
8667 /* Terminate the TB on memory ops if watchpoints are present. */
8668 /* FIXME: This should be replacd by the deterministic execution
8669 * IRQ raising bits. */
8670 if (dc->is_mem && env->nb_watchpoints)
8673 /* Translation stops when a conditional branch is enoutered.
8674 * Otherwise the subsequent code could get translated several times.
8675 * Also stop translation when a page boundary is reached. This
8676 * ensures prefech aborts occur at the right place. */
8678 } while (!dc->is_jmp && gen_opc_ptr < gen_opc_end &&
8679 !env->singlestep_enabled &&
8680 dc->pc < next_page_start &&
8681 num_insns < max_insns);
8683 if (tb->cflags & CF_LAST_IO) {
8685 /* FIXME: This can theoretically happen with self-modifying
8687 cpu_abort(env, "IO on conditional branch instruction");
8692 /* At this stage dc->condjmp will only be set when the skipped
8693 instruction was a conditional branch or trap, and the PC has
8694 already been written. */
8695 if (__builtin_expect(env->singlestep_enabled, 0)) {
8696 /* Make sure the pc is updated, and raise a debug exception. */
8698 gen_set_condexec(dc);
8699 if (dc->is_jmp == DISAS_SWI) {
8700 gen_exception(EXCP_SWI);
8702 gen_exception(EXCP_DEBUG);
8704 gen_set_label(dc->condlabel);
8706 if (dc->condjmp || !dc->is_jmp) {
8707 gen_set_pc_im(dc->pc);
8710 gen_set_condexec(dc);
8711 if (dc->is_jmp == DISAS_SWI && !dc->condjmp) {
8712 gen_exception(EXCP_SWI);
8714 /* FIXME: Single stepping a WFI insn will not halt
8716 gen_exception(EXCP_DEBUG);
8719 /* While branches must always occur at the end of an IT block,
8720 there are a few other things that can cause us to terminate
8721 the TB in the middel of an IT block:
8722 - Exception generating instructions (bkpt, swi, undefined).
8724 - Hardware watchpoints.
8725 Hardware breakpoints have already been handled and skip this code.
8727 gen_set_condexec(dc);
8728 switch(dc->is_jmp) {
8730 gen_goto_tb(dc, 1, dc->pc);
8735 /* indicate that the hash table must be used to find the next TB */
8739 /* nothing more to generate */
8745 gen_exception(EXCP_SWI);
8749 gen_set_label(dc->condlabel);
8750 gen_set_condexec(dc);
8751 gen_goto_tb(dc, 1, dc->pc);
8757 gen_icount_end(tb, num_insns);
8758 *gen_opc_ptr = INDEX_op_end;
8761 if (loglevel & CPU_LOG_TB_IN_ASM) {
8762 fprintf(logfile, "----------------\n");
8763 fprintf(logfile, "IN: %s\n", lookup_symbol(pc_start));
8764 target_disas(logfile, pc_start, dc->pc - pc_start, env->thumb);
8765 fprintf(logfile, "\n");
8769 j = gen_opc_ptr - gen_opc_buf;
8772 gen_opc_instr_start[lj++] = 0;
8774 tb->size = dc->pc - pc_start;
8775 tb->icount = num_insns;
8780 int gen_intermediate_code(CPUState *env, TranslationBlock *tb)
8782 return gen_intermediate_code_internal(env, tb, 0);
8785 int gen_intermediate_code_pc(CPUState *env, TranslationBlock *tb)
8787 return gen_intermediate_code_internal(env, tb, 1);
8790 static const char *cpu_mode_names[16] = {
8791 "usr", "fiq", "irq", "svc", "???", "???", "???", "abt",
8792 "???", "???", "???", "und", "???", "???", "???", "sys"
8795 void cpu_dump_state(CPUState *env, FILE *f,
8796 int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
8805 /* ??? This assumes float64 and double have the same layout.
8806 Oh well, it's only debug dumps. */
8814 cpu_fprintf(f, "R%02d=%08x", i, env->regs[i]);
8816 cpu_fprintf(f, "\n");
8818 cpu_fprintf(f, " ");
8820 psr = cpsr_read(env);
8821 cpu_fprintf(f, "PSR=%08x %c%c%c%c %c %s%d\n",
8823 psr & (1 << 31) ? 'N' : '-',
8824 psr & (1 << 30) ? 'Z' : '-',
8825 psr & (1 << 29) ? 'C' : '-',
8826 psr & (1 << 28) ? 'V' : '-',
8827 psr & CPSR_T ? 'T' : 'A',
8828 cpu_mode_names[psr & 0xf], (psr & 0x10) ? 32 : 26);
8831 for (i = 0; i < 16; i++) {
8832 d.d = env->vfp.regs[i];
8836 cpu_fprintf(f, "s%02d=%08x(%8g) s%02d=%08x(%8g) d%02d=%08x%08x(%8g)\n",
8837 i * 2, (int)s0.i, s0.s,
8838 i * 2 + 1, (int)s1.i, s1.s,
8839 i, (int)(uint32_t)d.l.upper, (int)(uint32_t)d.l.lower,
8842 cpu_fprintf(f, "FPSCR: %08x\n", (int)env->vfp.xregs[ARM_VFP_FPSCR]);
8846 void gen_pc_load(CPUState *env, TranslationBlock *tb,
8847 unsigned long searched_pc, int pc_pos, void *puc)
8849 env->regs[15] = gen_opc_pc[pc_pos];