4 * Copyright (c) 2003 Fabrice Bellard
5 * Copyright (c) 2005-2007 CodeSourcery
6 * Copyright (c) 2007 OpenedHand, Ltd.
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2 of the License, or (at your option) any later version.
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
36 #define ENABLE_ARCH_5J 0
37 #define ENABLE_ARCH_6 arm_feature(env, ARM_FEATURE_V6)
38 #define ENABLE_ARCH_6K arm_feature(env, ARM_FEATURE_V6K)
39 #define ENABLE_ARCH_6T2 arm_feature(env, ARM_FEATURE_THUMB2)
40 #define ENABLE_ARCH_7 arm_feature(env, ARM_FEATURE_V7)
42 #define ARCH(x) if (!ENABLE_ARCH_##x) goto illegal_op;
44 /* internal defines */
45 typedef struct DisasContext {
48 /* Nonzero if this instruction has been conditionally skipped. */
50 /* The label that will be jumped to when the instruction is skipped. */
52 /* Thumb-2 condtional execution bits. */
55 struct TranslationBlock *tb;
56 int singlestep_enabled;
59 #if !defined(CONFIG_USER_ONLY)
64 #if defined(CONFIG_USER_ONLY)
67 #define IS_USER(s) (s->user)
70 /* These instructions trap after executing, so defer them until after the
71 conditional executions state has been updated. */
75 /* XXX: move that elsewhere */
80 /* We reuse the same 64-bit temporaries for efficiency. */
81 static TCGv cpu_V0, cpu_V1, cpu_M0;
83 /* FIXME: These should be removed. */
85 static TCGv cpu_F0s, cpu_F1s, cpu_F0d, cpu_F1d;
87 /* initialize TCG globals. */
88 void arm_translate_init(void)
90 cpu_env = tcg_global_reg_new(TCG_TYPE_PTR, TCG_AREG0, "env");
92 cpu_T[0] = tcg_global_reg_new(TCG_TYPE_I32, TCG_AREG1, "T0");
93 cpu_T[1] = tcg_global_reg_new(TCG_TYPE_I32, TCG_AREG2, "T1");
96 /* The code generator doesn't like lots of temporaries, so maintain our own
97 cache for reuse within a function. */
100 static TCGv temps[MAX_TEMPS];
102 /* Allocate a temporary variable. */
103 static TCGv new_tmp(void)
106 if (num_temps == MAX_TEMPS)
109 if (GET_TCGV(temps[num_temps]))
110 return temps[num_temps++];
112 tmp = tcg_temp_new(TCG_TYPE_I32);
113 temps[num_temps++] = tmp;
117 /* Release a temporary variable. */
118 static void dead_tmp(TCGv tmp)
123 if (GET_TCGV(temps[i]) == GET_TCGV(tmp))
126 /* Shuffle this temp to the last slot. */
127 while (GET_TCGV(temps[i]) != GET_TCGV(tmp))
129 while (i < num_temps) {
130 temps[i] = temps[i + 1];
136 static inline TCGv load_cpu_offset(int offset)
138 TCGv tmp = new_tmp();
139 tcg_gen_ld_i32(tmp, cpu_env, offset);
143 #define load_cpu_field(name) load_cpu_offset(offsetof(CPUState, name))
145 static inline void store_cpu_offset(TCGv var, int offset)
147 tcg_gen_st_i32(var, cpu_env, offset);
151 #define store_cpu_field(var, name) \
152 store_cpu_offset(var, offsetof(CPUState, name))
154 /* Set a variable to the value of a CPU register. */
155 static void load_reg_var(DisasContext *s, TCGv var, int reg)
159 /* normaly, since we updated PC, we need only to add one insn */
161 addr = (long)s->pc + 2;
163 addr = (long)s->pc + 4;
164 tcg_gen_movi_i32(var, addr);
166 tcg_gen_ld_i32(var, cpu_env, offsetof(CPUState, regs[reg]));
170 /* Create a new temporary and set it to the value of a CPU register. */
171 static inline TCGv load_reg(DisasContext *s, int reg)
173 TCGv tmp = new_tmp();
174 load_reg_var(s, tmp, reg);
178 /* Set a CPU register. The source must be a temporary and will be
180 static void store_reg(DisasContext *s, int reg, TCGv var)
183 tcg_gen_andi_i32(var, var, ~1);
184 s->is_jmp = DISAS_JUMP;
186 tcg_gen_st_i32(var, cpu_env, offsetof(CPUState, regs[reg]));
191 /* Basic operations. */
192 #define gen_op_movl_T0_T1() tcg_gen_mov_i32(cpu_T[0], cpu_T[1])
193 #define gen_op_movl_T1_T0() tcg_gen_mov_i32(cpu_T[1], cpu_T[0])
194 #define gen_op_movl_T0_im(im) tcg_gen_movi_i32(cpu_T[0], im)
195 #define gen_op_movl_T1_im(im) tcg_gen_movi_i32(cpu_T[1], im)
197 #define gen_op_addl_T1_im(im) tcg_gen_addi_i32(cpu_T[1], cpu_T[1], im)
198 #define gen_op_addl_T0_T1() tcg_gen_add_i32(cpu_T[0], cpu_T[0], cpu_T[1])
199 #define gen_op_subl_T0_T1() tcg_gen_sub_i32(cpu_T[0], cpu_T[0], cpu_T[1])
200 #define gen_op_rsbl_T0_T1() tcg_gen_sub_i32(cpu_T[0], cpu_T[1], cpu_T[0])
202 #define gen_op_addl_T0_T1_cc() gen_helper_add_cc(cpu_T[0], cpu_T[0], cpu_T[1])
203 #define gen_op_adcl_T0_T1_cc() gen_helper_adc_cc(cpu_T[0], cpu_T[0], cpu_T[1])
204 #define gen_op_subl_T0_T1_cc() gen_helper_sub_cc(cpu_T[0], cpu_T[0], cpu_T[1])
205 #define gen_op_sbcl_T0_T1_cc() gen_helper_sbc_cc(cpu_T[0], cpu_T[0], cpu_T[1])
206 #define gen_op_rsbl_T0_T1_cc() gen_helper_sub_cc(cpu_T[0], cpu_T[1], cpu_T[0])
207 #define gen_op_rscl_T0_T1_cc() gen_helper_sbc_cc(cpu_T[0], cpu_T[1], cpu_T[0])
209 #define gen_op_andl_T0_T1() tcg_gen_and_i32(cpu_T[0], cpu_T[0], cpu_T[1])
210 #define gen_op_xorl_T0_T1() tcg_gen_xor_i32(cpu_T[0], cpu_T[0], cpu_T[1])
211 #define gen_op_orl_T0_T1() tcg_gen_or_i32(cpu_T[0], cpu_T[0], cpu_T[1])
212 #define gen_op_notl_T0() tcg_gen_not_i32(cpu_T[0], cpu_T[0])
213 #define gen_op_notl_T1() tcg_gen_not_i32(cpu_T[1], cpu_T[1])
214 #define gen_op_logic_T0_cc() gen_logic_CC(cpu_T[0]);
215 #define gen_op_logic_T1_cc() gen_logic_CC(cpu_T[1]);
217 #define gen_op_shll_T0_im(im) tcg_gen_shli_i32(cpu_T[0], cpu_T[0], im)
218 #define gen_op_shll_T1_im(im) tcg_gen_shli_i32(cpu_T[1], cpu_T[1], im)
219 #define gen_op_shrl_T1_im(im) tcg_gen_shri_i32(cpu_T[1], cpu_T[1], im)
220 #define gen_op_sarl_T1_im(im) tcg_gen_sari_i32(cpu_T[1], cpu_T[1], im)
221 #define gen_op_rorl_T1_im(im) tcg_gen_rori_i32(cpu_T[1], cpu_T[1], im)
223 /* Value extensions. */
224 #define gen_uxtb(var) tcg_gen_ext8u_i32(var, var)
225 #define gen_uxth(var) tcg_gen_ext16u_i32(var, var)
226 #define gen_sxtb(var) tcg_gen_ext8s_i32(var, var)
227 #define gen_sxth(var) tcg_gen_ext16s_i32(var, var)
229 #define gen_sxtb16(var) gen_helper_sxtb16(var, var)
230 #define gen_uxtb16(var) gen_helper_uxtb16(var, var)
232 #define gen_op_mul_T0_T1() tcg_gen_mul_i32(cpu_T[0], cpu_T[0], cpu_T[1])
234 #define gen_set_cpsr(var, mask) gen_helper_cpsr_write(var, tcg_const_i32(mask))
235 /* Set NZCV flags from the high 4 bits of var. */
236 #define gen_set_nzcv(var) gen_set_cpsr(var, CPSR_NZCV)
238 static void gen_exception(int excp)
240 TCGv tmp = new_tmp();
241 tcg_gen_movi_i32(tmp, excp);
242 gen_helper_exception(tmp);
246 static void gen_smul_dual(TCGv a, TCGv b)
248 TCGv tmp1 = new_tmp();
249 TCGv tmp2 = new_tmp();
250 tcg_gen_ext8s_i32(tmp1, a);
251 tcg_gen_ext8s_i32(tmp2, b);
252 tcg_gen_mul_i32(tmp1, tmp1, tmp2);
254 tcg_gen_sari_i32(a, a, 16);
255 tcg_gen_sari_i32(b, b, 16);
256 tcg_gen_mul_i32(b, b, a);
257 tcg_gen_mov_i32(a, tmp1);
261 /* Byteswap each halfword. */
262 static void gen_rev16(TCGv var)
264 TCGv tmp = new_tmp();
265 tcg_gen_shri_i32(tmp, var, 8);
266 tcg_gen_andi_i32(tmp, tmp, 0x00ff00ff);
267 tcg_gen_shli_i32(var, var, 8);
268 tcg_gen_andi_i32(var, var, 0xff00ff00);
269 tcg_gen_or_i32(var, var, tmp);
273 /* Byteswap low halfword and sign extend. */
274 static void gen_revsh(TCGv var)
276 TCGv tmp = new_tmp();
277 tcg_gen_shri_i32(tmp, var, 8);
278 tcg_gen_andi_i32(tmp, tmp, 0x00ff);
279 tcg_gen_shli_i32(var, var, 8);
280 tcg_gen_ext8s_i32(var, var);
281 tcg_gen_or_i32(var, var, tmp);
285 /* Unsigned bitfield extract. */
286 static void gen_ubfx(TCGv var, int shift, uint32_t mask)
289 tcg_gen_shri_i32(var, var, shift);
290 tcg_gen_andi_i32(var, var, mask);
293 /* Signed bitfield extract. */
294 static void gen_sbfx(TCGv var, int shift, int width)
299 tcg_gen_sari_i32(var, var, shift);
300 if (shift + width < 32) {
301 signbit = 1u << (width - 1);
302 tcg_gen_andi_i32(var, var, (1u << width) - 1);
303 tcg_gen_xori_i32(var, var, signbit);
304 tcg_gen_subi_i32(var, var, signbit);
308 /* Bitfield insertion. Insert val into base. Clobbers base and val. */
309 static void gen_bfi(TCGv dest, TCGv base, TCGv val, int shift, uint32_t mask)
311 tcg_gen_andi_i32(val, val, mask);
312 tcg_gen_shli_i32(val, val, shift);
313 tcg_gen_andi_i32(base, base, ~(mask << shift));
314 tcg_gen_or_i32(dest, base, val);
317 /* Round the top 32 bits of a 64-bit value. */
318 static void gen_roundqd(TCGv a, TCGv b)
320 tcg_gen_shri_i32(a, a, 31);
321 tcg_gen_add_i32(a, a, b);
324 /* FIXME: Most targets have native widening multiplication.
325 It would be good to use that instead of a full wide multiply. */
326 /* 32x32->64 multiply. Marks inputs as dead. */
327 static TCGv gen_mulu_i64_i32(TCGv a, TCGv b)
329 TCGv tmp1 = tcg_temp_new(TCG_TYPE_I64);
330 TCGv tmp2 = tcg_temp_new(TCG_TYPE_I64);
332 tcg_gen_extu_i32_i64(tmp1, a);
334 tcg_gen_extu_i32_i64(tmp2, b);
336 tcg_gen_mul_i64(tmp1, tmp1, tmp2);
340 static TCGv gen_muls_i64_i32(TCGv a, TCGv b)
342 TCGv tmp1 = tcg_temp_new(TCG_TYPE_I64);
343 TCGv tmp2 = tcg_temp_new(TCG_TYPE_I64);
345 tcg_gen_ext_i32_i64(tmp1, a);
347 tcg_gen_ext_i32_i64(tmp2, b);
349 tcg_gen_mul_i64(tmp1, tmp1, tmp2);
353 /* Unsigned 32x32->64 multiply. */
354 static void gen_op_mull_T0_T1(void)
356 TCGv tmp1 = tcg_temp_new(TCG_TYPE_I64);
357 TCGv tmp2 = tcg_temp_new(TCG_TYPE_I64);
359 tcg_gen_extu_i32_i64(tmp1, cpu_T[0]);
360 tcg_gen_extu_i32_i64(tmp2, cpu_T[1]);
361 tcg_gen_mul_i64(tmp1, tmp1, tmp2);
362 tcg_gen_trunc_i64_i32(cpu_T[0], tmp1);
363 tcg_gen_shri_i64(tmp1, tmp1, 32);
364 tcg_gen_trunc_i64_i32(cpu_T[1], tmp1);
367 /* Signed 32x32->64 multiply. */
368 static void gen_imull(TCGv a, TCGv b)
370 TCGv tmp1 = tcg_temp_new(TCG_TYPE_I64);
371 TCGv tmp2 = tcg_temp_new(TCG_TYPE_I64);
373 tcg_gen_ext_i32_i64(tmp1, a);
374 tcg_gen_ext_i32_i64(tmp2, b);
375 tcg_gen_mul_i64(tmp1, tmp1, tmp2);
376 tcg_gen_trunc_i64_i32(a, tmp1);
377 tcg_gen_shri_i64(tmp1, tmp1, 32);
378 tcg_gen_trunc_i64_i32(b, tmp1);
380 #define gen_op_imull_T0_T1() gen_imull(cpu_T[0], cpu_T[1])
382 /* Swap low and high halfwords. */
383 static void gen_swap_half(TCGv var)
385 TCGv tmp = new_tmp();
386 tcg_gen_shri_i32(tmp, var, 16);
387 tcg_gen_shli_i32(var, var, 16);
388 tcg_gen_or_i32(var, var, tmp);
392 /* Dual 16-bit add. Result placed in t0 and t1 is marked as dead.
393 tmp = (t0 ^ t1) & 0x8000;
396 t0 = (t0 + t1) ^ tmp;
399 static void gen_add16(TCGv t0, TCGv t1)
401 TCGv tmp = new_tmp();
402 tcg_gen_xor_i32(tmp, t0, t1);
403 tcg_gen_andi_i32(tmp, tmp, 0x8000);
404 tcg_gen_andi_i32(t0, t0, ~0x8000);
405 tcg_gen_andi_i32(t1, t1, ~0x8000);
406 tcg_gen_add_i32(t0, t0, t1);
407 tcg_gen_xor_i32(t0, t0, tmp);
412 #define gen_set_CF(var) tcg_gen_st_i32(var, cpu_env, offsetof(CPUState, CF))
414 /* Set CF to the top bit of var. */
415 static void gen_set_CF_bit31(TCGv var)
417 TCGv tmp = new_tmp();
418 tcg_gen_shri_i32(tmp, var, 31);
423 /* Set N and Z flags from var. */
424 static inline void gen_logic_CC(TCGv var)
426 tcg_gen_st_i32(var, cpu_env, offsetof(CPUState, NF));
427 tcg_gen_st_i32(var, cpu_env, offsetof(CPUState, ZF));
431 static void gen_adc_T0_T1(void)
435 tmp = load_cpu_field(CF);
436 tcg_gen_add_i32(cpu_T[0], cpu_T[0], tmp);
440 /* dest = T0 - T1 + CF - 1. */
441 static void gen_sub_carry(TCGv dest, TCGv t0, TCGv t1)
444 tcg_gen_sub_i32(dest, t0, t1);
445 tmp = load_cpu_field(CF);
446 tcg_gen_add_i32(dest, dest, tmp);
447 tcg_gen_subi_i32(dest, dest, 1);
451 #define gen_sbc_T0_T1() gen_sub_carry(cpu_T[0], cpu_T[0], cpu_T[1])
452 #define gen_rsc_T0_T1() gen_sub_carry(cpu_T[0], cpu_T[1], cpu_T[0])
454 /* T0 &= ~T1. Clobbers T1. */
455 /* FIXME: Implement bic natively. */
456 static inline void tcg_gen_bic_i32(TCGv dest, TCGv t0, TCGv t1)
458 TCGv tmp = new_tmp();
459 tcg_gen_not_i32(tmp, t1);
460 tcg_gen_and_i32(dest, t0, tmp);
463 static inline void gen_op_bicl_T0_T1(void)
469 /* FIXME: Implement this natively. */
470 #define tcg_gen_abs_i32(t0, t1) gen_helper_abs(t0, t1)
472 /* FIXME: Implement this natively. */
473 static void tcg_gen_rori_i32(TCGv t0, TCGv t1, int i)
481 tcg_gen_shri_i32(tmp, t1, i);
482 tcg_gen_shli_i32(t1, t1, 32 - i);
483 tcg_gen_or_i32(t0, t1, tmp);
487 static void shifter_out_im(TCGv var, int shift)
489 TCGv tmp = new_tmp();
491 tcg_gen_andi_i32(tmp, var, 1);
493 tcg_gen_shri_i32(tmp, var, shift);
495 tcg_gen_andi_i32(tmp, tmp, 1);
501 /* Shift by immediate. Includes special handling for shift == 0. */
502 static inline void gen_arm_shift_im(TCGv var, int shiftop, int shift, int flags)
508 shifter_out_im(var, 32 - shift);
509 tcg_gen_shli_i32(var, var, shift);
515 tcg_gen_shri_i32(var, var, 31);
518 tcg_gen_movi_i32(var, 0);
521 shifter_out_im(var, shift - 1);
522 tcg_gen_shri_i32(var, var, shift);
529 shifter_out_im(var, shift - 1);
532 tcg_gen_sari_i32(var, var, shift);
534 case 3: /* ROR/RRX */
537 shifter_out_im(var, shift - 1);
538 tcg_gen_rori_i32(var, var, shift); break;
540 TCGv tmp = load_cpu_field(CF);
542 shifter_out_im(var, 0);
543 tcg_gen_shri_i32(var, var, 1);
544 tcg_gen_shli_i32(tmp, tmp, 31);
545 tcg_gen_or_i32(var, var, tmp);
551 static inline void gen_arm_shift_reg(TCGv var, int shiftop,
552 TCGv shift, int flags)
556 case 0: gen_helper_shl_cc(var, var, shift); break;
557 case 1: gen_helper_shr_cc(var, var, shift); break;
558 case 2: gen_helper_sar_cc(var, var, shift); break;
559 case 3: gen_helper_ror_cc(var, var, shift); break;
563 case 0: gen_helper_shl(var, var, shift); break;
564 case 1: gen_helper_shr(var, var, shift); break;
565 case 2: gen_helper_sar(var, var, shift); break;
566 case 3: gen_helper_ror(var, var, shift); break;
572 #define PAS_OP(pfx) \
574 case 0: gen_pas_helper(glue(pfx,add16)); break; \
575 case 1: gen_pas_helper(glue(pfx,addsubx)); break; \
576 case 2: gen_pas_helper(glue(pfx,subaddx)); break; \
577 case 3: gen_pas_helper(glue(pfx,sub16)); break; \
578 case 4: gen_pas_helper(glue(pfx,add8)); break; \
579 case 7: gen_pas_helper(glue(pfx,sub8)); break; \
581 static void gen_arm_parallel_addsub(int op1, int op2, TCGv a, TCGv b)
586 #define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b, tmp)
588 tmp = tcg_temp_new(TCG_TYPE_PTR);
589 tcg_gen_addi_ptr(tmp, cpu_env, offsetof(CPUState, GE));
593 tmp = tcg_temp_new(TCG_TYPE_PTR);
594 tcg_gen_addi_ptr(tmp, cpu_env, offsetof(CPUState, GE));
597 #undef gen_pas_helper
598 #define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b)
611 #undef gen_pas_helper
616 /* For unknown reasons Arm and Thumb-2 use arbitrarily different encodings. */
617 #define PAS_OP(pfx) \
619 case 0: gen_pas_helper(glue(pfx,add8)); break; \
620 case 1: gen_pas_helper(glue(pfx,add16)); break; \
621 case 2: gen_pas_helper(glue(pfx,addsubx)); break; \
622 case 4: gen_pas_helper(glue(pfx,sub8)); break; \
623 case 5: gen_pas_helper(glue(pfx,sub16)); break; \
624 case 6: gen_pas_helper(glue(pfx,subaddx)); break; \
626 static void gen_thumb2_parallel_addsub(int op1, int op2, TCGv a, TCGv b)
631 #define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b, tmp)
633 tmp = tcg_temp_new(TCG_TYPE_PTR);
634 tcg_gen_addi_ptr(tmp, cpu_env, offsetof(CPUState, GE));
638 tmp = tcg_temp_new(TCG_TYPE_PTR);
639 tcg_gen_addi_ptr(tmp, cpu_env, offsetof(CPUState, GE));
642 #undef gen_pas_helper
643 #define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b)
656 #undef gen_pas_helper
661 static void gen_test_cc(int cc, int label)
668 zero = tcg_const_i32(0);
671 tmp = load_cpu_field(ZF);
672 tcg_gen_brcond_i32(TCG_COND_EQ, tmp, zero, label);
675 tmp = load_cpu_field(ZF);
676 tcg_gen_brcond_i32(TCG_COND_NE, tmp, zero, label);
679 tmp = load_cpu_field(CF);
680 tcg_gen_brcond_i32(TCG_COND_NE, tmp, zero, label);
683 tmp = load_cpu_field(CF);
684 tcg_gen_brcond_i32(TCG_COND_EQ, tmp, zero, label);
687 tmp = load_cpu_field(NF);
688 tcg_gen_brcond_i32(TCG_COND_LT, tmp, zero, label);
691 tmp = load_cpu_field(NF);
692 tcg_gen_brcond_i32(TCG_COND_GE, tmp, zero, label);
695 tmp = load_cpu_field(VF);
696 tcg_gen_brcond_i32(TCG_COND_LT, tmp, zero, label);
699 tmp = load_cpu_field(VF);
700 tcg_gen_brcond_i32(TCG_COND_GE, tmp, zero, label);
702 case 8: /* hi: C && !Z */
703 inv = gen_new_label();
704 tmp = load_cpu_field(CF);
705 tcg_gen_brcond_i32(TCG_COND_EQ, tmp, zero, inv);
707 tmp = load_cpu_field(ZF);
708 tcg_gen_brcond_i32(TCG_COND_NE, tmp, zero, label);
711 case 9: /* ls: !C || Z */
712 tmp = load_cpu_field(CF);
713 tcg_gen_brcond_i32(TCG_COND_EQ, tmp, zero, label);
715 tmp = load_cpu_field(ZF);
716 tcg_gen_brcond_i32(TCG_COND_EQ, tmp, zero, label);
718 case 10: /* ge: N == V -> N ^ V == 0 */
719 tmp = load_cpu_field(VF);
720 tmp2 = load_cpu_field(NF);
721 tcg_gen_xor_i32(tmp, tmp, tmp2);
723 tcg_gen_brcond_i32(TCG_COND_GE, tmp, zero, label);
725 case 11: /* lt: N != V -> N ^ V != 0 */
726 tmp = load_cpu_field(VF);
727 tmp2 = load_cpu_field(NF);
728 tcg_gen_xor_i32(tmp, tmp, tmp2);
730 tcg_gen_brcond_i32(TCG_COND_LT, tmp, zero, label);
732 case 12: /* gt: !Z && N == V */
733 inv = gen_new_label();
734 tmp = load_cpu_field(ZF);
735 tcg_gen_brcond_i32(TCG_COND_EQ, tmp, zero, inv);
737 tmp = load_cpu_field(VF);
738 tmp2 = load_cpu_field(NF);
739 tcg_gen_xor_i32(tmp, tmp, tmp2);
741 tcg_gen_brcond_i32(TCG_COND_GE, tmp, zero, label);
744 case 13: /* le: Z || N != V */
745 tmp = load_cpu_field(ZF);
746 tcg_gen_brcond_i32(TCG_COND_EQ, tmp, zero, label);
748 tmp = load_cpu_field(VF);
749 tmp2 = load_cpu_field(NF);
750 tcg_gen_xor_i32(tmp, tmp, tmp2);
752 tcg_gen_brcond_i32(TCG_COND_LT, tmp, zero, label);
755 fprintf(stderr, "Bad condition code 0x%x\n", cc);
761 const uint8_t table_logic_cc[16] = {
780 /* Set PC and Thumb state from an immediate address. */
781 static inline void gen_bx_im(DisasContext *s, uint32_t addr)
785 s->is_jmp = DISAS_UPDATE;
787 if (s->thumb != (addr & 1)) {
788 tcg_gen_movi_i32(tmp, addr & 1);
789 tcg_gen_st_i32(tmp, cpu_env, offsetof(CPUState, thumb));
791 tcg_gen_movi_i32(tmp, addr & ~1);
792 tcg_gen_st_i32(tmp, cpu_env, offsetof(CPUState, regs[15]));
796 /* Set PC and Thumb state from var. var is marked as dead. */
797 static inline void gen_bx(DisasContext *s, TCGv var)
801 s->is_jmp = DISAS_UPDATE;
803 tcg_gen_andi_i32(tmp, var, 1);
804 store_cpu_field(tmp, thumb);
805 tcg_gen_andi_i32(var, var, ~1);
806 store_cpu_field(var, regs[15]);
809 /* TODO: This should be removed. Use gen_bx instead. */
810 static inline void gen_bx_T0(DisasContext *s)
812 TCGv tmp = new_tmp();
813 tcg_gen_mov_i32(tmp, cpu_T[0]);
817 #if defined(CONFIG_USER_ONLY)
818 #define gen_ldst(name, s) gen_op_##name##_raw()
820 #define gen_ldst(name, s) do { \
823 gen_op_##name##_user(); \
825 gen_op_##name##_kernel(); \
828 static inline TCGv gen_ld8s(TCGv addr, int index)
830 TCGv tmp = new_tmp();
831 tcg_gen_qemu_ld8s(tmp, addr, index);
834 static inline TCGv gen_ld8u(TCGv addr, int index)
836 TCGv tmp = new_tmp();
837 tcg_gen_qemu_ld8u(tmp, addr, index);
840 static inline TCGv gen_ld16s(TCGv addr, int index)
842 TCGv tmp = new_tmp();
843 tcg_gen_qemu_ld16s(tmp, addr, index);
846 static inline TCGv gen_ld16u(TCGv addr, int index)
848 TCGv tmp = new_tmp();
849 tcg_gen_qemu_ld16u(tmp, addr, index);
852 static inline TCGv gen_ld32(TCGv addr, int index)
854 TCGv tmp = new_tmp();
855 tcg_gen_qemu_ld32u(tmp, addr, index);
858 static inline void gen_st8(TCGv val, TCGv addr, int index)
860 tcg_gen_qemu_st8(val, addr, index);
863 static inline void gen_st16(TCGv val, TCGv addr, int index)
865 tcg_gen_qemu_st16(val, addr, index);
868 static inline void gen_st32(TCGv val, TCGv addr, int index)
870 tcg_gen_qemu_st32(val, addr, index);
874 static inline void gen_movl_T0_reg(DisasContext *s, int reg)
876 load_reg_var(s, cpu_T[0], reg);
879 static inline void gen_movl_T1_reg(DisasContext *s, int reg)
881 load_reg_var(s, cpu_T[1], reg);
884 static inline void gen_movl_T2_reg(DisasContext *s, int reg)
886 load_reg_var(s, cpu_T[2], reg);
889 static inline void gen_set_pc_im(uint32_t val)
891 TCGv tmp = new_tmp();
892 tcg_gen_movi_i32(tmp, val);
893 store_cpu_field(tmp, regs[15]);
896 static inline void gen_movl_reg_TN(DisasContext *s, int reg, int t)
901 tcg_gen_andi_i32(tmp, cpu_T[t], ~1);
905 tcg_gen_st_i32(tmp, cpu_env, offsetof(CPUState, regs[reg]));
908 s->is_jmp = DISAS_JUMP;
912 static inline void gen_movl_reg_T0(DisasContext *s, int reg)
914 gen_movl_reg_TN(s, reg, 0);
917 static inline void gen_movl_reg_T1(DisasContext *s, int reg)
919 gen_movl_reg_TN(s, reg, 1);
922 /* Force a TB lookup after an instruction that changes the CPU state. */
923 static inline void gen_lookup_tb(DisasContext *s)
925 gen_op_movl_T0_im(s->pc);
926 gen_movl_reg_T0(s, 15);
927 s->is_jmp = DISAS_UPDATE;
930 static inline void gen_add_data_offset(DisasContext *s, unsigned int insn,
933 int val, rm, shift, shiftop;
936 if (!(insn & (1 << 25))) {
939 if (!(insn & (1 << 23)))
942 tcg_gen_addi_i32(var, var, val);
946 shift = (insn >> 7) & 0x1f;
947 shiftop = (insn >> 5) & 3;
948 offset = load_reg(s, rm);
949 gen_arm_shift_im(offset, shiftop, shift, 0);
950 if (!(insn & (1 << 23)))
951 tcg_gen_sub_i32(var, var, offset);
953 tcg_gen_add_i32(var, var, offset);
958 static inline void gen_add_datah_offset(DisasContext *s, unsigned int insn,
964 if (insn & (1 << 22)) {
966 val = (insn & 0xf) | ((insn >> 4) & 0xf0);
967 if (!(insn & (1 << 23)))
971 tcg_gen_addi_i32(var, var, val);
975 tcg_gen_addi_i32(var, var, extra);
977 offset = load_reg(s, rm);
978 if (!(insn & (1 << 23)))
979 tcg_gen_sub_i32(var, var, offset);
981 tcg_gen_add_i32(var, var, offset);
986 #define VFP_OP2(name) \
987 static inline void gen_vfp_##name(int dp) \
990 gen_helper_vfp_##name##d(cpu_F0d, cpu_F0d, cpu_F1d, cpu_env); \
992 gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, cpu_F1s, cpu_env); \
995 #define VFP_OP1(name) \
996 static inline void gen_vfp_##name(int dp, int arg) \
999 gen_op_vfp_##name##d(arg); \
1001 gen_op_vfp_##name##s(arg); \
1011 static inline void gen_vfp_abs(int dp)
1014 gen_helper_vfp_absd(cpu_F0d, cpu_F0d);
1016 gen_helper_vfp_abss(cpu_F0s, cpu_F0s);
1019 static inline void gen_vfp_neg(int dp)
1022 gen_helper_vfp_negd(cpu_F0d, cpu_F0d);
1024 gen_helper_vfp_negs(cpu_F0s, cpu_F0s);
1027 static inline void gen_vfp_sqrt(int dp)
1030 gen_helper_vfp_sqrtd(cpu_F0d, cpu_F0d, cpu_env);
1032 gen_helper_vfp_sqrts(cpu_F0s, cpu_F0s, cpu_env);
1035 static inline void gen_vfp_cmp(int dp)
1038 gen_helper_vfp_cmpd(cpu_F0d, cpu_F1d, cpu_env);
1040 gen_helper_vfp_cmps(cpu_F0s, cpu_F1s, cpu_env);
1043 static inline void gen_vfp_cmpe(int dp)
1046 gen_helper_vfp_cmped(cpu_F0d, cpu_F1d, cpu_env);
1048 gen_helper_vfp_cmpes(cpu_F0s, cpu_F1s, cpu_env);
1051 static inline void gen_vfp_F1_ld0(int dp)
1054 tcg_gen_movi_i64(cpu_F1d, 0);
1056 tcg_gen_movi_i32(cpu_F1s, 0);
1059 static inline void gen_vfp_uito(int dp)
1062 gen_helper_vfp_uitod(cpu_F0d, cpu_F0s, cpu_env);
1064 gen_helper_vfp_uitos(cpu_F0s, cpu_F0s, cpu_env);
1067 static inline void gen_vfp_sito(int dp)
1070 gen_helper_vfp_sitod(cpu_F0d, cpu_F0s, cpu_env);
1072 gen_helper_vfp_sitos(cpu_F0s, cpu_F0s, cpu_env);
1075 static inline void gen_vfp_toui(int dp)
1078 gen_helper_vfp_touid(cpu_F0s, cpu_F0d, cpu_env);
1080 gen_helper_vfp_touis(cpu_F0s, cpu_F0s, cpu_env);
1083 static inline void gen_vfp_touiz(int dp)
1086 gen_helper_vfp_touizd(cpu_F0s, cpu_F0d, cpu_env);
1088 gen_helper_vfp_touizs(cpu_F0s, cpu_F0s, cpu_env);
1091 static inline void gen_vfp_tosi(int dp)
1094 gen_helper_vfp_tosid(cpu_F0s, cpu_F0d, cpu_env);
1096 gen_helper_vfp_tosis(cpu_F0s, cpu_F0s, cpu_env);
1099 static inline void gen_vfp_tosiz(int dp)
1102 gen_helper_vfp_tosizd(cpu_F0s, cpu_F0d, cpu_env);
1104 gen_helper_vfp_tosizs(cpu_F0s, cpu_F0s, cpu_env);
1107 #define VFP_GEN_FIX(name) \
1108 static inline void gen_vfp_##name(int dp, int shift) \
1111 gen_helper_vfp_##name##d(cpu_F0d, cpu_F0d, tcg_const_i32(shift), cpu_env);\
1113 gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, tcg_const_i32(shift), cpu_env);\
1125 static inline void gen_vfp_ld(DisasContext *s, int dp)
1128 tcg_gen_qemu_ld64(cpu_F0d, cpu_T[1], IS_USER(s));
1130 tcg_gen_qemu_ld32u(cpu_F0s, cpu_T[1], IS_USER(s));
1133 static inline void gen_vfp_st(DisasContext *s, int dp)
1136 tcg_gen_qemu_st64(cpu_F0d, cpu_T[1], IS_USER(s));
1138 tcg_gen_qemu_st32(cpu_F0s, cpu_T[1], IS_USER(s));
1142 vfp_reg_offset (int dp, int reg)
1145 return offsetof(CPUARMState, vfp.regs[reg]);
1147 return offsetof(CPUARMState, vfp.regs[reg >> 1])
1148 + offsetof(CPU_DoubleU, l.upper);
1150 return offsetof(CPUARMState, vfp.regs[reg >> 1])
1151 + offsetof(CPU_DoubleU, l.lower);
1155 /* Return the offset of a 32-bit piece of a NEON register.
1156 zero is the least significant end of the register. */
1158 neon_reg_offset (int reg, int n)
1162 return vfp_reg_offset(0, sreg);
1165 /* FIXME: Remove these. */
1166 #define neon_T0 cpu_T[0]
1167 #define neon_T1 cpu_T[1]
1168 #define NEON_GET_REG(T, reg, n) \
1169 tcg_gen_ld_i32(neon_##T, cpu_env, neon_reg_offset(reg, n))
1170 #define NEON_SET_REG(T, reg, n) \
1171 tcg_gen_st_i32(neon_##T, cpu_env, neon_reg_offset(reg, n))
1173 static TCGv neon_load_reg(int reg, int pass)
1175 TCGv tmp = new_tmp();
1176 tcg_gen_ld_i32(tmp, cpu_env, neon_reg_offset(reg, pass));
1180 static void neon_store_reg(int reg, int pass, TCGv var)
1182 tcg_gen_st_i32(var, cpu_env, neon_reg_offset(reg, pass));
1186 static inline void neon_load_reg64(TCGv var, int reg)
1188 tcg_gen_ld_i64(var, cpu_env, vfp_reg_offset(1, reg));
1191 static inline void neon_store_reg64(TCGv var, int reg)
1193 tcg_gen_st_i64(var, cpu_env, vfp_reg_offset(1, reg));
1196 #define tcg_gen_ld_f32 tcg_gen_ld_i32
1197 #define tcg_gen_ld_f64 tcg_gen_ld_i64
1198 #define tcg_gen_st_f32 tcg_gen_st_i32
1199 #define tcg_gen_st_f64 tcg_gen_st_i64
1201 static inline void gen_mov_F0_vreg(int dp, int reg)
1204 tcg_gen_ld_f64(cpu_F0d, cpu_env, vfp_reg_offset(dp, reg));
1206 tcg_gen_ld_f32(cpu_F0s, cpu_env, vfp_reg_offset(dp, reg));
1209 static inline void gen_mov_F1_vreg(int dp, int reg)
1212 tcg_gen_ld_f64(cpu_F1d, cpu_env, vfp_reg_offset(dp, reg));
1214 tcg_gen_ld_f32(cpu_F1s, cpu_env, vfp_reg_offset(dp, reg));
1217 static inline void gen_mov_vreg_F0(int dp, int reg)
1220 tcg_gen_st_f64(cpu_F0d, cpu_env, vfp_reg_offset(dp, reg));
1222 tcg_gen_st_f32(cpu_F0s, cpu_env, vfp_reg_offset(dp, reg));
1225 #define ARM_CP_RW_BIT (1 << 20)
1227 static inline void iwmmxt_load_reg(TCGv var, int reg)
1229 tcg_gen_ld_i64(var, cpu_env, offsetof(CPUState, iwmmxt.regs[reg]));
1232 static inline void iwmmxt_store_reg(TCGv var, int reg)
1234 tcg_gen_st_i64(var, cpu_env, offsetof(CPUState, iwmmxt.regs[reg]));
1237 static inline void gen_op_iwmmxt_movl_wCx_T0(int reg)
1239 tcg_gen_st_i32(cpu_T[0], cpu_env, offsetof(CPUState, iwmmxt.cregs[reg]));
1242 static inline void gen_op_iwmmxt_movl_T0_wCx(int reg)
1244 tcg_gen_ld_i32(cpu_T[0], cpu_env, offsetof(CPUState, iwmmxt.cregs[reg]));
1247 static inline void gen_op_iwmmxt_movl_T1_wCx(int reg)
1249 tcg_gen_ld_i32(cpu_T[1], cpu_env, offsetof(CPUState, iwmmxt.cregs[reg]));
1252 static inline void gen_op_iwmmxt_movq_wRn_M0(int rn)
1254 iwmmxt_store_reg(cpu_M0, rn);
1257 static inline void gen_op_iwmmxt_movq_M0_wRn(int rn)
1259 iwmmxt_load_reg(cpu_M0, rn);
1262 static inline void gen_op_iwmmxt_orq_M0_wRn(int rn)
1264 iwmmxt_load_reg(cpu_V1, rn);
1265 tcg_gen_or_i64(cpu_M0, cpu_M0, cpu_V1);
1268 static inline void gen_op_iwmmxt_andq_M0_wRn(int rn)
1270 iwmmxt_load_reg(cpu_V1, rn);
1271 tcg_gen_and_i64(cpu_M0, cpu_M0, cpu_V1);
1274 static inline void gen_op_iwmmxt_xorq_M0_wRn(int rn)
1276 iwmmxt_load_reg(cpu_V1, rn);
1277 tcg_gen_xor_i64(cpu_M0, cpu_M0, cpu_V1);
1280 #define IWMMXT_OP(name) \
1281 static inline void gen_op_iwmmxt_##name##_M0_wRn(int rn) \
1283 iwmmxt_load_reg(cpu_V1, rn); \
1284 gen_helper_iwmmxt_##name(cpu_M0, cpu_M0, cpu_V1); \
1287 #define IWMMXT_OP_ENV(name) \
1288 static inline void gen_op_iwmmxt_##name##_M0_wRn(int rn) \
1290 iwmmxt_load_reg(cpu_V1, rn); \
1291 gen_helper_iwmmxt_##name(cpu_M0, cpu_env, cpu_M0, cpu_V1); \
1294 #define IWMMXT_OP_ENV_SIZE(name) \
1295 IWMMXT_OP_ENV(name##b) \
1296 IWMMXT_OP_ENV(name##w) \
1297 IWMMXT_OP_ENV(name##l)
1299 #define IWMMXT_OP_ENV1(name) \
1300 static inline void gen_op_iwmmxt_##name##_M0(void) \
1302 gen_helper_iwmmxt_##name(cpu_M0, cpu_env, cpu_M0); \
1316 IWMMXT_OP_ENV_SIZE(unpackl)
1317 IWMMXT_OP_ENV_SIZE(unpackh)
1319 IWMMXT_OP_ENV1(unpacklub)
1320 IWMMXT_OP_ENV1(unpackluw)
1321 IWMMXT_OP_ENV1(unpacklul)
1322 IWMMXT_OP_ENV1(unpackhub)
1323 IWMMXT_OP_ENV1(unpackhuw)
1324 IWMMXT_OP_ENV1(unpackhul)
1325 IWMMXT_OP_ENV1(unpacklsb)
1326 IWMMXT_OP_ENV1(unpacklsw)
1327 IWMMXT_OP_ENV1(unpacklsl)
1328 IWMMXT_OP_ENV1(unpackhsb)
1329 IWMMXT_OP_ENV1(unpackhsw)
1330 IWMMXT_OP_ENV1(unpackhsl)
1332 IWMMXT_OP_ENV_SIZE(cmpeq)
1333 IWMMXT_OP_ENV_SIZE(cmpgtu)
1334 IWMMXT_OP_ENV_SIZE(cmpgts)
1336 IWMMXT_OP_ENV_SIZE(mins)
1337 IWMMXT_OP_ENV_SIZE(minu)
1338 IWMMXT_OP_ENV_SIZE(maxs)
1339 IWMMXT_OP_ENV_SIZE(maxu)
1341 IWMMXT_OP_ENV_SIZE(subn)
1342 IWMMXT_OP_ENV_SIZE(addn)
1343 IWMMXT_OP_ENV_SIZE(subu)
1344 IWMMXT_OP_ENV_SIZE(addu)
1345 IWMMXT_OP_ENV_SIZE(subs)
1346 IWMMXT_OP_ENV_SIZE(adds)
1348 IWMMXT_OP_ENV(avgb0)
1349 IWMMXT_OP_ENV(avgb1)
1350 IWMMXT_OP_ENV(avgw0)
1351 IWMMXT_OP_ENV(avgw1)
1355 IWMMXT_OP_ENV(packuw)
1356 IWMMXT_OP_ENV(packul)
1357 IWMMXT_OP_ENV(packuq)
1358 IWMMXT_OP_ENV(packsw)
1359 IWMMXT_OP_ENV(packsl)
1360 IWMMXT_OP_ENV(packsq)
1362 static inline void gen_op_iwmmxt_muladdsl_M0_T0_T1(void)
1364 gen_helper_iwmmxt_muladdsl(cpu_M0, cpu_M0, cpu_T[0], cpu_T[1]);
1367 static inline void gen_op_iwmmxt_muladdsw_M0_T0_T1(void)
1369 gen_helper_iwmmxt_muladdsw(cpu_M0, cpu_M0, cpu_T[0], cpu_T[1]);
1372 static inline void gen_op_iwmmxt_muladdswl_M0_T0_T1(void)
1374 gen_helper_iwmmxt_muladdswl(cpu_M0, cpu_M0, cpu_T[0], cpu_T[1]);
1377 static inline void gen_op_iwmmxt_align_M0_T0_wRn(int rn)
1379 iwmmxt_load_reg(cpu_V1, rn);
1380 gen_helper_iwmmxt_align(cpu_M0, cpu_M0, cpu_V1, cpu_T[0]);
1383 static inline void gen_op_iwmmxt_insr_M0_T0_T1(int shift)
1385 TCGv tmp = tcg_const_i32(shift);
1386 gen_helper_iwmmxt_insr(cpu_M0, cpu_M0, cpu_T[0], cpu_T[1], tmp);
1389 static inline void gen_op_iwmmxt_extrsb_T0_M0(int shift)
1391 tcg_gen_shri_i64(cpu_M0, cpu_M0, shift);
1392 tcg_gen_trunc_i64_i32(cpu_T[0], cpu_M0);
1393 tcg_gen_ext8s_i32(cpu_T[0], cpu_T[0]);
1396 static inline void gen_op_iwmmxt_extrsw_T0_M0(int shift)
1398 tcg_gen_shri_i64(cpu_M0, cpu_M0, shift);
1399 tcg_gen_trunc_i64_i32(cpu_T[0], cpu_M0);
1400 tcg_gen_ext16s_i32(cpu_T[0], cpu_T[0]);
1403 static inline void gen_op_iwmmxt_extru_T0_M0(int shift, uint32_t mask)
1405 tcg_gen_shri_i64(cpu_M0, cpu_M0, shift);
1406 tcg_gen_trunc_i64_i32(cpu_T[0], cpu_M0);
1408 tcg_gen_andi_i32(cpu_T[0], cpu_T[0], mask);
1411 static void gen_op_iwmmxt_set_mup(void)
1414 tmp = load_cpu_field(iwmmxt.cregs[ARM_IWMMXT_wCon]);
1415 tcg_gen_ori_i32(tmp, tmp, 2);
1416 store_cpu_field(tmp, iwmmxt.cregs[ARM_IWMMXT_wCon]);
1419 static void gen_op_iwmmxt_set_cup(void)
1422 tmp = load_cpu_field(iwmmxt.cregs[ARM_IWMMXT_wCon]);
1423 tcg_gen_ori_i32(tmp, tmp, 1);
1424 store_cpu_field(tmp, iwmmxt.cregs[ARM_IWMMXT_wCon]);
1427 static void gen_op_iwmmxt_setpsr_nz(void)
1429 TCGv tmp = new_tmp();
1430 gen_helper_iwmmxt_setpsr_nz(tmp, cpu_M0);
1431 store_cpu_field(tmp, iwmmxt.cregs[ARM_IWMMXT_wCASF]);
1434 static inline void gen_op_iwmmxt_addl_M0_wRn(int rn)
1436 iwmmxt_load_reg(cpu_V1, rn);
1437 tcg_gen_ext32u_i64(cpu_V1, cpu_V1);
1438 tcg_gen_add_i64(cpu_M0, cpu_M0, cpu_V1);
1442 static void gen_iwmmxt_movl_T0_T1_wRn(int rn)
1444 iwmmxt_load_reg(cpu_V0, rn);
1445 tcg_gen_trunc_i64_i32(cpu_T[0], cpu_V0);
1446 tcg_gen_shri_i64(cpu_V0, cpu_V0, 32);
1447 tcg_gen_trunc_i64_i32(cpu_T[1], cpu_V0);
1450 static void gen_iwmmxt_movl_wRn_T0_T1(int rn)
1452 tcg_gen_extu_i32_i64(cpu_V0, cpu_T[0]);
1453 tcg_gen_extu_i32_i64(cpu_V1, cpu_T[0]);
1454 tcg_gen_shli_i64(cpu_V1, cpu_V1, 32);
1455 tcg_gen_or_i64(cpu_V0, cpu_V0, cpu_V1);
1456 iwmmxt_store_reg(cpu_V0, rn);
1459 static inline int gen_iwmmxt_address(DisasContext *s, uint32_t insn)
1464 rd = (insn >> 16) & 0xf;
1465 gen_movl_T1_reg(s, rd);
1467 offset = (insn & 0xff) << ((insn >> 7) & 2);
1468 if (insn & (1 << 24)) {
1470 if (insn & (1 << 23))
1471 gen_op_addl_T1_im(offset);
1473 gen_op_addl_T1_im(-offset);
1475 if (insn & (1 << 21))
1476 gen_movl_reg_T1(s, rd);
1477 } else if (insn & (1 << 21)) {
1479 if (insn & (1 << 23))
1480 gen_op_movl_T0_im(offset);
1482 gen_op_movl_T0_im(- offset);
1483 gen_op_addl_T0_T1();
1484 gen_movl_reg_T0(s, rd);
1485 } else if (!(insn & (1 << 23)))
1490 static inline int gen_iwmmxt_shift(uint32_t insn, uint32_t mask)
1492 int rd = (insn >> 0) & 0xf;
1494 if (insn & (1 << 8))
1495 if (rd < ARM_IWMMXT_wCGR0 || rd > ARM_IWMMXT_wCGR3)
1498 gen_op_iwmmxt_movl_T0_wCx(rd);
1500 gen_iwmmxt_movl_T0_T1_wRn(rd);
1502 gen_op_movl_T1_im(mask);
1503 gen_op_andl_T0_T1();
1507 /* Disassemble an iwMMXt instruction. Returns nonzero if an error occured
1508 (ie. an undefined instruction). */
1509 static int disas_iwmmxt_insn(CPUState *env, DisasContext *s, uint32_t insn)
1512 int rdhi, rdlo, rd0, rd1, i;
1515 if ((insn & 0x0e000e00) == 0x0c000000) {
1516 if ((insn & 0x0fe00ff0) == 0x0c400000) {
1518 rdlo = (insn >> 12) & 0xf;
1519 rdhi = (insn >> 16) & 0xf;
1520 if (insn & ARM_CP_RW_BIT) { /* TMRRC */
1521 gen_iwmmxt_movl_T0_T1_wRn(wrd);
1522 gen_movl_reg_T0(s, rdlo);
1523 gen_movl_reg_T1(s, rdhi);
1524 } else { /* TMCRR */
1525 gen_movl_T0_reg(s, rdlo);
1526 gen_movl_T1_reg(s, rdhi);
1527 gen_iwmmxt_movl_wRn_T0_T1(wrd);
1528 gen_op_iwmmxt_set_mup();
1533 wrd = (insn >> 12) & 0xf;
1534 if (gen_iwmmxt_address(s, insn))
1536 if (insn & ARM_CP_RW_BIT) {
1537 if ((insn >> 28) == 0xf) { /* WLDRW wCx */
1538 tmp = gen_ld32(cpu_T[1], IS_USER(s));
1539 tcg_gen_mov_i32(cpu_T[0], tmp);
1541 gen_op_iwmmxt_movl_wCx_T0(wrd);
1544 if (insn & (1 << 8)) {
1545 if (insn & (1 << 22)) { /* WLDRD */
1546 tcg_gen_qemu_ld64(cpu_M0, cpu_T[1], IS_USER(s));
1548 } else { /* WLDRW wRd */
1549 tmp = gen_ld32(cpu_T[1], IS_USER(s));
1552 if (insn & (1 << 22)) { /* WLDRH */
1553 tmp = gen_ld16u(cpu_T[1], IS_USER(s));
1554 } else { /* WLDRB */
1555 tmp = gen_ld8u(cpu_T[1], IS_USER(s));
1559 tcg_gen_extu_i32_i64(cpu_M0, tmp);
1562 gen_op_iwmmxt_movq_wRn_M0(wrd);
1565 if ((insn >> 28) == 0xf) { /* WSTRW wCx */
1566 gen_op_iwmmxt_movl_T0_wCx(wrd);
1568 tcg_gen_mov_i32(tmp, cpu_T[0]);
1569 gen_st32(tmp, cpu_T[1], IS_USER(s));
1571 gen_op_iwmmxt_movq_M0_wRn(wrd);
1573 if (insn & (1 << 8)) {
1574 if (insn & (1 << 22)) { /* WSTRD */
1576 tcg_gen_qemu_st64(cpu_M0, cpu_T[1], IS_USER(s));
1577 } else { /* WSTRW wRd */
1578 tcg_gen_trunc_i64_i32(tmp, cpu_M0);
1579 gen_st32(tmp, cpu_T[1], IS_USER(s));
1582 if (insn & (1 << 22)) { /* WSTRH */
1583 tcg_gen_trunc_i64_i32(tmp, cpu_M0);
1584 gen_st16(tmp, cpu_T[1], IS_USER(s));
1585 } else { /* WSTRB */
1586 tcg_gen_trunc_i64_i32(tmp, cpu_M0);
1587 gen_st8(tmp, cpu_T[1], IS_USER(s));
1595 if ((insn & 0x0f000000) != 0x0e000000)
1598 switch (((insn >> 12) & 0xf00) | ((insn >> 4) & 0xff)) {
1599 case 0x000: /* WOR */
1600 wrd = (insn >> 12) & 0xf;
1601 rd0 = (insn >> 0) & 0xf;
1602 rd1 = (insn >> 16) & 0xf;
1603 gen_op_iwmmxt_movq_M0_wRn(rd0);
1604 gen_op_iwmmxt_orq_M0_wRn(rd1);
1605 gen_op_iwmmxt_setpsr_nz();
1606 gen_op_iwmmxt_movq_wRn_M0(wrd);
1607 gen_op_iwmmxt_set_mup();
1608 gen_op_iwmmxt_set_cup();
1610 case 0x011: /* TMCR */
1613 rd = (insn >> 12) & 0xf;
1614 wrd = (insn >> 16) & 0xf;
1616 case ARM_IWMMXT_wCID:
1617 case ARM_IWMMXT_wCASF:
1619 case ARM_IWMMXT_wCon:
1620 gen_op_iwmmxt_set_cup();
1622 case ARM_IWMMXT_wCSSF:
1623 gen_op_iwmmxt_movl_T0_wCx(wrd);
1624 gen_movl_T1_reg(s, rd);
1625 gen_op_bicl_T0_T1();
1626 gen_op_iwmmxt_movl_wCx_T0(wrd);
1628 case ARM_IWMMXT_wCGR0:
1629 case ARM_IWMMXT_wCGR1:
1630 case ARM_IWMMXT_wCGR2:
1631 case ARM_IWMMXT_wCGR3:
1632 gen_op_iwmmxt_set_cup();
1633 gen_movl_reg_T0(s, rd);
1634 gen_op_iwmmxt_movl_wCx_T0(wrd);
1640 case 0x100: /* WXOR */
1641 wrd = (insn >> 12) & 0xf;
1642 rd0 = (insn >> 0) & 0xf;
1643 rd1 = (insn >> 16) & 0xf;
1644 gen_op_iwmmxt_movq_M0_wRn(rd0);
1645 gen_op_iwmmxt_xorq_M0_wRn(rd1);
1646 gen_op_iwmmxt_setpsr_nz();
1647 gen_op_iwmmxt_movq_wRn_M0(wrd);
1648 gen_op_iwmmxt_set_mup();
1649 gen_op_iwmmxt_set_cup();
1651 case 0x111: /* TMRC */
1654 rd = (insn >> 12) & 0xf;
1655 wrd = (insn >> 16) & 0xf;
1656 gen_op_iwmmxt_movl_T0_wCx(wrd);
1657 gen_movl_reg_T0(s, rd);
1659 case 0x300: /* WANDN */
1660 wrd = (insn >> 12) & 0xf;
1661 rd0 = (insn >> 0) & 0xf;
1662 rd1 = (insn >> 16) & 0xf;
1663 gen_op_iwmmxt_movq_M0_wRn(rd0);
1664 tcg_gen_neg_i64(cpu_M0, cpu_M0);
1665 gen_op_iwmmxt_andq_M0_wRn(rd1);
1666 gen_op_iwmmxt_setpsr_nz();
1667 gen_op_iwmmxt_movq_wRn_M0(wrd);
1668 gen_op_iwmmxt_set_mup();
1669 gen_op_iwmmxt_set_cup();
1671 case 0x200: /* WAND */
1672 wrd = (insn >> 12) & 0xf;
1673 rd0 = (insn >> 0) & 0xf;
1674 rd1 = (insn >> 16) & 0xf;
1675 gen_op_iwmmxt_movq_M0_wRn(rd0);
1676 gen_op_iwmmxt_andq_M0_wRn(rd1);
1677 gen_op_iwmmxt_setpsr_nz();
1678 gen_op_iwmmxt_movq_wRn_M0(wrd);
1679 gen_op_iwmmxt_set_mup();
1680 gen_op_iwmmxt_set_cup();
1682 case 0x810: case 0xa10: /* WMADD */
1683 wrd = (insn >> 12) & 0xf;
1684 rd0 = (insn >> 0) & 0xf;
1685 rd1 = (insn >> 16) & 0xf;
1686 gen_op_iwmmxt_movq_M0_wRn(rd0);
1687 if (insn & (1 << 21))
1688 gen_op_iwmmxt_maddsq_M0_wRn(rd1);
1690 gen_op_iwmmxt_madduq_M0_wRn(rd1);
1691 gen_op_iwmmxt_movq_wRn_M0(wrd);
1692 gen_op_iwmmxt_set_mup();
1694 case 0x10e: case 0x50e: case 0x90e: case 0xd0e: /* WUNPCKIL */
1695 wrd = (insn >> 12) & 0xf;
1696 rd0 = (insn >> 16) & 0xf;
1697 rd1 = (insn >> 0) & 0xf;
1698 gen_op_iwmmxt_movq_M0_wRn(rd0);
1699 switch ((insn >> 22) & 3) {
1701 gen_op_iwmmxt_unpacklb_M0_wRn(rd1);
1704 gen_op_iwmmxt_unpacklw_M0_wRn(rd1);
1707 gen_op_iwmmxt_unpackll_M0_wRn(rd1);
1712 gen_op_iwmmxt_movq_wRn_M0(wrd);
1713 gen_op_iwmmxt_set_mup();
1714 gen_op_iwmmxt_set_cup();
1716 case 0x10c: case 0x50c: case 0x90c: case 0xd0c: /* WUNPCKIH */
1717 wrd = (insn >> 12) & 0xf;
1718 rd0 = (insn >> 16) & 0xf;
1719 rd1 = (insn >> 0) & 0xf;
1720 gen_op_iwmmxt_movq_M0_wRn(rd0);
1721 switch ((insn >> 22) & 3) {
1723 gen_op_iwmmxt_unpackhb_M0_wRn(rd1);
1726 gen_op_iwmmxt_unpackhw_M0_wRn(rd1);
1729 gen_op_iwmmxt_unpackhl_M0_wRn(rd1);
1734 gen_op_iwmmxt_movq_wRn_M0(wrd);
1735 gen_op_iwmmxt_set_mup();
1736 gen_op_iwmmxt_set_cup();
1738 case 0x012: case 0x112: case 0x412: case 0x512: /* WSAD */
1739 wrd = (insn >> 12) & 0xf;
1740 rd0 = (insn >> 16) & 0xf;
1741 rd1 = (insn >> 0) & 0xf;
1742 gen_op_iwmmxt_movq_M0_wRn(rd0);
1743 if (insn & (1 << 22))
1744 gen_op_iwmmxt_sadw_M0_wRn(rd1);
1746 gen_op_iwmmxt_sadb_M0_wRn(rd1);
1747 if (!(insn & (1 << 20)))
1748 gen_op_iwmmxt_addl_M0_wRn(wrd);
1749 gen_op_iwmmxt_movq_wRn_M0(wrd);
1750 gen_op_iwmmxt_set_mup();
1752 case 0x010: case 0x110: case 0x210: case 0x310: /* WMUL */
1753 wrd = (insn >> 12) & 0xf;
1754 rd0 = (insn >> 16) & 0xf;
1755 rd1 = (insn >> 0) & 0xf;
1756 gen_op_iwmmxt_movq_M0_wRn(rd0);
1757 if (insn & (1 << 21)) {
1758 if (insn & (1 << 20))
1759 gen_op_iwmmxt_mulshw_M0_wRn(rd1);
1761 gen_op_iwmmxt_mulslw_M0_wRn(rd1);
1763 if (insn & (1 << 20))
1764 gen_op_iwmmxt_muluhw_M0_wRn(rd1);
1766 gen_op_iwmmxt_mululw_M0_wRn(rd1);
1768 gen_op_iwmmxt_movq_wRn_M0(wrd);
1769 gen_op_iwmmxt_set_mup();
1771 case 0x410: case 0x510: case 0x610: case 0x710: /* WMAC */
1772 wrd = (insn >> 12) & 0xf;
1773 rd0 = (insn >> 16) & 0xf;
1774 rd1 = (insn >> 0) & 0xf;
1775 gen_op_iwmmxt_movq_M0_wRn(rd0);
1776 if (insn & (1 << 21))
1777 gen_op_iwmmxt_macsw_M0_wRn(rd1);
1779 gen_op_iwmmxt_macuw_M0_wRn(rd1);
1780 if (!(insn & (1 << 20))) {
1781 iwmmxt_load_reg(cpu_V1, wrd);
1782 tcg_gen_add_i64(cpu_M0, cpu_M0, cpu_V1);
1784 gen_op_iwmmxt_movq_wRn_M0(wrd);
1785 gen_op_iwmmxt_set_mup();
1787 case 0x006: case 0x406: case 0x806: case 0xc06: /* WCMPEQ */
1788 wrd = (insn >> 12) & 0xf;
1789 rd0 = (insn >> 16) & 0xf;
1790 rd1 = (insn >> 0) & 0xf;
1791 gen_op_iwmmxt_movq_M0_wRn(rd0);
1792 switch ((insn >> 22) & 3) {
1794 gen_op_iwmmxt_cmpeqb_M0_wRn(rd1);
1797 gen_op_iwmmxt_cmpeqw_M0_wRn(rd1);
1800 gen_op_iwmmxt_cmpeql_M0_wRn(rd1);
1805 gen_op_iwmmxt_movq_wRn_M0(wrd);
1806 gen_op_iwmmxt_set_mup();
1807 gen_op_iwmmxt_set_cup();
1809 case 0x800: case 0x900: case 0xc00: case 0xd00: /* WAVG2 */
1810 wrd = (insn >> 12) & 0xf;
1811 rd0 = (insn >> 16) & 0xf;
1812 rd1 = (insn >> 0) & 0xf;
1813 gen_op_iwmmxt_movq_M0_wRn(rd0);
1814 if (insn & (1 << 22)) {
1815 if (insn & (1 << 20))
1816 gen_op_iwmmxt_avgw1_M0_wRn(rd1);
1818 gen_op_iwmmxt_avgw0_M0_wRn(rd1);
1820 if (insn & (1 << 20))
1821 gen_op_iwmmxt_avgb1_M0_wRn(rd1);
1823 gen_op_iwmmxt_avgb0_M0_wRn(rd1);
1825 gen_op_iwmmxt_movq_wRn_M0(wrd);
1826 gen_op_iwmmxt_set_mup();
1827 gen_op_iwmmxt_set_cup();
1829 case 0x802: case 0x902: case 0xa02: case 0xb02: /* WALIGNR */
1830 wrd = (insn >> 12) & 0xf;
1831 rd0 = (insn >> 16) & 0xf;
1832 rd1 = (insn >> 0) & 0xf;
1833 gen_op_iwmmxt_movq_M0_wRn(rd0);
1834 gen_op_iwmmxt_movl_T0_wCx(ARM_IWMMXT_wCGR0 + ((insn >> 20) & 3));
1835 gen_op_movl_T1_im(7);
1836 gen_op_andl_T0_T1();
1837 gen_op_iwmmxt_align_M0_T0_wRn(rd1);
1838 gen_op_iwmmxt_movq_wRn_M0(wrd);
1839 gen_op_iwmmxt_set_mup();
1841 case 0x601: case 0x605: case 0x609: case 0x60d: /* TINSR */
1842 rd = (insn >> 12) & 0xf;
1843 wrd = (insn >> 16) & 0xf;
1844 gen_movl_T0_reg(s, rd);
1845 gen_op_iwmmxt_movq_M0_wRn(wrd);
1846 switch ((insn >> 6) & 3) {
1848 gen_op_movl_T1_im(0xff);
1849 gen_op_iwmmxt_insr_M0_T0_T1((insn & 7) << 3);
1852 gen_op_movl_T1_im(0xffff);
1853 gen_op_iwmmxt_insr_M0_T0_T1((insn & 3) << 4);
1856 gen_op_movl_T1_im(0xffffffff);
1857 gen_op_iwmmxt_insr_M0_T0_T1((insn & 1) << 5);
1862 gen_op_iwmmxt_movq_wRn_M0(wrd);
1863 gen_op_iwmmxt_set_mup();
1865 case 0x107: case 0x507: case 0x907: case 0xd07: /* TEXTRM */
1866 rd = (insn >> 12) & 0xf;
1867 wrd = (insn >> 16) & 0xf;
1870 gen_op_iwmmxt_movq_M0_wRn(wrd);
1871 switch ((insn >> 22) & 3) {
1874 gen_op_iwmmxt_extrsb_T0_M0((insn & 7) << 3);
1876 gen_op_iwmmxt_extru_T0_M0((insn & 7) << 3, 0xff);
1881 gen_op_iwmmxt_extrsw_T0_M0((insn & 3) << 4);
1883 gen_op_iwmmxt_extru_T0_M0((insn & 3) << 4, 0xffff);
1887 gen_op_iwmmxt_extru_T0_M0((insn & 1) << 5, ~0u);
1892 gen_movl_reg_T0(s, rd);
1894 case 0x117: case 0x517: case 0x917: case 0xd17: /* TEXTRC */
1895 if ((insn & 0x000ff008) != 0x0003f000)
1897 gen_op_iwmmxt_movl_T1_wCx(ARM_IWMMXT_wCASF);
1898 switch ((insn >> 22) & 3) {
1900 gen_op_shrl_T1_im(((insn & 7) << 2) + 0);
1903 gen_op_shrl_T1_im(((insn & 3) << 3) + 4);
1906 gen_op_shrl_T1_im(((insn & 1) << 4) + 12);
1911 gen_op_shll_T1_im(28);
1912 gen_set_nzcv(cpu_T[1]);
1914 case 0x401: case 0x405: case 0x409: case 0x40d: /* TBCST */
1915 rd = (insn >> 12) & 0xf;
1916 wrd = (insn >> 16) & 0xf;
1917 gen_movl_T0_reg(s, rd);
1918 switch ((insn >> 6) & 3) {
1920 gen_helper_iwmmxt_bcstb(cpu_M0, cpu_T[0]);
1923 gen_helper_iwmmxt_bcstw(cpu_M0, cpu_T[0]);
1926 gen_helper_iwmmxt_bcstl(cpu_M0, cpu_T[0]);
1931 gen_op_iwmmxt_movq_wRn_M0(wrd);
1932 gen_op_iwmmxt_set_mup();
1934 case 0x113: case 0x513: case 0x913: case 0xd13: /* TANDC */
1935 if ((insn & 0x000ff00f) != 0x0003f000)
1937 gen_op_iwmmxt_movl_T1_wCx(ARM_IWMMXT_wCASF);
1938 switch ((insn >> 22) & 3) {
1940 for (i = 0; i < 7; i ++) {
1941 gen_op_shll_T1_im(4);
1942 gen_op_andl_T0_T1();
1946 for (i = 0; i < 3; i ++) {
1947 gen_op_shll_T1_im(8);
1948 gen_op_andl_T0_T1();
1952 gen_op_shll_T1_im(16);
1953 gen_op_andl_T0_T1();
1958 gen_set_nzcv(cpu_T[0]);
1960 case 0x01c: case 0x41c: case 0x81c: case 0xc1c: /* WACC */
1961 wrd = (insn >> 12) & 0xf;
1962 rd0 = (insn >> 16) & 0xf;
1963 gen_op_iwmmxt_movq_M0_wRn(rd0);
1964 switch ((insn >> 22) & 3) {
1966 gen_helper_iwmmxt_addcb(cpu_M0, cpu_M0);
1969 gen_helper_iwmmxt_addcw(cpu_M0, cpu_M0);
1972 gen_helper_iwmmxt_addcl(cpu_M0, cpu_M0);
1977 gen_op_iwmmxt_movq_wRn_M0(wrd);
1978 gen_op_iwmmxt_set_mup();
1980 case 0x115: case 0x515: case 0x915: case 0xd15: /* TORC */
1981 if ((insn & 0x000ff00f) != 0x0003f000)
1983 gen_op_iwmmxt_movl_T1_wCx(ARM_IWMMXT_wCASF);
1984 switch ((insn >> 22) & 3) {
1986 for (i = 0; i < 7; i ++) {
1987 gen_op_shll_T1_im(4);
1992 for (i = 0; i < 3; i ++) {
1993 gen_op_shll_T1_im(8);
1998 gen_op_shll_T1_im(16);
2004 gen_set_nzcv(cpu_T[0]);
2006 case 0x103: case 0x503: case 0x903: case 0xd03: /* TMOVMSK */
2007 rd = (insn >> 12) & 0xf;
2008 rd0 = (insn >> 16) & 0xf;
2009 if ((insn & 0xf) != 0)
2011 gen_op_iwmmxt_movq_M0_wRn(rd0);
2012 switch ((insn >> 22) & 3) {
2014 gen_helper_iwmmxt_msbb(cpu_T[0], cpu_M0);
2017 gen_helper_iwmmxt_msbw(cpu_T[0], cpu_M0);
2020 gen_helper_iwmmxt_msbl(cpu_T[0], cpu_M0);
2025 gen_movl_reg_T0(s, rd);
2027 case 0x106: case 0x306: case 0x506: case 0x706: /* WCMPGT */
2028 case 0x906: case 0xb06: case 0xd06: case 0xf06:
2029 wrd = (insn >> 12) & 0xf;
2030 rd0 = (insn >> 16) & 0xf;
2031 rd1 = (insn >> 0) & 0xf;
2032 gen_op_iwmmxt_movq_M0_wRn(rd0);
2033 switch ((insn >> 22) & 3) {
2035 if (insn & (1 << 21))
2036 gen_op_iwmmxt_cmpgtsb_M0_wRn(rd1);
2038 gen_op_iwmmxt_cmpgtub_M0_wRn(rd1);
2041 if (insn & (1 << 21))
2042 gen_op_iwmmxt_cmpgtsw_M0_wRn(rd1);
2044 gen_op_iwmmxt_cmpgtuw_M0_wRn(rd1);
2047 if (insn & (1 << 21))
2048 gen_op_iwmmxt_cmpgtsl_M0_wRn(rd1);
2050 gen_op_iwmmxt_cmpgtul_M0_wRn(rd1);
2055 gen_op_iwmmxt_movq_wRn_M0(wrd);
2056 gen_op_iwmmxt_set_mup();
2057 gen_op_iwmmxt_set_cup();
2059 case 0x00e: case 0x20e: case 0x40e: case 0x60e: /* WUNPCKEL */
2060 case 0x80e: case 0xa0e: case 0xc0e: case 0xe0e:
2061 wrd = (insn >> 12) & 0xf;
2062 rd0 = (insn >> 16) & 0xf;
2063 gen_op_iwmmxt_movq_M0_wRn(rd0);
2064 switch ((insn >> 22) & 3) {
2066 if (insn & (1 << 21))
2067 gen_op_iwmmxt_unpacklsb_M0();
2069 gen_op_iwmmxt_unpacklub_M0();
2072 if (insn & (1 << 21))
2073 gen_op_iwmmxt_unpacklsw_M0();
2075 gen_op_iwmmxt_unpackluw_M0();
2078 if (insn & (1 << 21))
2079 gen_op_iwmmxt_unpacklsl_M0();
2081 gen_op_iwmmxt_unpacklul_M0();
2086 gen_op_iwmmxt_movq_wRn_M0(wrd);
2087 gen_op_iwmmxt_set_mup();
2088 gen_op_iwmmxt_set_cup();
2090 case 0x00c: case 0x20c: case 0x40c: case 0x60c: /* WUNPCKEH */
2091 case 0x80c: case 0xa0c: case 0xc0c: case 0xe0c:
2092 wrd = (insn >> 12) & 0xf;
2093 rd0 = (insn >> 16) & 0xf;
2094 gen_op_iwmmxt_movq_M0_wRn(rd0);
2095 switch ((insn >> 22) & 3) {
2097 if (insn & (1 << 21))
2098 gen_op_iwmmxt_unpackhsb_M0();
2100 gen_op_iwmmxt_unpackhub_M0();
2103 if (insn & (1 << 21))
2104 gen_op_iwmmxt_unpackhsw_M0();
2106 gen_op_iwmmxt_unpackhuw_M0();
2109 if (insn & (1 << 21))
2110 gen_op_iwmmxt_unpackhsl_M0();
2112 gen_op_iwmmxt_unpackhul_M0();
2117 gen_op_iwmmxt_movq_wRn_M0(wrd);
2118 gen_op_iwmmxt_set_mup();
2119 gen_op_iwmmxt_set_cup();
2121 case 0x204: case 0x604: case 0xa04: case 0xe04: /* WSRL */
2122 case 0x214: case 0x614: case 0xa14: case 0xe14:
2123 wrd = (insn >> 12) & 0xf;
2124 rd0 = (insn >> 16) & 0xf;
2125 gen_op_iwmmxt_movq_M0_wRn(rd0);
2126 if (gen_iwmmxt_shift(insn, 0xff))
2128 switch ((insn >> 22) & 3) {
2132 gen_helper_iwmmxt_srlw(cpu_M0, cpu_env, cpu_M0, cpu_T[0]);
2135 gen_helper_iwmmxt_srll(cpu_M0, cpu_env, cpu_M0, cpu_T[0]);
2138 gen_helper_iwmmxt_srlq(cpu_M0, cpu_env, cpu_M0, cpu_T[0]);
2141 gen_op_iwmmxt_movq_wRn_M0(wrd);
2142 gen_op_iwmmxt_set_mup();
2143 gen_op_iwmmxt_set_cup();
2145 case 0x004: case 0x404: case 0x804: case 0xc04: /* WSRA */
2146 case 0x014: case 0x414: case 0x814: case 0xc14:
2147 wrd = (insn >> 12) & 0xf;
2148 rd0 = (insn >> 16) & 0xf;
2149 gen_op_iwmmxt_movq_M0_wRn(rd0);
2150 if (gen_iwmmxt_shift(insn, 0xff))
2152 switch ((insn >> 22) & 3) {
2156 gen_helper_iwmmxt_sraw(cpu_M0, cpu_env, cpu_M0, cpu_T[0]);
2159 gen_helper_iwmmxt_sral(cpu_M0, cpu_env, cpu_M0, cpu_T[0]);
2162 gen_helper_iwmmxt_sraq(cpu_M0, cpu_env, cpu_M0, cpu_T[0]);
2165 gen_op_iwmmxt_movq_wRn_M0(wrd);
2166 gen_op_iwmmxt_set_mup();
2167 gen_op_iwmmxt_set_cup();
2169 case 0x104: case 0x504: case 0x904: case 0xd04: /* WSLL */
2170 case 0x114: case 0x514: case 0x914: case 0xd14:
2171 wrd = (insn >> 12) & 0xf;
2172 rd0 = (insn >> 16) & 0xf;
2173 gen_op_iwmmxt_movq_M0_wRn(rd0);
2174 if (gen_iwmmxt_shift(insn, 0xff))
2176 switch ((insn >> 22) & 3) {
2180 gen_helper_iwmmxt_sllw(cpu_M0, cpu_env, cpu_M0, cpu_T[0]);
2183 gen_helper_iwmmxt_slll(cpu_M0, cpu_env, cpu_M0, cpu_T[0]);
2186 gen_helper_iwmmxt_sllq(cpu_M0, cpu_env, cpu_M0, cpu_T[0]);
2189 gen_op_iwmmxt_movq_wRn_M0(wrd);
2190 gen_op_iwmmxt_set_mup();
2191 gen_op_iwmmxt_set_cup();
2193 case 0x304: case 0x704: case 0xb04: case 0xf04: /* WROR */
2194 case 0x314: case 0x714: case 0xb14: case 0xf14:
2195 wrd = (insn >> 12) & 0xf;
2196 rd0 = (insn >> 16) & 0xf;
2197 gen_op_iwmmxt_movq_M0_wRn(rd0);
2198 switch ((insn >> 22) & 3) {
2202 if (gen_iwmmxt_shift(insn, 0xf))
2204 gen_helper_iwmmxt_rorw(cpu_M0, cpu_env, cpu_M0, cpu_T[0]);
2207 if (gen_iwmmxt_shift(insn, 0x1f))
2209 gen_helper_iwmmxt_rorl(cpu_M0, cpu_env, cpu_M0, cpu_T[0]);
2212 if (gen_iwmmxt_shift(insn, 0x3f))
2214 gen_helper_iwmmxt_rorq(cpu_M0, cpu_env, cpu_M0, cpu_T[0]);
2217 gen_op_iwmmxt_movq_wRn_M0(wrd);
2218 gen_op_iwmmxt_set_mup();
2219 gen_op_iwmmxt_set_cup();
2221 case 0x116: case 0x316: case 0x516: case 0x716: /* WMIN */
2222 case 0x916: case 0xb16: case 0xd16: case 0xf16:
2223 wrd = (insn >> 12) & 0xf;
2224 rd0 = (insn >> 16) & 0xf;
2225 rd1 = (insn >> 0) & 0xf;
2226 gen_op_iwmmxt_movq_M0_wRn(rd0);
2227 switch ((insn >> 22) & 3) {
2229 if (insn & (1 << 21))
2230 gen_op_iwmmxt_minsb_M0_wRn(rd1);
2232 gen_op_iwmmxt_minub_M0_wRn(rd1);
2235 if (insn & (1 << 21))
2236 gen_op_iwmmxt_minsw_M0_wRn(rd1);
2238 gen_op_iwmmxt_minuw_M0_wRn(rd1);
2241 if (insn & (1 << 21))
2242 gen_op_iwmmxt_minsl_M0_wRn(rd1);
2244 gen_op_iwmmxt_minul_M0_wRn(rd1);
2249 gen_op_iwmmxt_movq_wRn_M0(wrd);
2250 gen_op_iwmmxt_set_mup();
2252 case 0x016: case 0x216: case 0x416: case 0x616: /* WMAX */
2253 case 0x816: case 0xa16: case 0xc16: case 0xe16:
2254 wrd = (insn >> 12) & 0xf;
2255 rd0 = (insn >> 16) & 0xf;
2256 rd1 = (insn >> 0) & 0xf;
2257 gen_op_iwmmxt_movq_M0_wRn(rd0);
2258 switch ((insn >> 22) & 3) {
2260 if (insn & (1 << 21))
2261 gen_op_iwmmxt_maxsb_M0_wRn(rd1);
2263 gen_op_iwmmxt_maxub_M0_wRn(rd1);
2266 if (insn & (1 << 21))
2267 gen_op_iwmmxt_maxsw_M0_wRn(rd1);
2269 gen_op_iwmmxt_maxuw_M0_wRn(rd1);
2272 if (insn & (1 << 21))
2273 gen_op_iwmmxt_maxsl_M0_wRn(rd1);
2275 gen_op_iwmmxt_maxul_M0_wRn(rd1);
2280 gen_op_iwmmxt_movq_wRn_M0(wrd);
2281 gen_op_iwmmxt_set_mup();
2283 case 0x002: case 0x102: case 0x202: case 0x302: /* WALIGNI */
2284 case 0x402: case 0x502: case 0x602: case 0x702:
2285 wrd = (insn >> 12) & 0xf;
2286 rd0 = (insn >> 16) & 0xf;
2287 rd1 = (insn >> 0) & 0xf;
2288 gen_op_iwmmxt_movq_M0_wRn(rd0);
2289 gen_op_movl_T0_im((insn >> 20) & 3);
2290 gen_op_iwmmxt_align_M0_T0_wRn(rd1);
2291 gen_op_iwmmxt_movq_wRn_M0(wrd);
2292 gen_op_iwmmxt_set_mup();
2294 case 0x01a: case 0x11a: case 0x21a: case 0x31a: /* WSUB */
2295 case 0x41a: case 0x51a: case 0x61a: case 0x71a:
2296 case 0x81a: case 0x91a: case 0xa1a: case 0xb1a:
2297 case 0xc1a: case 0xd1a: case 0xe1a: case 0xf1a:
2298 wrd = (insn >> 12) & 0xf;
2299 rd0 = (insn >> 16) & 0xf;
2300 rd1 = (insn >> 0) & 0xf;
2301 gen_op_iwmmxt_movq_M0_wRn(rd0);
2302 switch ((insn >> 20) & 0xf) {
2304 gen_op_iwmmxt_subnb_M0_wRn(rd1);
2307 gen_op_iwmmxt_subub_M0_wRn(rd1);
2310 gen_op_iwmmxt_subsb_M0_wRn(rd1);
2313 gen_op_iwmmxt_subnw_M0_wRn(rd1);
2316 gen_op_iwmmxt_subuw_M0_wRn(rd1);
2319 gen_op_iwmmxt_subsw_M0_wRn(rd1);
2322 gen_op_iwmmxt_subnl_M0_wRn(rd1);
2325 gen_op_iwmmxt_subul_M0_wRn(rd1);
2328 gen_op_iwmmxt_subsl_M0_wRn(rd1);
2333 gen_op_iwmmxt_movq_wRn_M0(wrd);
2334 gen_op_iwmmxt_set_mup();
2335 gen_op_iwmmxt_set_cup();
2337 case 0x01e: case 0x11e: case 0x21e: case 0x31e: /* WSHUFH */
2338 case 0x41e: case 0x51e: case 0x61e: case 0x71e:
2339 case 0x81e: case 0x91e: case 0xa1e: case 0xb1e:
2340 case 0xc1e: case 0xd1e: case 0xe1e: case 0xf1e:
2341 wrd = (insn >> 12) & 0xf;
2342 rd0 = (insn >> 16) & 0xf;
2343 gen_op_iwmmxt_movq_M0_wRn(rd0);
2344 gen_op_movl_T0_im(((insn >> 16) & 0xf0) | (insn & 0x0f));
2345 gen_helper_iwmmxt_shufh(cpu_M0, cpu_env, cpu_M0, cpu_T[0]);
2346 gen_op_iwmmxt_movq_wRn_M0(wrd);
2347 gen_op_iwmmxt_set_mup();
2348 gen_op_iwmmxt_set_cup();
2350 case 0x018: case 0x118: case 0x218: case 0x318: /* WADD */
2351 case 0x418: case 0x518: case 0x618: case 0x718:
2352 case 0x818: case 0x918: case 0xa18: case 0xb18:
2353 case 0xc18: case 0xd18: case 0xe18: case 0xf18:
2354 wrd = (insn >> 12) & 0xf;
2355 rd0 = (insn >> 16) & 0xf;
2356 rd1 = (insn >> 0) & 0xf;
2357 gen_op_iwmmxt_movq_M0_wRn(rd0);
2358 switch ((insn >> 20) & 0xf) {
2360 gen_op_iwmmxt_addnb_M0_wRn(rd1);
2363 gen_op_iwmmxt_addub_M0_wRn(rd1);
2366 gen_op_iwmmxt_addsb_M0_wRn(rd1);
2369 gen_op_iwmmxt_addnw_M0_wRn(rd1);
2372 gen_op_iwmmxt_adduw_M0_wRn(rd1);
2375 gen_op_iwmmxt_addsw_M0_wRn(rd1);
2378 gen_op_iwmmxt_addnl_M0_wRn(rd1);
2381 gen_op_iwmmxt_addul_M0_wRn(rd1);
2384 gen_op_iwmmxt_addsl_M0_wRn(rd1);
2389 gen_op_iwmmxt_movq_wRn_M0(wrd);
2390 gen_op_iwmmxt_set_mup();
2391 gen_op_iwmmxt_set_cup();
2393 case 0x008: case 0x108: case 0x208: case 0x308: /* WPACK */
2394 case 0x408: case 0x508: case 0x608: case 0x708:
2395 case 0x808: case 0x908: case 0xa08: case 0xb08:
2396 case 0xc08: case 0xd08: case 0xe08: case 0xf08:
2397 wrd = (insn >> 12) & 0xf;
2398 rd0 = (insn >> 16) & 0xf;
2399 rd1 = (insn >> 0) & 0xf;
2400 gen_op_iwmmxt_movq_M0_wRn(rd0);
2401 if (!(insn & (1 << 20)))
2403 switch ((insn >> 22) & 3) {
2407 if (insn & (1 << 21))
2408 gen_op_iwmmxt_packsw_M0_wRn(rd1);
2410 gen_op_iwmmxt_packuw_M0_wRn(rd1);
2413 if (insn & (1 << 21))
2414 gen_op_iwmmxt_packsl_M0_wRn(rd1);
2416 gen_op_iwmmxt_packul_M0_wRn(rd1);
2419 if (insn & (1 << 21))
2420 gen_op_iwmmxt_packsq_M0_wRn(rd1);
2422 gen_op_iwmmxt_packuq_M0_wRn(rd1);
2425 gen_op_iwmmxt_movq_wRn_M0(wrd);
2426 gen_op_iwmmxt_set_mup();
2427 gen_op_iwmmxt_set_cup();
2429 case 0x201: case 0x203: case 0x205: case 0x207:
2430 case 0x209: case 0x20b: case 0x20d: case 0x20f:
2431 case 0x211: case 0x213: case 0x215: case 0x217:
2432 case 0x219: case 0x21b: case 0x21d: case 0x21f:
2433 wrd = (insn >> 5) & 0xf;
2434 rd0 = (insn >> 12) & 0xf;
2435 rd1 = (insn >> 0) & 0xf;
2436 if (rd0 == 0xf || rd1 == 0xf)
2438 gen_op_iwmmxt_movq_M0_wRn(wrd);
2439 switch ((insn >> 16) & 0xf) {
2440 case 0x0: /* TMIA */
2441 gen_movl_T0_reg(s, rd0);
2442 gen_movl_T1_reg(s, rd1);
2443 gen_op_iwmmxt_muladdsl_M0_T0_T1();
2445 case 0x8: /* TMIAPH */
2446 gen_movl_T0_reg(s, rd0);
2447 gen_movl_T1_reg(s, rd1);
2448 gen_op_iwmmxt_muladdsw_M0_T0_T1();
2450 case 0xc: case 0xd: case 0xe: case 0xf: /* TMIAxy */
2451 gen_movl_T1_reg(s, rd0);
2452 if (insn & (1 << 16))
2453 gen_op_shrl_T1_im(16);
2454 gen_op_movl_T0_T1();
2455 gen_movl_T1_reg(s, rd1);
2456 if (insn & (1 << 17))
2457 gen_op_shrl_T1_im(16);
2458 gen_op_iwmmxt_muladdswl_M0_T0_T1();
2463 gen_op_iwmmxt_movq_wRn_M0(wrd);
2464 gen_op_iwmmxt_set_mup();
2473 /* Disassemble an XScale DSP instruction. Returns nonzero if an error occured
2474 (ie. an undefined instruction). */
2475 static int disas_dsp_insn(CPUState *env, DisasContext *s, uint32_t insn)
2477 int acc, rd0, rd1, rdhi, rdlo;
2479 if ((insn & 0x0ff00f10) == 0x0e200010) {
2480 /* Multiply with Internal Accumulate Format */
2481 rd0 = (insn >> 12) & 0xf;
2483 acc = (insn >> 5) & 7;
2488 switch ((insn >> 16) & 0xf) {
2490 gen_movl_T0_reg(s, rd0);
2491 gen_movl_T1_reg(s, rd1);
2492 gen_op_iwmmxt_muladdsl_M0_T0_T1();
2494 case 0x8: /* MIAPH */
2495 gen_movl_T0_reg(s, rd0);
2496 gen_movl_T1_reg(s, rd1);
2497 gen_op_iwmmxt_muladdsw_M0_T0_T1();
2499 case 0xc: /* MIABB */
2500 case 0xd: /* MIABT */
2501 case 0xe: /* MIATB */
2502 case 0xf: /* MIATT */
2503 gen_movl_T1_reg(s, rd0);
2504 if (insn & (1 << 16))
2505 gen_op_shrl_T1_im(16);
2506 gen_op_movl_T0_T1();
2507 gen_movl_T1_reg(s, rd1);
2508 if (insn & (1 << 17))
2509 gen_op_shrl_T1_im(16);
2510 gen_op_iwmmxt_muladdswl_M0_T0_T1();
2516 gen_op_iwmmxt_movq_wRn_M0(acc);
2520 if ((insn & 0x0fe00ff8) == 0x0c400000) {
2521 /* Internal Accumulator Access Format */
2522 rdhi = (insn >> 16) & 0xf;
2523 rdlo = (insn >> 12) & 0xf;
2529 if (insn & ARM_CP_RW_BIT) { /* MRA */
2530 gen_iwmmxt_movl_T0_T1_wRn(acc);
2531 gen_movl_reg_T0(s, rdlo);
2532 gen_op_movl_T0_im((1 << (40 - 32)) - 1);
2533 gen_op_andl_T0_T1();
2534 gen_movl_reg_T0(s, rdhi);
2536 gen_movl_T0_reg(s, rdlo);
2537 gen_movl_T1_reg(s, rdhi);
2538 gen_iwmmxt_movl_wRn_T0_T1(acc);
2546 /* Disassemble system coprocessor instruction. Return nonzero if
2547 instruction is not defined. */
2548 static int disas_cp_insn(CPUState *env, DisasContext *s, uint32_t insn)
2551 uint32_t rd = (insn >> 12) & 0xf;
2552 uint32_t cp = (insn >> 8) & 0xf;
2557 if (insn & ARM_CP_RW_BIT) {
2558 if (!env->cp[cp].cp_read)
2560 gen_set_pc_im(s->pc);
2562 gen_helper_get_cp(tmp, cpu_env, tcg_const_i32(insn));
2563 store_reg(s, rd, tmp);
2565 if (!env->cp[cp].cp_write)
2567 gen_set_pc_im(s->pc);
2568 tmp = load_reg(s, rd);
2569 gen_helper_set_cp(cpu_env, tcg_const_i32(insn), tmp);
2574 static int cp15_user_ok(uint32_t insn)
2576 int cpn = (insn >> 16) & 0xf;
2577 int cpm = insn & 0xf;
2578 int op = ((insn >> 5) & 7) | ((insn >> 18) & 0x38);
2580 if (cpn == 13 && cpm == 0) {
2582 if (op == 2 || (op == 3 && (insn & ARM_CP_RW_BIT)))
2586 /* ISB, DSB, DMB. */
2587 if ((cpm == 5 && op == 4)
2588 || (cpm == 10 && (op == 4 || op == 5)))
2594 /* Disassemble system coprocessor (cp15) instruction. Return nonzero if
2595 instruction is not defined. */
2596 static int disas_cp15_insn(CPUState *env, DisasContext *s, uint32_t insn)
2601 /* M profile cores use memory mapped registers instead of cp15. */
2602 if (arm_feature(env, ARM_FEATURE_M))
2605 if ((insn & (1 << 25)) == 0) {
2606 if (insn & (1 << 20)) {
2610 /* mcrr. Used for block cache operations, so implement as no-op. */
2613 if ((insn & (1 << 4)) == 0) {
2617 if (IS_USER(s) && !cp15_user_ok(insn)) {
2620 if ((insn & 0x0fff0fff) == 0x0e070f90
2621 || (insn & 0x0fff0fff) == 0x0e070f58) {
2622 /* Wait for interrupt. */
2623 gen_set_pc_im(s->pc);
2624 s->is_jmp = DISAS_WFI;
2627 rd = (insn >> 12) & 0xf;
2628 if (insn & ARM_CP_RW_BIT) {
2630 gen_helper_get_cp15(tmp, cpu_env, tcg_const_i32(insn));
2631 /* If the destination register is r15 then sets condition codes. */
2633 store_reg(s, rd, tmp);
2637 tmp = load_reg(s, rd);
2638 gen_helper_set_cp15(cpu_env, tcg_const_i32(insn), tmp);
2640 /* Normally we would always end the TB here, but Linux
2641 * arch/arm/mach-pxa/sleep.S expects two instructions following
2642 * an MMU enable to execute from cache. Imitate this behaviour. */
2643 if (!arm_feature(env, ARM_FEATURE_XSCALE) ||
2644 (insn & 0x0fff0fff) != 0x0e010f10)
2650 #define VFP_REG_SHR(x, n) (((n) > 0) ? (x) >> (n) : (x) << -(n))
2651 #define VFP_SREG(insn, bigbit, smallbit) \
2652 ((VFP_REG_SHR(insn, bigbit - 1) & 0x1e) | (((insn) >> (smallbit)) & 1))
2653 #define VFP_DREG(reg, insn, bigbit, smallbit) do { \
2654 if (arm_feature(env, ARM_FEATURE_VFP3)) { \
2655 reg = (((insn) >> (bigbit)) & 0x0f) \
2656 | (((insn) >> ((smallbit) - 4)) & 0x10); \
2658 if (insn & (1 << (smallbit))) \
2660 reg = ((insn) >> (bigbit)) & 0x0f; \
2663 #define VFP_SREG_D(insn) VFP_SREG(insn, 12, 22)
2664 #define VFP_DREG_D(reg, insn) VFP_DREG(reg, insn, 12, 22)
2665 #define VFP_SREG_N(insn) VFP_SREG(insn, 16, 7)
2666 #define VFP_DREG_N(reg, insn) VFP_DREG(reg, insn, 16, 7)
2667 #define VFP_SREG_M(insn) VFP_SREG(insn, 0, 5)
2668 #define VFP_DREG_M(reg, insn) VFP_DREG(reg, insn, 0, 5)
2670 /* Move between integer and VFP cores. */
2671 static TCGv gen_vfp_mrs(void)
2673 TCGv tmp = new_tmp();
2674 tcg_gen_mov_i32(tmp, cpu_F0s);
2678 static void gen_vfp_msr(TCGv tmp)
2680 tcg_gen_mov_i32(cpu_F0s, tmp);
2685 vfp_enabled(CPUState * env)
2687 return ((env->vfp.xregs[ARM_VFP_FPEXC] & (1 << 30)) != 0);
2690 static void gen_neon_dup_u8(TCGv var, int shift)
2692 TCGv tmp = new_tmp();
2694 tcg_gen_shri_i32(var, var, shift);
2695 tcg_gen_ext8u_i32(var, var);
2696 tcg_gen_shli_i32(tmp, var, 8);
2697 tcg_gen_or_i32(var, var, tmp);
2698 tcg_gen_shli_i32(tmp, var, 16);
2699 tcg_gen_or_i32(var, var, tmp);
2703 static void gen_neon_dup_low16(TCGv var)
2705 TCGv tmp = new_tmp();
2706 tcg_gen_ext16u_i32(var, var);
2707 tcg_gen_shli_i32(tmp, var, 16);
2708 tcg_gen_or_i32(var, var, tmp);
2712 static void gen_neon_dup_high16(TCGv var)
2714 TCGv tmp = new_tmp();
2715 tcg_gen_andi_i32(var, var, 0xffff0000);
2716 tcg_gen_shri_i32(tmp, var, 16);
2717 tcg_gen_or_i32(var, var, tmp);
2721 /* Disassemble a VFP instruction. Returns nonzero if an error occured
2722 (ie. an undefined instruction). */
2723 static int disas_vfp_insn(CPUState * env, DisasContext *s, uint32_t insn)
2725 uint32_t rd, rn, rm, op, i, n, offset, delta_d, delta_m, bank_mask;
2730 if (!arm_feature(env, ARM_FEATURE_VFP))
2733 if (!vfp_enabled(env)) {
2734 /* VFP disabled. Only allow fmxr/fmrx to/from some control regs. */
2735 if ((insn & 0x0fe00fff) != 0x0ee00a10)
2737 rn = (insn >> 16) & 0xf;
2738 if (rn != ARM_VFP_FPSID && rn != ARM_VFP_FPEXC
2739 && rn != ARM_VFP_MVFR1 && rn != ARM_VFP_MVFR0)
2742 dp = ((insn & 0xf00) == 0xb00);
2743 switch ((insn >> 24) & 0xf) {
2745 if (insn & (1 << 4)) {
2746 /* single register transfer */
2747 rd = (insn >> 12) & 0xf;
2752 VFP_DREG_N(rn, insn);
2755 if (insn & 0x00c00060
2756 && !arm_feature(env, ARM_FEATURE_NEON))
2759 pass = (insn >> 21) & 1;
2760 if (insn & (1 << 22)) {
2762 offset = ((insn >> 5) & 3) * 8;
2763 } else if (insn & (1 << 5)) {
2765 offset = (insn & (1 << 6)) ? 16 : 0;
2770 if (insn & ARM_CP_RW_BIT) {
2772 tmp = neon_load_reg(rn, pass);
2776 tcg_gen_shri_i32(tmp, tmp, offset);
2777 if (insn & (1 << 23))
2783 if (insn & (1 << 23)) {
2785 tcg_gen_shri_i32(tmp, tmp, 16);
2791 tcg_gen_sari_i32(tmp, tmp, 16);
2800 store_reg(s, rd, tmp);
2803 tmp = load_reg(s, rd);
2804 if (insn & (1 << 23)) {
2807 gen_neon_dup_u8(tmp, 0);
2808 } else if (size == 1) {
2809 gen_neon_dup_low16(tmp);
2812 tcg_gen_mov_i32(tmp2, tmp);
2813 neon_store_reg(rn, 0, tmp2);
2814 neon_store_reg(rn, 0, tmp);
2819 tmp2 = neon_load_reg(rn, pass);
2820 gen_bfi(tmp, tmp2, tmp, offset, 0xff);
2824 tmp2 = neon_load_reg(rn, pass);
2825 gen_bfi(tmp, tmp2, tmp, offset, 0xffff);
2831 neon_store_reg(rn, pass, tmp);
2835 if ((insn & 0x6f) != 0x00)
2837 rn = VFP_SREG_N(insn);
2838 if (insn & ARM_CP_RW_BIT) {
2840 if (insn & (1 << 21)) {
2841 /* system register */
2846 /* VFP2 allows access to FSID from userspace.
2847 VFP3 restricts all id registers to privileged
2850 && arm_feature(env, ARM_FEATURE_VFP3))
2852 tmp = load_cpu_field(vfp.xregs[rn]);
2857 tmp = load_cpu_field(vfp.xregs[rn]);
2859 case ARM_VFP_FPINST:
2860 case ARM_VFP_FPINST2:
2861 /* Not present in VFP3. */
2863 || arm_feature(env, ARM_FEATURE_VFP3))
2865 tmp = load_cpu_field(vfp.xregs[rn]);
2869 tmp = load_cpu_field(vfp.xregs[ARM_VFP_FPSCR]);
2870 tcg_gen_andi_i32(tmp, tmp, 0xf0000000);
2873 gen_helper_vfp_get_fpscr(tmp, cpu_env);
2879 || !arm_feature(env, ARM_FEATURE_VFP3))
2881 tmp = load_cpu_field(vfp.xregs[rn]);
2887 gen_mov_F0_vreg(0, rn);
2888 tmp = gen_vfp_mrs();
2891 /* Set the 4 flag bits in the CPSR. */
2895 store_reg(s, rd, tmp);
2899 tmp = load_reg(s, rd);
2900 if (insn & (1 << 21)) {
2902 /* system register */
2907 /* Writes are ignored. */
2910 gen_helper_vfp_set_fpscr(cpu_env, tmp);
2917 store_cpu_field(tmp, vfp.xregs[rn]);
2920 case ARM_VFP_FPINST:
2921 case ARM_VFP_FPINST2:
2922 store_cpu_field(tmp, vfp.xregs[rn]);
2929 gen_mov_vreg_F0(0, rn);
2934 /* data processing */
2935 /* The opcode is in bits 23, 21, 20 and 6. */
2936 op = ((insn >> 20) & 8) | ((insn >> 19) & 6) | ((insn >> 6) & 1);
2940 rn = ((insn >> 15) & 0x1e) | ((insn >> 7) & 1);
2942 /* rn is register number */
2943 VFP_DREG_N(rn, insn);
2946 if (op == 15 && (rn == 15 || rn > 17)) {
2947 /* Integer or single precision destination. */
2948 rd = VFP_SREG_D(insn);
2950 VFP_DREG_D(rd, insn);
2953 if (op == 15 && (rn == 16 || rn == 17)) {
2954 /* Integer source. */
2955 rm = ((insn << 1) & 0x1e) | ((insn >> 5) & 1);
2957 VFP_DREG_M(rm, insn);
2960 rn = VFP_SREG_N(insn);
2961 if (op == 15 && rn == 15) {
2962 /* Double precision destination. */
2963 VFP_DREG_D(rd, insn);
2965 rd = VFP_SREG_D(insn);
2967 rm = VFP_SREG_M(insn);
2970 veclen = env->vfp.vec_len;
2971 if (op == 15 && rn > 3)
2974 /* Shut up compiler warnings. */
2985 /* Figure out what type of vector operation this is. */
2986 if ((rd & bank_mask) == 0) {
2991 delta_d = (env->vfp.vec_stride >> 1) + 1;
2993 delta_d = env->vfp.vec_stride + 1;
2995 if ((rm & bank_mask) == 0) {
2996 /* mixed scalar/vector */
3005 /* Load the initial operands. */
3010 /* Integer source */
3011 gen_mov_F0_vreg(0, rm);
3016 gen_mov_F0_vreg(dp, rd);
3017 gen_mov_F1_vreg(dp, rm);
3021 /* Compare with zero */
3022 gen_mov_F0_vreg(dp, rd);
3029 /* Source and destination the same. */
3030 gen_mov_F0_vreg(dp, rd);
3033 /* One source operand. */
3034 gen_mov_F0_vreg(dp, rm);
3038 /* Two source operands. */
3039 gen_mov_F0_vreg(dp, rn);
3040 gen_mov_F1_vreg(dp, rm);
3044 /* Perform the calculation. */
3046 case 0: /* mac: fd + (fn * fm) */
3048 gen_mov_F1_vreg(dp, rd);
3051 case 1: /* nmac: fd - (fn * fm) */
3054 gen_mov_F1_vreg(dp, rd);
3057 case 2: /* msc: -fd + (fn * fm) */
3059 gen_mov_F1_vreg(dp, rd);
3062 case 3: /* nmsc: -fd - (fn * fm) */
3064 gen_mov_F1_vreg(dp, rd);
3068 case 4: /* mul: fn * fm */
3071 case 5: /* nmul: -(fn * fm) */
3075 case 6: /* add: fn + fm */
3078 case 7: /* sub: fn - fm */
3081 case 8: /* div: fn / fm */
3084 case 14: /* fconst */
3085 if (!arm_feature(env, ARM_FEATURE_VFP3))
3088 n = (insn << 12) & 0x80000000;
3089 i = ((insn >> 12) & 0x70) | (insn & 0xf);
3096 tcg_gen_movi_i64(cpu_F0d, ((uint64_t)n) << 32);
3103 tcg_gen_movi_i32(cpu_F0s, n);
3106 case 15: /* extension space */
3129 case 11: /* cmpez */
3133 case 15: /* single<->double conversion */
3135 gen_helper_vfp_fcvtsd(cpu_F0s, cpu_F0d, cpu_env);
3137 gen_helper_vfp_fcvtds(cpu_F0d, cpu_F0s, cpu_env);
3139 case 16: /* fuito */
3142 case 17: /* fsito */
3145 case 20: /* fshto */
3146 if (!arm_feature(env, ARM_FEATURE_VFP3))
3148 gen_vfp_shto(dp, rm);
3150 case 21: /* fslto */
3151 if (!arm_feature(env, ARM_FEATURE_VFP3))
3153 gen_vfp_slto(dp, rm);
3155 case 22: /* fuhto */
3156 if (!arm_feature(env, ARM_FEATURE_VFP3))
3158 gen_vfp_uhto(dp, rm);
3160 case 23: /* fulto */
3161 if (!arm_feature(env, ARM_FEATURE_VFP3))
3163 gen_vfp_ulto(dp, rm);
3165 case 24: /* ftoui */
3168 case 25: /* ftouiz */
3171 case 26: /* ftosi */
3174 case 27: /* ftosiz */
3177 case 28: /* ftosh */
3178 if (!arm_feature(env, ARM_FEATURE_VFP3))
3180 gen_vfp_tosh(dp, rm);
3182 case 29: /* ftosl */
3183 if (!arm_feature(env, ARM_FEATURE_VFP3))
3185 gen_vfp_tosl(dp, rm);
3187 case 30: /* ftouh */
3188 if (!arm_feature(env, ARM_FEATURE_VFP3))
3190 gen_vfp_touh(dp, rm);
3192 case 31: /* ftoul */
3193 if (!arm_feature(env, ARM_FEATURE_VFP3))
3195 gen_vfp_toul(dp, rm);
3197 default: /* undefined */
3198 printf ("rn:%d\n", rn);
3202 default: /* undefined */
3203 printf ("op:%d\n", op);
3207 /* Write back the result. */
3208 if (op == 15 && (rn >= 8 && rn <= 11))
3209 ; /* Comparison, do nothing. */
3210 else if (op == 15 && rn > 17)
3211 /* Integer result. */
3212 gen_mov_vreg_F0(0, rd);
3213 else if (op == 15 && rn == 15)
3215 gen_mov_vreg_F0(!dp, rd);
3217 gen_mov_vreg_F0(dp, rd);
3219 /* break out of the loop if we have finished */
3223 if (op == 15 && delta_m == 0) {
3224 /* single source one-many */
3226 rd = ((rd + delta_d) & (bank_mask - 1))
3228 gen_mov_vreg_F0(dp, rd);
3232 /* Setup the next operands. */
3234 rd = ((rd + delta_d) & (bank_mask - 1))
3238 /* One source operand. */
3239 rm = ((rm + delta_m) & (bank_mask - 1))
3241 gen_mov_F0_vreg(dp, rm);
3243 /* Two source operands. */
3244 rn = ((rn + delta_d) & (bank_mask - 1))
3246 gen_mov_F0_vreg(dp, rn);
3248 rm = ((rm + delta_m) & (bank_mask - 1))
3250 gen_mov_F1_vreg(dp, rm);
3258 if (dp && (insn & 0x03e00000) == 0x00400000) {
3259 /* two-register transfer */
3260 rn = (insn >> 16) & 0xf;
3261 rd = (insn >> 12) & 0xf;
3263 VFP_DREG_M(rm, insn);
3265 rm = VFP_SREG_M(insn);
3268 if (insn & ARM_CP_RW_BIT) {
3271 gen_mov_F0_vreg(0, rm * 2);
3272 tmp = gen_vfp_mrs();
3273 store_reg(s, rd, tmp);
3274 gen_mov_F0_vreg(0, rm * 2 + 1);
3275 tmp = gen_vfp_mrs();
3276 store_reg(s, rn, tmp);
3278 gen_mov_F0_vreg(0, rm);
3279 tmp = gen_vfp_mrs();
3280 store_reg(s, rn, tmp);
3281 gen_mov_F0_vreg(0, rm + 1);
3282 tmp = gen_vfp_mrs();
3283 store_reg(s, rd, tmp);
3288 tmp = load_reg(s, rd);
3290 gen_mov_vreg_F0(0, rm * 2);
3291 tmp = load_reg(s, rn);
3293 gen_mov_vreg_F0(0, rm * 2 + 1);
3295 tmp = load_reg(s, rn);
3297 gen_mov_vreg_F0(0, rm);
3298 tmp = load_reg(s, rd);
3300 gen_mov_vreg_F0(0, rm + 1);
3305 rn = (insn >> 16) & 0xf;
3307 VFP_DREG_D(rd, insn);
3309 rd = VFP_SREG_D(insn);
3310 if (s->thumb && rn == 15) {
3311 gen_op_movl_T1_im(s->pc & ~2);
3313 gen_movl_T1_reg(s, rn);
3315 if ((insn & 0x01200000) == 0x01000000) {
3316 /* Single load/store */
3317 offset = (insn & 0xff) << 2;
3318 if ((insn & (1 << 23)) == 0)
3320 gen_op_addl_T1_im(offset);
3321 if (insn & (1 << 20)) {
3323 gen_mov_vreg_F0(dp, rd);
3325 gen_mov_F0_vreg(dp, rd);
3329 /* load/store multiple */
3331 n = (insn >> 1) & 0x7f;
3335 if (insn & (1 << 24)) /* pre-decrement */
3336 gen_op_addl_T1_im(-((insn & 0xff) << 2));
3342 for (i = 0; i < n; i++) {
3343 if (insn & ARM_CP_RW_BIT) {
3346 gen_mov_vreg_F0(dp, rd + i);
3349 gen_mov_F0_vreg(dp, rd + i);
3352 gen_op_addl_T1_im(offset);
3354 if (insn & (1 << 21)) {
3356 if (insn & (1 << 24))
3357 offset = -offset * n;
3358 else if (dp && (insn & 1))
3364 gen_op_addl_T1_im(offset);
3365 gen_movl_reg_T1(s, rn);
3371 /* Should never happen. */
3377 static inline void gen_goto_tb(DisasContext *s, int n, uint32_t dest)
3379 TranslationBlock *tb;
3382 if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK)) {
3384 gen_set_pc_im(dest);
3385 tcg_gen_exit_tb((long)tb + n);
3387 gen_set_pc_im(dest);
3392 static inline void gen_jmp (DisasContext *s, uint32_t dest)
3394 if (__builtin_expect(s->singlestep_enabled, 0)) {
3395 /* An indirect jump so that we still trigger the debug exception. */
3400 gen_goto_tb(s, 0, dest);
3401 s->is_jmp = DISAS_TB_JUMP;
3405 static inline void gen_mulxy(TCGv t0, TCGv t1, int x, int y)
3408 tcg_gen_sari_i32(t0, t0, 16);
3412 tcg_gen_sari_i32(t1, t1, 16);
3415 tcg_gen_mul_i32(t0, t0, t1);
3418 /* Return the mask of PSR bits set by a MSR instruction. */
3419 static uint32_t msr_mask(CPUState *env, DisasContext *s, int flags, int spsr) {
3423 if (flags & (1 << 0))
3425 if (flags & (1 << 1))
3427 if (flags & (1 << 2))
3429 if (flags & (1 << 3))
3432 /* Mask out undefined bits. */
3433 mask &= ~CPSR_RESERVED;
3434 if (!arm_feature(env, ARM_FEATURE_V6))
3435 mask &= ~(CPSR_E | CPSR_GE);
3436 if (!arm_feature(env, ARM_FEATURE_THUMB2))
3438 /* Mask out execution state bits. */
3441 /* Mask out privileged bits. */
3447 /* Returns nonzero if access to the PSR is not permitted. */
3448 static int gen_set_psr_T0(DisasContext *s, uint32_t mask, int spsr)
3452 /* ??? This is also undefined in system mode. */
3456 tmp = load_cpu_field(spsr);
3457 tcg_gen_andi_i32(tmp, tmp, ~mask);
3458 tcg_gen_andi_i32(cpu_T[0], cpu_T[0], mask);
3459 tcg_gen_or_i32(tmp, tmp, cpu_T[0]);
3460 store_cpu_field(tmp, spsr);
3462 gen_set_cpsr(cpu_T[0], mask);
3468 /* Generate an old-style exception return. */
3469 static void gen_exception_return(DisasContext *s)
3472 gen_movl_reg_T0(s, 15);
3473 tmp = load_cpu_field(spsr);
3474 gen_set_cpsr(tmp, 0xffffffff);
3476 s->is_jmp = DISAS_UPDATE;
3479 /* Generate a v6 exception return. Marks both values as dead. */
3480 static void gen_rfe(DisasContext *s, TCGv pc, TCGv cpsr)
3482 gen_set_cpsr(cpsr, 0xffffffff);
3484 store_reg(s, 15, pc);
3485 s->is_jmp = DISAS_UPDATE;
3489 gen_set_condexec (DisasContext *s)
3491 if (s->condexec_mask) {
3492 uint32_t val = (s->condexec_cond << 4) | (s->condexec_mask >> 1);
3493 TCGv tmp = new_tmp();
3494 tcg_gen_movi_i32(tmp, val);
3495 store_cpu_field(tmp, condexec_bits);
3499 static void gen_nop_hint(DisasContext *s, int val)
3503 gen_set_pc_im(s->pc);
3504 s->is_jmp = DISAS_WFI;
3508 /* TODO: Implement SEV and WFE. May help SMP performance. */
3514 /* These macros help make the code more readable when migrating from the
3515 old dyngen helpers. They should probably be removed when
3516 T0/T1 are removed. */
3517 #define CPU_T001 cpu_T[0], cpu_T[0], cpu_T[1]
3518 #define CPU_T0E01 cpu_T[0], cpu_env, cpu_T[0], cpu_T[1]
3520 #define CPU_V001 cpu_V0, cpu_V0, cpu_V1
3522 static inline int gen_neon_add(int size)
3525 case 0: gen_helper_neon_add_u8(CPU_T001); break;
3526 case 1: gen_helper_neon_add_u16(CPU_T001); break;
3527 case 2: gen_op_addl_T0_T1(); break;
3533 static inline void gen_neon_rsb(int size)
3536 case 0: gen_helper_neon_sub_u8(cpu_T[0], cpu_T[1], cpu_T[0]); break;
3537 case 1: gen_helper_neon_sub_u16(cpu_T[0], cpu_T[1], cpu_T[0]); break;
3538 case 2: gen_op_rsbl_T0_T1(); break;
3543 /* 32-bit pairwise ops end up the same as the elementwise versions. */
3544 #define gen_helper_neon_pmax_s32 gen_helper_neon_max_s32
3545 #define gen_helper_neon_pmax_u32 gen_helper_neon_max_u32
3546 #define gen_helper_neon_pmin_s32 gen_helper_neon_min_s32
3547 #define gen_helper_neon_pmin_u32 gen_helper_neon_min_u32
3549 /* FIXME: This is wrong. They set the wrong overflow bit. */
3550 #define gen_helper_neon_qadd_s32(a, e, b, c) gen_helper_add_saturate(a, b, c)
3551 #define gen_helper_neon_qadd_u32(a, e, b, c) gen_helper_add_usaturate(a, b, c)
3552 #define gen_helper_neon_qsub_s32(a, e, b, c) gen_helper_sub_saturate(a, b, c)
3553 #define gen_helper_neon_qsub_u32(a, e, b, c) gen_helper_sub_usaturate(a, b, c)
3555 #define GEN_NEON_INTEGER_OP_ENV(name) do { \
3556 switch ((size << 1) | u) { \
3558 gen_helper_neon_##name##_s8(cpu_T[0], cpu_env, cpu_T[0], cpu_T[1]); \
3561 gen_helper_neon_##name##_u8(cpu_T[0], cpu_env, cpu_T[0], cpu_T[1]); \
3564 gen_helper_neon_##name##_s16(cpu_T[0], cpu_env, cpu_T[0], cpu_T[1]); \
3567 gen_helper_neon_##name##_u16(cpu_T[0], cpu_env, cpu_T[0], cpu_T[1]); \
3570 gen_helper_neon_##name##_s32(cpu_T[0], cpu_env, cpu_T[0], cpu_T[1]); \
3573 gen_helper_neon_##name##_u32(cpu_T[0], cpu_env, cpu_T[0], cpu_T[1]); \
3575 default: return 1; \
3578 #define GEN_NEON_INTEGER_OP(name) do { \
3579 switch ((size << 1) | u) { \
3581 gen_helper_neon_##name##_s8(cpu_T[0], cpu_T[0], cpu_T[1]); \
3584 gen_helper_neon_##name##_u8(cpu_T[0], cpu_T[0], cpu_T[1]); \
3587 gen_helper_neon_##name##_s16(cpu_T[0], cpu_T[0], cpu_T[1]); \
3590 gen_helper_neon_##name##_u16(cpu_T[0], cpu_T[0], cpu_T[1]); \
3593 gen_helper_neon_##name##_s32(cpu_T[0], cpu_T[0], cpu_T[1]); \
3596 gen_helper_neon_##name##_u32(cpu_T[0], cpu_T[0], cpu_T[1]); \
3598 default: return 1; \
3602 gen_neon_movl_scratch_T0(int scratch)
3606 offset = offsetof(CPUARMState, vfp.scratch[scratch]);
3607 tcg_gen_st_i32(cpu_T[0], cpu_env, offset);
3611 gen_neon_movl_scratch_T1(int scratch)
3615 offset = offsetof(CPUARMState, vfp.scratch[scratch]);
3616 tcg_gen_st_i32(cpu_T[1], cpu_env, offset);
3620 gen_neon_movl_T0_scratch(int scratch)
3624 offset = offsetof(CPUARMState, vfp.scratch[scratch]);
3625 tcg_gen_ld_i32(cpu_T[0], cpu_env, offset);
3629 gen_neon_movl_T1_scratch(int scratch)
3633 offset = offsetof(CPUARMState, vfp.scratch[scratch]);
3634 tcg_gen_ld_i32(cpu_T[1], cpu_env, offset);
3637 static inline void gen_neon_get_scalar(int size, int reg)
3640 NEON_GET_REG(T0, reg >> 1, reg & 1);
3642 NEON_GET_REG(T0, reg >> 2, (reg >> 1) & 1);
3644 gen_neon_dup_low16(cpu_T[0]);
3646 gen_neon_dup_high16(cpu_T[0]);
3650 static void gen_neon_unzip(int reg, int q, int tmp, int size)
3654 for (n = 0; n < q + 1; n += 2) {
3655 NEON_GET_REG(T0, reg, n);
3656 NEON_GET_REG(T0, reg, n + n);
3658 case 0: gen_helper_neon_unzip_u8(); break;
3659 case 1: gen_helper_neon_zip_u16(); break; /* zip and unzip are the same. */
3660 case 2: /* no-op */; break;
3663 gen_neon_movl_scratch_T0(tmp + n);
3664 gen_neon_movl_scratch_T1(tmp + n + 1);
3672 } neon_ls_element_type[11] = {
3686 /* Translate a NEON load/store element instruction. Return nonzero if the
3687 instruction is invalid. */
3688 static int disas_neon_ls_insn(CPUState * env, DisasContext *s, uint32_t insn)
3704 if (!vfp_enabled(env))
3706 VFP_DREG_D(rd, insn);
3707 rn = (insn >> 16) & 0xf;
3709 load = (insn & (1 << 21)) != 0;
3710 if ((insn & (1 << 23)) == 0) {
3711 /* Load store all elements. */
3712 op = (insn >> 8) & 0xf;
3713 size = (insn >> 6) & 3;
3714 if (op > 10 || size == 3)
3716 nregs = neon_ls_element_type[op].nregs;
3717 interleave = neon_ls_element_type[op].interleave;
3718 gen_movl_T1_reg(s, rn);
3719 stride = (1 << size) * interleave;
3720 for (reg = 0; reg < nregs; reg++) {
3721 if (interleave > 2 || (interleave == 2 && nregs == 2)) {
3722 gen_movl_T1_reg(s, rn);
3723 gen_op_addl_T1_im((1 << size) * reg);
3724 } else if (interleave == 2 && nregs == 4 && reg == 2) {
3725 gen_movl_T1_reg(s, rn);
3726 gen_op_addl_T1_im(1 << size);
3728 for (pass = 0; pass < 2; pass++) {
3731 tmp = gen_ld32(cpu_T[1], IS_USER(s));
3732 neon_store_reg(rd, pass, tmp);
3734 tmp = neon_load_reg(rd, pass);
3735 gen_st32(tmp, cpu_T[1], IS_USER(s));
3737 gen_op_addl_T1_im(stride);
3738 } else if (size == 1) {
3740 tmp = gen_ld16u(cpu_T[1], IS_USER(s));
3741 gen_op_addl_T1_im(stride);
3742 tmp2 = gen_ld16u(cpu_T[1], IS_USER(s));
3743 gen_op_addl_T1_im(stride);
3744 gen_bfi(tmp, tmp, tmp2, 16, 0xffff);
3746 neon_store_reg(rd, pass, tmp);
3748 tmp = neon_load_reg(rd, pass);
3750 tcg_gen_shri_i32(tmp2, tmp, 16);
3751 gen_st16(tmp, cpu_T[1], IS_USER(s));
3752 gen_op_addl_T1_im(stride);
3753 gen_st16(tmp2, cpu_T[1], IS_USER(s));
3754 gen_op_addl_T1_im(stride);
3756 } else /* size == 0 */ {
3758 for (n = 0; n < 4; n++) {
3759 tmp = gen_ld8u(cpu_T[1], IS_USER(s));
3760 gen_op_addl_T1_im(stride);
3764 gen_bfi(tmp2, tmp2, tmp, n * 8, 0xff);
3768 neon_store_reg(rd, pass, tmp2);
3770 tmp2 = neon_load_reg(rd, pass);
3771 for (n = 0; n < 4; n++) {
3774 tcg_gen_mov_i32(tmp, tmp2);
3776 tcg_gen_shri_i32(tmp, tmp2, n * 8);
3778 gen_st8(tmp, cpu_T[1], IS_USER(s));
3779 gen_op_addl_T1_im(stride);
3785 rd += neon_ls_element_type[op].spacing;
3789 size = (insn >> 10) & 3;
3791 /* Load single element to all lanes. */
3794 size = (insn >> 6) & 3;
3795 nregs = ((insn >> 8) & 3) + 1;
3796 stride = (insn & (1 << 5)) ? 2 : 1;
3797 gen_movl_T1_reg(s, rn);
3798 for (reg = 0; reg < nregs; reg++) {
3801 tmp = gen_ld8u(cpu_T[1], IS_USER(s));
3802 gen_neon_dup_u8(tmp, 0);
3805 tmp = gen_ld16u(cpu_T[1], IS_USER(s));
3806 gen_neon_dup_low16(tmp);
3809 tmp = gen_ld32(cpu_T[0], IS_USER(s));
3814 gen_op_addl_T1_im(1 << size);
3816 tcg_gen_mov_i32(tmp2, tmp);
3817 neon_store_reg(rd, 0, tmp2);
3818 neon_store_reg(rd, 0, tmp);
3821 stride = (1 << size) * nregs;
3823 /* Single element. */
3824 pass = (insn >> 7) & 1;
3827 shift = ((insn >> 5) & 3) * 8;
3831 shift = ((insn >> 6) & 1) * 16;
3832 stride = (insn & (1 << 5)) ? 2 : 1;
3836 stride = (insn & (1 << 6)) ? 2 : 1;
3841 nregs = ((insn >> 8) & 3) + 1;
3842 gen_movl_T1_reg(s, rn);
3843 for (reg = 0; reg < nregs; reg++) {
3847 tmp = gen_ld8u(cpu_T[1], IS_USER(s));
3850 tmp = gen_ld16u(cpu_T[1], IS_USER(s));
3853 tmp = gen_ld32(cpu_T[1], IS_USER(s));
3857 tmp2 = neon_load_reg(rd, pass);
3858 gen_bfi(tmp, tmp2, tmp, shift, size ? 0xffff : 0xff);
3861 neon_store_reg(rd, pass, tmp);
3862 } else { /* Store */
3863 tmp = neon_load_reg(rd, pass);
3865 tcg_gen_shri_i32(tmp, tmp, shift);
3868 gen_st8(tmp, cpu_T[1], IS_USER(s));
3871 gen_st16(tmp, cpu_T[1], IS_USER(s));
3874 gen_st32(tmp, cpu_T[1], IS_USER(s));
3879 gen_op_addl_T1_im(1 << size);
3881 stride = nregs * (1 << size);
3887 base = load_reg(s, rn);
3889 tcg_gen_addi_i32(base, base, stride);
3892 index = load_reg(s, rm);
3893 tcg_gen_add_i32(base, base, index);
3896 store_reg(s, rn, base);
3901 /* Bitwise select. dest = c ? t : f. Clobbers T and F. */
3902 static void gen_neon_bsl(TCGv dest, TCGv t, TCGv f, TCGv c)
3904 tcg_gen_and_i32(t, t, c);
3905 tcg_gen_bic_i32(f, f, c);
3906 tcg_gen_or_i32(dest, t, f);
3909 static inline void gen_neon_narrow(int size, TCGv dest, TCGv src)
3912 case 0: gen_helper_neon_narrow_u8(dest, src); break;
3913 case 1: gen_helper_neon_narrow_u16(dest, src); break;
3914 case 2: tcg_gen_trunc_i64_i32(dest, src); break;
3919 static inline void gen_neon_narrow_sats(int size, TCGv dest, TCGv src)
3922 case 0: gen_helper_neon_narrow_sat_s8(dest, cpu_env, src); break;
3923 case 1: gen_helper_neon_narrow_sat_s16(dest, cpu_env, src); break;
3924 case 2: gen_helper_neon_narrow_sat_s32(dest, cpu_env, src); break;
3929 static inline void gen_neon_narrow_satu(int size, TCGv dest, TCGv src)
3932 case 0: gen_helper_neon_narrow_sat_u8(dest, cpu_env, src); break;
3933 case 1: gen_helper_neon_narrow_sat_u16(dest, cpu_env, src); break;
3934 case 2: gen_helper_neon_narrow_sat_u32(dest, cpu_env, src); break;
3939 static inline void gen_neon_shift_narrow(int size, TCGv var, TCGv shift,
3945 case 1: gen_helper_neon_rshl_u16(var, var, shift); break;
3946 case 2: gen_helper_neon_rshl_u32(var, var, shift); break;
3951 case 1: gen_helper_neon_rshl_s16(var, var, shift); break;
3952 case 2: gen_helper_neon_rshl_s32(var, var, shift); break;
3959 case 1: gen_helper_neon_rshl_u16(var, var, shift); break;
3960 case 2: gen_helper_neon_rshl_u32(var, var, shift); break;
3965 case 1: gen_helper_neon_shl_s16(var, var, shift); break;
3966 case 2: gen_helper_neon_shl_s32(var, var, shift); break;
3973 static inline void gen_neon_widen(TCGv dest, TCGv src, int size, int u)
3977 case 0: gen_helper_neon_widen_u8(dest, src); break;
3978 case 1: gen_helper_neon_widen_u16(dest, src); break;
3979 case 2: tcg_gen_extu_i32_i64(dest, src); break;
3984 case 0: gen_helper_neon_widen_s8(dest, src); break;
3985 case 1: gen_helper_neon_widen_s16(dest, src); break;
3986 case 2: tcg_gen_ext_i32_i64(dest, src); break;
3993 static inline void gen_neon_addl(int size)
3996 case 0: gen_helper_neon_addl_u16(CPU_V001); break;
3997 case 1: gen_helper_neon_addl_u32(CPU_V001); break;
3998 case 2: tcg_gen_add_i64(CPU_V001); break;
4003 static inline void gen_neon_subl(int size)
4006 case 0: gen_helper_neon_subl_u16(CPU_V001); break;
4007 case 1: gen_helper_neon_subl_u32(CPU_V001); break;
4008 case 2: tcg_gen_sub_i64(CPU_V001); break;
4013 static inline void gen_neon_negl(TCGv var, int size)
4016 case 0: gen_helper_neon_negl_u16(var, var); break;
4017 case 1: gen_helper_neon_negl_u32(var, var); break;
4018 case 2: gen_helper_neon_negl_u64(var, var); break;
4023 static inline void gen_neon_addl_saturate(TCGv op0, TCGv op1, int size)
4026 case 1: gen_helper_neon_addl_saturate_s32(op0, cpu_env, op0, op1); break;
4027 case 2: gen_helper_neon_addl_saturate_s64(op0, cpu_env, op0, op1); break;
4032 static inline void gen_neon_mull(TCGv dest, TCGv a, TCGv b, int size, int u)
4036 switch ((size << 1) | u) {
4037 case 0: gen_helper_neon_mull_s8(dest, a, b); break;
4038 case 1: gen_helper_neon_mull_u8(dest, a, b); break;
4039 case 2: gen_helper_neon_mull_s16(dest, a, b); break;
4040 case 3: gen_helper_neon_mull_u16(dest, a, b); break;
4042 tmp = gen_muls_i64_i32(a, b);
4043 tcg_gen_mov_i64(dest, tmp);
4046 tmp = gen_mulu_i64_i32(a, b);
4047 tcg_gen_mov_i64(dest, tmp);
4057 /* Translate a NEON data processing instruction. Return nonzero if the
4058 instruction is invalid.
4059 We process data in a mixture of 32-bit and 64-bit chunks.
4060 Mostly we use 32-bit chunks so we can use normal scalar instructions. */
4062 static int disas_neon_data_insn(CPUState * env, DisasContext *s, uint32_t insn)
4079 if (!vfp_enabled(env))
4081 q = (insn & (1 << 6)) != 0;
4082 u = (insn >> 24) & 1;
4083 VFP_DREG_D(rd, insn);
4084 VFP_DREG_N(rn, insn);
4085 VFP_DREG_M(rm, insn);
4086 size = (insn >> 20) & 3;
4087 if ((insn & (1 << 23)) == 0) {
4088 /* Three register same length. */
4089 op = ((insn >> 7) & 0x1e) | ((insn >> 4) & 1);
4090 if (size == 3 && (op == 1 || op == 5 || op == 8 || op == 9
4091 || op == 10 || op == 11 || op == 16)) {
4092 /* 64-bit element instructions. */
4093 for (pass = 0; pass < (q ? 2 : 1); pass++) {
4094 neon_load_reg64(cpu_V0, rn + pass);
4095 neon_load_reg64(cpu_V1, rm + pass);
4099 gen_helper_neon_add_saturate_u64(CPU_V001);
4101 gen_helper_neon_add_saturate_s64(CPU_V001);
4106 gen_helper_neon_sub_saturate_u64(CPU_V001);
4108 gen_helper_neon_sub_saturate_s64(CPU_V001);
4113 gen_helper_neon_shl_u64(cpu_V0, cpu_V1, cpu_V0);
4115 gen_helper_neon_shl_s64(cpu_V0, cpu_V1, cpu_V0);
4120 gen_helper_neon_qshl_u64(cpu_V0, cpu_env,
4123 gen_helper_neon_qshl_s64(cpu_V1, cpu_env,
4127 case 10: /* VRSHL */
4129 gen_helper_neon_rshl_u64(cpu_V0, cpu_V1, cpu_V0);
4131 gen_helper_neon_rshl_s64(cpu_V0, cpu_V1, cpu_V0);
4134 case 11: /* VQRSHL */
4136 gen_helper_neon_qrshl_u64(cpu_V0, cpu_env,
4139 gen_helper_neon_qrshl_s64(cpu_V0, cpu_env,
4145 tcg_gen_sub_i64(CPU_V001);
4147 tcg_gen_add_i64(CPU_V001);
4153 neon_store_reg64(cpu_V0, rd + pass);
4160 case 10: /* VRSHL */
4161 case 11: /* VQRSHL */
4164 /* Shift instruction operands are reversed. */
4171 case 20: /* VPMAX */
4172 case 21: /* VPMIN */
4173 case 23: /* VPADD */
4176 case 26: /* VPADD (float) */
4177 pairwise = (u && size < 2);
4179 case 30: /* VPMIN/VPMAX (float) */
4186 for (pass = 0; pass < (q ? 4 : 2); pass++) {
4195 NEON_GET_REG(T0, rn, n);
4196 NEON_GET_REG(T1, rn, n + 1);
4198 NEON_GET_REG(T0, rm, n);
4199 NEON_GET_REG(T1, rm, n + 1);
4203 NEON_GET_REG(T0, rn, pass);
4204 NEON_GET_REG(T1, rm, pass);
4208 GEN_NEON_INTEGER_OP(hadd);
4211 GEN_NEON_INTEGER_OP_ENV(qadd);
4213 case 2: /* VRHADD */
4214 GEN_NEON_INTEGER_OP(rhadd);
4216 case 3: /* Logic ops. */
4217 switch ((u << 2) | size) {
4219 gen_op_andl_T0_T1();
4222 gen_op_bicl_T0_T1();
4232 gen_op_xorl_T0_T1();
4235 tmp = neon_load_reg(rd, pass);
4236 gen_neon_bsl(cpu_T[0], cpu_T[0], cpu_T[1], tmp);
4240 tmp = neon_load_reg(rd, pass);
4241 gen_neon_bsl(cpu_T[0], cpu_T[0], tmp, cpu_T[1]);
4245 tmp = neon_load_reg(rd, pass);
4246 gen_neon_bsl(cpu_T[0], tmp, cpu_T[0], cpu_T[1]);
4252 GEN_NEON_INTEGER_OP(hsub);
4255 GEN_NEON_INTEGER_OP_ENV(qsub);
4258 GEN_NEON_INTEGER_OP(cgt);
4261 GEN_NEON_INTEGER_OP(cge);
4264 GEN_NEON_INTEGER_OP(shl);
4267 GEN_NEON_INTEGER_OP_ENV(qshl);
4269 case 10: /* VRSHL */
4270 GEN_NEON_INTEGER_OP(rshl);
4272 case 11: /* VQRSHL */
4273 GEN_NEON_INTEGER_OP_ENV(qrshl);
4276 GEN_NEON_INTEGER_OP(max);
4279 GEN_NEON_INTEGER_OP(min);
4282 GEN_NEON_INTEGER_OP(abd);
4285 GEN_NEON_INTEGER_OP(abd);
4286 NEON_GET_REG(T1, rd, pass);
4290 if (!u) { /* VADD */
4291 if (gen_neon_add(size))
4295 case 0: gen_helper_neon_sub_u8(CPU_T001); break;
4296 case 1: gen_helper_neon_sub_u16(CPU_T001); break;
4297 case 2: gen_op_subl_T0_T1(); break;
4303 if (!u) { /* VTST */
4305 case 0: gen_helper_neon_tst_u8(CPU_T001); break;
4306 case 1: gen_helper_neon_tst_u16(CPU_T001); break;
4307 case 2: gen_helper_neon_tst_u32(CPU_T001); break;
4312 case 0: gen_helper_neon_ceq_u8(CPU_T001); break;
4313 case 1: gen_helper_neon_ceq_u16(CPU_T001); break;
4314 case 2: gen_helper_neon_ceq_u32(CPU_T001); break;
4319 case 18: /* Multiply. */
4321 case 0: gen_helper_neon_mul_u8(CPU_T001); break;
4322 case 1: gen_helper_neon_mul_u16(CPU_T001); break;
4323 case 2: gen_op_mul_T0_T1(); break;
4326 NEON_GET_REG(T1, rd, pass);
4334 if (u) { /* polynomial */
4335 gen_helper_neon_mul_p8(CPU_T001);
4336 } else { /* Integer */
4338 case 0: gen_helper_neon_mul_u8(CPU_T001); break;
4339 case 1: gen_helper_neon_mul_u16(CPU_T001); break;
4340 case 2: gen_op_mul_T0_T1(); break;
4345 case 20: /* VPMAX */
4346 GEN_NEON_INTEGER_OP(pmax);
4348 case 21: /* VPMIN */
4349 GEN_NEON_INTEGER_OP(pmin);
4351 case 22: /* Hultiply high. */
4352 if (!u) { /* VQDMULH */
4354 case 1: gen_helper_neon_qdmulh_s16(CPU_T0E01); break;
4355 case 2: gen_helper_neon_qdmulh_s32(CPU_T0E01); break;
4358 } else { /* VQRDHMUL */
4360 case 1: gen_helper_neon_qrdmulh_s16(CPU_T0E01); break;
4361 case 2: gen_helper_neon_qrdmulh_s32(CPU_T0E01); break;
4366 case 23: /* VPADD */
4370 case 0: gen_helper_neon_padd_u8(CPU_T001); break;
4371 case 1: gen_helper_neon_padd_u16(CPU_T001); break;
4372 case 2: gen_op_addl_T0_T1(); break;
4376 case 26: /* Floating point arithnetic. */
4377 switch ((u << 2) | size) {
4379 gen_helper_neon_add_f32(CPU_T001);
4382 gen_helper_neon_sub_f32(CPU_T001);
4385 gen_helper_neon_add_f32(CPU_T001);
4388 gen_helper_neon_abd_f32(CPU_T001);
4394 case 27: /* Float multiply. */
4395 gen_helper_neon_mul_f32(CPU_T001);
4397 NEON_GET_REG(T1, rd, pass);
4399 gen_helper_neon_add_f32(CPU_T001);
4401 gen_helper_neon_sub_f32(cpu_T[0], cpu_T[1], cpu_T[0]);
4405 case 28: /* Float compare. */
4407 gen_helper_neon_ceq_f32(CPU_T001);
4410 gen_helper_neon_cge_f32(CPU_T001);
4412 gen_helper_neon_cgt_f32(CPU_T001);
4415 case 29: /* Float compare absolute. */
4419 gen_helper_neon_acge_f32(CPU_T001);
4421 gen_helper_neon_acgt_f32(CPU_T001);
4423 case 30: /* Float min/max. */
4425 gen_helper_neon_max_f32(CPU_T001);
4427 gen_helper_neon_min_f32(CPU_T001);
4431 gen_helper_recps_f32(cpu_T[0], cpu_T[0], cpu_T[1], cpu_env);
4433 gen_helper_rsqrts_f32(cpu_T[0], cpu_T[0], cpu_T[1], cpu_env);
4438 /* Save the result. For elementwise operations we can put it
4439 straight into the destination register. For pairwise operations
4440 we have to be careful to avoid clobbering the source operands. */
4441 if (pairwise && rd == rm) {
4442 gen_neon_movl_scratch_T0(pass);
4444 NEON_SET_REG(T0, rd, pass);
4448 if (pairwise && rd == rm) {
4449 for (pass = 0; pass < (q ? 4 : 2); pass++) {
4450 gen_neon_movl_T0_scratch(pass);
4451 NEON_SET_REG(T0, rd, pass);
4454 /* End of 3 register same size operations. */
4455 } else if (insn & (1 << 4)) {
4456 if ((insn & 0x00380080) != 0) {
4457 /* Two registers and shift. */
4458 op = (insn >> 8) & 0xf;
4459 if (insn & (1 << 7)) {
4464 while ((insn & (1 << (size + 19))) == 0)
4467 shift = (insn >> 16) & ((1 << (3 + size)) - 1);
4468 /* To avoid excessive dumplication of ops we implement shift
4469 by immediate using the variable shift operations. */
4471 /* Shift by immediate:
4472 VSHR, VSRA, VRSHR, VRSRA, VSRI, VSHL, VQSHL, VQSHLU. */
4473 /* Right shifts are encoded as N - shift, where N is the
4474 element size in bits. */
4476 shift = shift - (1 << (size + 3));
4484 imm = (uint8_t) shift;
4489 imm = (uint16_t) shift;
4500 for (pass = 0; pass < count; pass++) {
4502 neon_load_reg64(cpu_V0, rm + pass);
4503 tcg_gen_movi_i64(cpu_V1, imm);
4508 gen_helper_neon_shl_u64(cpu_V0, cpu_V0, cpu_V1);
4510 gen_helper_neon_shl_s64(cpu_V0, cpu_V0, cpu_V1);
4515 gen_helper_neon_rshl_u64(cpu_V0, cpu_V0, cpu_V1);
4517 gen_helper_neon_rshl_s64(cpu_V0, cpu_V0, cpu_V1);
4522 gen_helper_neon_shl_u64(cpu_V0, cpu_V0, cpu_V1);
4524 case 5: /* VSHL, VSLI */
4525 gen_helper_neon_shl_u64(cpu_V0, cpu_V0, cpu_V1);
4529 gen_helper_neon_qshl_u64(cpu_V0, cpu_env, cpu_V0, cpu_V1);
4531 gen_helper_neon_qshl_s64(cpu_V0, cpu_env, cpu_V0, cpu_V1);
4533 case 7: /* VQSHLU */
4534 gen_helper_neon_qshl_u64(cpu_V0, cpu_env, cpu_V0, cpu_V1);
4537 if (op == 1 || op == 3) {
4539 neon_load_reg64(cpu_V0, rd + pass);
4540 tcg_gen_add_i64(cpu_V0, cpu_V0, cpu_V1);
4541 } else if (op == 4 || (op == 5 && u)) {
4543 cpu_abort(env, "VS[LR]I.64 not implemented");
4545 neon_store_reg64(cpu_V0, rd + pass);
4546 } else { /* size < 3 */
4547 /* Operands in T0 and T1. */
4548 gen_op_movl_T1_im(imm);
4549 NEON_GET_REG(T0, rm, pass);
4553 GEN_NEON_INTEGER_OP(shl);
4557 GEN_NEON_INTEGER_OP(rshl);
4562 GEN_NEON_INTEGER_OP(shl);
4564 case 5: /* VSHL, VSLI */
4566 case 0: gen_helper_neon_shl_u8(CPU_T001); break;
4567 case 1: gen_helper_neon_shl_u16(CPU_T001); break;
4568 case 2: gen_helper_neon_shl_u32(CPU_T001); break;
4573 GEN_NEON_INTEGER_OP_ENV(qshl);
4575 case 7: /* VQSHLU */
4577 case 0: gen_helper_neon_qshl_u8(CPU_T0E01); break;
4578 case 1: gen_helper_neon_qshl_u16(CPU_T0E01); break;
4579 case 2: gen_helper_neon_qshl_u32(CPU_T0E01); break;
4585 if (op == 1 || op == 3) {
4587 NEON_GET_REG(T1, rd, pass);
4589 } else if (op == 4 || (op == 5 && u)) {
4594 imm = 0xff >> -shift;
4596 imm = (uint8_t)(0xff << shift);
4602 imm = 0xffff >> -shift;
4604 imm = (uint16_t)(0xffff << shift);
4609 imm = 0xffffffffu >> -shift;
4611 imm = 0xffffffffu << shift;
4616 tmp = neon_load_reg(rd, pass);
4617 tcg_gen_andi_i32(cpu_T[0], cpu_T[0], imm);
4618 tcg_gen_andi_i32(tmp, tmp, ~imm);
4619 tcg_gen_or_i32(cpu_T[0], cpu_T[0], tmp);
4621 NEON_SET_REG(T0, rd, pass);
4624 } else if (op < 10) {
4625 /* Shift by immediate and narrow:
4626 VSHRN, VRSHRN, VQSHRN, VQRSHRN. */
4627 shift = shift - (1 << (size + 3));
4631 imm = (uint16_t)shift;
4633 tmp2 = tcg_const_i32(imm);
4636 imm = (uint32_t)shift;
4637 tmp2 = tcg_const_i32(imm);
4639 tmp2 = tcg_const_i64(shift);
4645 for (pass = 0; pass < 2; pass++) {
4647 neon_load_reg64(cpu_V0, rm + pass);
4650 gen_helper_neon_rshl_u64(cpu_V0, cpu_V0, tmp2);
4652 gen_helper_neon_rshl_s64(cpu_V0, cpu_V0, tmp2);
4655 gen_helper_neon_shl_u64(cpu_V0, cpu_V0, tmp2);
4657 gen_helper_neon_shl_s64(cpu_V0, cpu_V0, tmp2);
4660 tmp = neon_load_reg(rm + pass, 0);
4661 gen_neon_shift_narrow(size, tmp, tmp2, q, u);
4662 tcg_gen_extu_i32_i64(cpu_V0, tmp);
4664 tmp = neon_load_reg(rm + pass, 1);
4665 gen_neon_shift_narrow(size, tmp, tmp2, q, u);
4666 tcg_gen_extu_i32_i64(cpu_V1, tmp);
4668 tcg_gen_shli_i64(cpu_V1, cpu_V1, 32);
4669 tcg_gen_or_i64(cpu_V0, cpu_V0, cpu_V1);
4672 if (op == 8 && !u) {
4673 gen_neon_narrow(size - 1, tmp, cpu_V0);
4676 gen_neon_narrow_sats(size - 1, tmp, cpu_V0);
4678 gen_neon_narrow_satu(size - 1, tmp, cpu_V0);
4683 neon_store_reg(rd, 0, tmp2);
4684 neon_store_reg(rd, 1, tmp);
4687 } else if (op == 10) {
4691 tmp = neon_load_reg(rm, 0);
4692 tmp2 = neon_load_reg(rm, 1);
4693 for (pass = 0; pass < 2; pass++) {
4697 gen_neon_widen(cpu_V0, tmp, size, u);
4700 /* The shift is less than the width of the source
4701 type, so we can just shift the whole register. */
4702 tcg_gen_shli_i64(cpu_V0, cpu_V0, shift);
4703 if (size < 2 || !u) {
4706 imm = (0xffu >> (8 - shift));
4709 imm = 0xffff >> (16 - shift);
4711 imm64 = imm | (((uint64_t)imm) << 32);
4712 tcg_gen_andi_i64(cpu_V0, cpu_V0, imm64);
4715 neon_store_reg64(cpu_V0, rd + pass);
4717 } else if (op == 15 || op == 16) {
4718 /* VCVT fixed-point. */
4719 for (pass = 0; pass < (q ? 4 : 2); pass++) {
4720 tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, pass));
4723 gen_vfp_ulto(0, shift);
4725 gen_vfp_slto(0, shift);
4728 gen_vfp_toul(0, shift);
4730 gen_vfp_tosl(0, shift);
4732 tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, pass));
4737 } else { /* (insn & 0x00380080) == 0 */
4740 op = (insn >> 8) & 0xf;
4741 /* One register and immediate. */
4742 imm = (u << 7) | ((insn >> 12) & 0x70) | (insn & 0xf);
4743 invert = (insn & (1 << 5)) != 0;
4761 imm = (imm << 8) | (imm << 24);
4764 imm = (imm < 8) | 0xff;
4767 imm = (imm << 16) | 0xffff;
4770 imm |= (imm << 8) | (imm << 16) | (imm << 24);
4775 imm = ((imm & 0x80) << 24) | ((imm & 0x3f) << 19)
4776 | ((imm & 0x40) ? (0x1f << 25) : (1 << 30));
4782 if (op != 14 || !invert)
4783 gen_op_movl_T1_im(imm);
4785 for (pass = 0; pass < (q ? 4 : 2); pass++) {
4786 if (op & 1 && op < 12) {
4787 tmp = neon_load_reg(rd, pass);
4789 /* The immediate value has already been inverted, so
4791 tcg_gen_andi_i32(tmp, tmp, imm);
4793 tcg_gen_ori_i32(tmp, tmp, imm);
4798 if (op == 14 && invert) {
4801 for (n = 0; n < 4; n++) {
4802 if (imm & (1 << (n + (pass & 1) * 4)))
4803 val |= 0xff << (n * 8);
4805 tcg_gen_movi_i32(tmp, val);
4807 tcg_gen_movi_i32(tmp, imm);
4810 neon_store_reg(rd, pass, tmp);
4813 } else { /* (insn & 0x00800010 == 0x00800010) */
4815 op = (insn >> 8) & 0xf;
4816 if ((insn & (1 << 6)) == 0) {
4817 /* Three registers of different lengths. */
4821 /* prewiden, src1_wide, src2_wide */
4822 static const int neon_3reg_wide[16][3] = {
4823 {1, 0, 0}, /* VADDL */
4824 {1, 1, 0}, /* VADDW */
4825 {1, 0, 0}, /* VSUBL */
4826 {1, 1, 0}, /* VSUBW */
4827 {0, 1, 1}, /* VADDHN */
4828 {0, 0, 0}, /* VABAL */
4829 {0, 1, 1}, /* VSUBHN */
4830 {0, 0, 0}, /* VABDL */
4831 {0, 0, 0}, /* VMLAL */
4832 {0, 0, 0}, /* VQDMLAL */
4833 {0, 0, 0}, /* VMLSL */
4834 {0, 0, 0}, /* VQDMLSL */
4835 {0, 0, 0}, /* Integer VMULL */
4836 {0, 0, 0}, /* VQDMULL */
4837 {0, 0, 0} /* Polynomial VMULL */
4840 prewiden = neon_3reg_wide[op][0];
4841 src1_wide = neon_3reg_wide[op][1];
4842 src2_wide = neon_3reg_wide[op][2];
4844 if (size == 0 && (op == 9 || op == 11 || op == 13))
4847 /* Avoid overlapping operands. Wide source operands are
4848 always aligned so will never overlap with wide
4849 destinations in problematic ways. */
4850 if (rd == rm && !src2_wide) {
4851 NEON_GET_REG(T0, rm, 1);
4852 gen_neon_movl_scratch_T0(2);
4853 } else if (rd == rn && !src1_wide) {
4854 NEON_GET_REG(T0, rn, 1);
4855 gen_neon_movl_scratch_T0(2);
4857 for (pass = 0; pass < 2; pass++) {
4859 neon_load_reg64(cpu_V0, rn + pass);
4861 if (pass == 1 && rd == rn) {
4862 gen_neon_movl_T0_scratch(2);
4864 tcg_gen_mov_i32(tmp, cpu_T[0]);
4866 tmp = neon_load_reg(rn, pass);
4869 gen_neon_widen(cpu_V0, tmp, size, u);
4873 neon_load_reg64(cpu_V1, rm + pass);
4875 if (pass == 1 && rd == rm) {
4876 gen_neon_movl_T0_scratch(2);
4878 tcg_gen_mov_i32(tmp2, cpu_T[0]);
4880 tmp2 = neon_load_reg(rm, pass);
4883 gen_neon_widen(cpu_V1, tmp2, size, u);
4887 case 0: case 1: case 4: /* VADDL, VADDW, VADDHN, VRADDHN */
4888 gen_neon_addl(size);
4890 case 2: case 3: case 6: /* VSUBL, VSUBW, VSUBHL, VRSUBHL */
4891 gen_neon_subl(size);
4893 case 5: case 7: /* VABAL, VABDL */
4894 switch ((size << 1) | u) {
4896 gen_helper_neon_abdl_s16(cpu_V0, tmp, tmp2);
4899 gen_helper_neon_abdl_u16(cpu_V0, tmp, tmp2);
4902 gen_helper_neon_abdl_s32(cpu_V0, tmp, tmp2);
4905 gen_helper_neon_abdl_u32(cpu_V0, tmp, tmp2);
4908 gen_helper_neon_abdl_s64(cpu_V0, tmp, tmp2);
4911 gen_helper_neon_abdl_u64(cpu_V0, tmp, tmp2);
4918 case 8: case 9: case 10: case 11: case 12: case 13:
4919 /* VMLAL, VQDMLAL, VMLSL, VQDMLSL, VMULL, VQDMULL */
4920 gen_neon_mull(cpu_V0, tmp, tmp2, size, u);
4922 case 14: /* Polynomial VMULL */
4923 cpu_abort(env, "Polynomial VMULL not implemented");
4925 default: /* 15 is RESERVED. */
4928 if (op == 5 || op == 13 || (op >= 8 && op <= 11)) {
4930 if (op == 10 || op == 11) {
4931 gen_neon_negl(cpu_V0, size);
4935 neon_load_reg64(cpu_V1, rd + pass);
4939 case 5: case 8: case 10: /* VABAL, VMLAL, VMLSL */
4940 gen_neon_addl(size);
4942 case 9: case 11: /* VQDMLAL, VQDMLSL */
4943 gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
4944 gen_neon_addl_saturate(cpu_V0, cpu_V1, size);
4947 case 13: /* VQDMULL */
4948 gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
4953 neon_store_reg64(cpu_V0, rd + pass);
4954 } else if (op == 4 || op == 6) {
4955 /* Narrowing operation. */
4960 gen_helper_neon_narrow_high_u8(tmp, cpu_V0);
4963 gen_helper_neon_narrow_high_u16(tmp, cpu_V0);
4966 tcg_gen_shri_i64(cpu_V0, cpu_V0, 32);
4967 tcg_gen_trunc_i64_i32(tmp, cpu_V0);
4974 gen_helper_neon_narrow_round_high_u8(tmp, cpu_V0);
4977 gen_helper_neon_narrow_round_high_u16(tmp, cpu_V0);
4980 tcg_gen_addi_i64(cpu_V0, cpu_V0, 1u << 31);
4981 tcg_gen_shri_i64(cpu_V0, cpu_V0, 32);
4982 tcg_gen_trunc_i64_i32(tmp, cpu_V0);
4990 neon_store_reg(rd, 0, tmp3);
4991 neon_store_reg(rd, 1, tmp);
4994 /* Write back the result. */
4995 neon_store_reg64(cpu_V0, rd + pass);
4999 /* Two registers and a scalar. */
5001 case 0: /* Integer VMLA scalar */
5002 case 1: /* Float VMLA scalar */
5003 case 4: /* Integer VMLS scalar */
5004 case 5: /* Floating point VMLS scalar */
5005 case 8: /* Integer VMUL scalar */
5006 case 9: /* Floating point VMUL scalar */
5007 case 12: /* VQDMULH scalar */
5008 case 13: /* VQRDMULH scalar */
5009 gen_neon_get_scalar(size, rm);
5010 gen_neon_movl_scratch_T0(0);
5011 for (pass = 0; pass < (u ? 4 : 2); pass++) {
5013 gen_neon_movl_T0_scratch(0);
5014 NEON_GET_REG(T1, rn, pass);
5017 gen_helper_neon_qdmulh_s16(CPU_T0E01);
5019 gen_helper_neon_qdmulh_s32(CPU_T0E01);
5021 } else if (op == 13) {
5023 gen_helper_neon_qrdmulh_s16(CPU_T0E01);
5025 gen_helper_neon_qrdmulh_s32(CPU_T0E01);
5027 } else if (op & 1) {
5028 gen_helper_neon_mul_f32(CPU_T001);
5031 case 0: gen_helper_neon_mul_u8(CPU_T001); break;
5032 case 1: gen_helper_neon_mul_u16(CPU_T001); break;
5033 case 2: gen_op_mul_T0_T1(); break;
5039 NEON_GET_REG(T1, rd, pass);
5045 gen_helper_neon_add_f32(CPU_T001);
5051 gen_helper_neon_sub_f32(cpu_T[0], cpu_T[1], cpu_T[0]);
5057 NEON_SET_REG(T0, rd, pass);
5060 case 2: /* VMLAL sclar */
5061 case 3: /* VQDMLAL scalar */
5062 case 6: /* VMLSL scalar */
5063 case 7: /* VQDMLSL scalar */
5064 case 10: /* VMULL scalar */
5065 case 11: /* VQDMULL scalar */
5066 if (size == 0 && (op == 3 || op == 7 || op == 11))
5069 gen_neon_get_scalar(size, rm);
5070 NEON_GET_REG(T1, rn, 1);
5072 for (pass = 0; pass < 2; pass++) {
5074 tmp = neon_load_reg(rn, 0);
5077 tcg_gen_mov_i32(tmp, cpu_T[1]);
5080 tcg_gen_mov_i32(tmp2, cpu_T[0]);
5081 gen_neon_mull(cpu_V0, tmp, tmp2, size, u);
5082 if (op == 6 || op == 7) {
5083 gen_neon_negl(cpu_V0, size);
5086 neon_load_reg64(cpu_V1, rd + pass);
5090 gen_neon_addl(size);
5093 gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
5094 gen_neon_addl_saturate(cpu_V0, cpu_V1, size);
5100 gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
5105 neon_store_reg64(cpu_V0, rd + pass);
5108 default: /* 14 and 15 are RESERVED */
5112 } else { /* size == 3 */
5115 imm = (insn >> 8) & 0xf;
5122 neon_load_reg64(cpu_V0, rn);
5124 neon_load_reg64(cpu_V1, rn + 1);
5126 } else if (imm == 8) {
5127 neon_load_reg64(cpu_V0, rn + 1);
5129 neon_load_reg64(cpu_V1, rm);
5132 tmp = tcg_temp_new(TCG_TYPE_I64);
5134 neon_load_reg64(cpu_V0, rn);
5135 neon_load_reg64(tmp, rn + 1);
5137 neon_load_reg64(cpu_V0, rn + 1);
5138 neon_load_reg64(tmp, rm);
5140 tcg_gen_shri_i64(cpu_V0, cpu_V0, (imm & 7) * 8);
5141 tcg_gen_shli_i64(cpu_V1, tmp, 64 - ((imm & 7) * 8));
5142 tcg_gen_or_i64(cpu_V0, cpu_V0, cpu_V1);
5144 neon_load_reg64(cpu_V1, rm);
5146 neon_load_reg64(cpu_V1, rm + 1);
5149 tcg_gen_shli_i64(cpu_V1, cpu_V1, 64 - (imm * 8));
5150 tcg_gen_shri_i64(tmp, tmp, imm * 8);
5151 tcg_gen_or_i64(cpu_V1, cpu_V1, tmp);
5153 neon_load_reg64(cpu_V0, rn);
5154 tcg_gen_shri_i32(cpu_V0, cpu_V0, imm * 8);
5155 neon_load_reg64(cpu_V1, rm);
5156 tcg_gen_shli_i32(cpu_V1, cpu_V1, 64 - (imm * 8));
5157 tcg_gen_or_i64(cpu_V0, cpu_V0, cpu_V1);
5159 neon_store_reg64(cpu_V0, rd);
5161 neon_store_reg64(cpu_V1, rd + 1);
5163 } else if ((insn & (1 << 11)) == 0) {
5164 /* Two register misc. */
5165 op = ((insn >> 12) & 0x30) | ((insn >> 7) & 0xf);
5166 size = (insn >> 18) & 3;
5168 case 0: /* VREV64 */
5171 for (pass = 0; pass < (q ? 2 : 1); pass++) {
5172 NEON_GET_REG(T0, rm, pass * 2);
5173 NEON_GET_REG(T1, rm, pass * 2 + 1);
5175 case 0: tcg_gen_bswap_i32(cpu_T[0], cpu_T[0]); break;
5176 case 1: gen_swap_half(cpu_T[0]); break;
5177 case 2: /* no-op */ break;
5180 NEON_SET_REG(T0, rd, pass * 2 + 1);
5182 NEON_SET_REG(T1, rd, pass * 2);
5184 gen_op_movl_T0_T1();
5186 case 0: tcg_gen_bswap_i32(cpu_T[0], cpu_T[0]); break;
5187 case 1: gen_swap_half(cpu_T[0]); break;
5190 NEON_SET_REG(T0, rd, pass * 2);
5194 case 4: case 5: /* VPADDL */
5195 case 12: case 13: /* VPADAL */
5198 for (pass = 0; pass < q + 1; pass++) {
5199 tmp = neon_load_reg(rm, pass * 2);
5200 gen_neon_widen(cpu_V0, tmp, size, op & 1);
5201 tmp = neon_load_reg(rm, pass * 2 + 1);
5202 gen_neon_widen(cpu_V1, tmp, size, op & 1);
5204 case 0: gen_helper_neon_paddl_u16(CPU_V001); break;
5205 case 1: gen_helper_neon_paddl_u32(CPU_V001); break;
5206 case 2: tcg_gen_add_i64(CPU_V001); break;
5211 neon_load_reg64(cpu_V1, rd + pass);
5212 gen_neon_addl(size);
5214 neon_store_reg64(cpu_V0, rd + pass);
5219 for (n = 0; n < (q ? 4 : 2); n += 2) {
5220 NEON_GET_REG(T0, rm, n);
5221 NEON_GET_REG(T1, rd, n + 1);
5222 NEON_SET_REG(T1, rm, n);
5223 NEON_SET_REG(T0, rd, n + 1);
5231 Rd A3 A2 A1 A0 B2 B0 A2 A0
5232 Rm B3 B2 B1 B0 B3 B1 A3 A1
5236 gen_neon_unzip(rd, q, 0, size);
5237 gen_neon_unzip(rm, q, 4, size);
5239 static int unzip_order_q[8] =
5240 {0, 2, 4, 6, 1, 3, 5, 7};
5241 for (n = 0; n < 8; n++) {
5242 int reg = (n < 4) ? rd : rm;
5243 gen_neon_movl_T0_scratch(unzip_order_q[n]);
5244 NEON_SET_REG(T0, reg, n % 4);
5247 static int unzip_order[4] =
5249 for (n = 0; n < 4; n++) {
5250 int reg = (n < 2) ? rd : rm;
5251 gen_neon_movl_T0_scratch(unzip_order[n]);
5252 NEON_SET_REG(T0, reg, n % 2);
5258 Rd A3 A2 A1 A0 B1 A1 B0 A0
5259 Rm B3 B2 B1 B0 B3 A3 B2 A2
5263 count = (q ? 4 : 2);
5264 for (n = 0; n < count; n++) {
5265 NEON_GET_REG(T0, rd, n);
5266 NEON_GET_REG(T1, rd, n);
5268 case 0: gen_helper_neon_zip_u8(); break;
5269 case 1: gen_helper_neon_zip_u16(); break;
5270 case 2: /* no-op */; break;
5273 gen_neon_movl_scratch_T0(n * 2);
5274 gen_neon_movl_scratch_T1(n * 2 + 1);
5276 for (n = 0; n < count * 2; n++) {
5277 int reg = (n < count) ? rd : rm;
5278 gen_neon_movl_T0_scratch(n);
5279 NEON_SET_REG(T0, reg, n % count);
5282 case 36: case 37: /* VMOVN, VQMOVUN, VQMOVN */
5285 for (pass = 0; pass < 2; pass++) {
5286 neon_load_reg64(cpu_V0, rm + pass);
5288 if (op == 36 && q == 0) {
5289 gen_neon_narrow(size, tmp, cpu_V0);
5291 gen_neon_narrow_satu(size, tmp, cpu_V0);
5293 gen_neon_narrow_sats(size, tmp, cpu_V0);
5298 neon_store_reg(rd, 0, tmp2);
5299 neon_store_reg(rd, 1, tmp);
5303 case 38: /* VSHLL */
5306 tmp = neon_load_reg(rm, 0);
5307 tmp2 = neon_load_reg(rm, 1);
5308 for (pass = 0; pass < 2; pass++) {
5311 gen_neon_widen(cpu_V0, tmp, size, 1);
5312 neon_store_reg64(cpu_V0, rd + pass);
5317 for (pass = 0; pass < (q ? 4 : 2); pass++) {
5318 if (op == 30 || op == 31 || op >= 58) {
5319 tcg_gen_ld_f32(cpu_F0s, cpu_env,
5320 neon_reg_offset(rm, pass));
5322 NEON_GET_REG(T0, rm, pass);
5325 case 1: /* VREV32 */
5327 case 0: tcg_gen_bswap_i32(cpu_T[0], cpu_T[0]); break;
5328 case 1: gen_swap_half(cpu_T[0]); break;
5332 case 2: /* VREV16 */
5335 gen_rev16(cpu_T[0]);
5339 case 0: gen_helper_neon_cls_s8(cpu_T[0], cpu_T[0]); break;
5340 case 1: gen_helper_neon_cls_s16(cpu_T[0], cpu_T[0]); break;
5341 case 2: gen_helper_neon_cls_s32(cpu_T[0], cpu_T[0]); break;
5347 case 0: gen_helper_neon_clz_u8(cpu_T[0], cpu_T[0]); break;
5348 case 1: gen_helper_neon_clz_u16(cpu_T[0], cpu_T[0]); break;
5349 case 2: gen_helper_clz(cpu_T[0], cpu_T[0]); break;
5356 gen_helper_neon_cnt_u8(cpu_T[0], cpu_T[0]);
5363 case 14: /* VQABS */
5365 case 0: gen_helper_neon_qabs_s8(cpu_T[0], cpu_env, cpu_T[0]); break;
5366 case 1: gen_helper_neon_qabs_s16(cpu_T[0], cpu_env, cpu_T[0]); break;
5367 case 2: gen_helper_neon_qabs_s32(cpu_T[0], cpu_env, cpu_T[0]); break;
5371 case 15: /* VQNEG */
5373 case 0: gen_helper_neon_qneg_s8(cpu_T[0], cpu_env, cpu_T[0]); break;
5374 case 1: gen_helper_neon_qneg_s16(cpu_T[0], cpu_env, cpu_T[0]); break;
5375 case 2: gen_helper_neon_qneg_s32(cpu_T[0], cpu_env, cpu_T[0]); break;
5379 case 16: case 19: /* VCGT #0, VCLE #0 */
5380 gen_op_movl_T1_im(0);
5382 case 0: gen_helper_neon_cgt_s8(CPU_T001); break;
5383 case 1: gen_helper_neon_cgt_s16(CPU_T001); break;
5384 case 2: gen_helper_neon_cgt_s32(CPU_T001); break;
5390 case 17: case 20: /* VCGE #0, VCLT #0 */
5391 gen_op_movl_T1_im(0);
5393 case 0: gen_helper_neon_cge_s8(CPU_T001); break;
5394 case 1: gen_helper_neon_cge_s16(CPU_T001); break;
5395 case 2: gen_helper_neon_cge_s32(CPU_T001); break;
5401 case 18: /* VCEQ #0 */
5402 gen_op_movl_T1_im(0);
5404 case 0: gen_helper_neon_ceq_u8(CPU_T001); break;
5405 case 1: gen_helper_neon_ceq_u16(CPU_T001); break;
5406 case 2: gen_helper_neon_ceq_u32(CPU_T001); break;
5412 case 0: gen_helper_neon_abs_s8(cpu_T[0], cpu_T[0]); break;
5413 case 1: gen_helper_neon_abs_s16(cpu_T[0], cpu_T[0]); break;
5414 case 2: tcg_gen_abs_i32(cpu_T[0], cpu_T[0]); break;
5419 gen_op_movl_T1_im(0);
5424 case 24: case 27: /* Float VCGT #0, Float VCLE #0 */
5425 gen_op_movl_T1_im(0);
5426 gen_helper_neon_cgt_f32(CPU_T001);
5430 case 25: case 28: /* Float VCGE #0, Float VCLT #0 */
5431 gen_op_movl_T1_im(0);
5432 gen_helper_neon_cge_f32(CPU_T001);
5436 case 26: /* Float VCEQ #0 */
5437 gen_op_movl_T1_im(0);
5438 gen_helper_neon_ceq_f32(CPU_T001);
5440 case 30: /* Float VABS */
5443 case 31: /* Float VNEG */
5447 NEON_GET_REG(T1, rd, pass);
5448 NEON_SET_REG(T1, rm, pass);
5451 NEON_GET_REG(T1, rd, pass);
5453 case 0: gen_helper_neon_trn_u8(); break;
5454 case 1: gen_helper_neon_trn_u16(); break;
5458 NEON_SET_REG(T1, rm, pass);
5460 case 56: /* Integer VRECPE */
5461 gen_helper_recpe_u32(cpu_T[0], cpu_T[0], cpu_env);
5463 case 57: /* Integer VRSQRTE */
5464 gen_helper_rsqrte_u32(cpu_T[0], cpu_T[0], cpu_env);
5466 case 58: /* Float VRECPE */
5467 gen_helper_recpe_f32(cpu_F0s, cpu_F0s, cpu_env);
5469 case 59: /* Float VRSQRTE */
5470 gen_helper_rsqrte_f32(cpu_F0s, cpu_F0s, cpu_env);
5472 case 60: /* VCVT.F32.S32 */
5475 case 61: /* VCVT.F32.U32 */
5478 case 62: /* VCVT.S32.F32 */
5481 case 63: /* VCVT.U32.F32 */
5485 /* Reserved: 21, 29, 39-56 */
5488 if (op == 30 || op == 31 || op >= 58) {
5489 tcg_gen_st_f32(cpu_F0s, cpu_env,
5490 neon_reg_offset(rd, pass));
5492 NEON_SET_REG(T0, rd, pass);
5497 } else if ((insn & (1 << 10)) == 0) {
5499 n = (insn >> 5) & 0x18;
5500 if (insn & (1 << 6)) {
5501 tmp = neon_load_reg(rd, 0);
5504 tcg_gen_movi_i32(tmp, 0);
5506 tmp2 = neon_load_reg(rm, 0);
5507 gen_helper_neon_tbl(tmp2, tmp2, tmp, tcg_const_i32(rn),
5509 if (insn & (1 << 6)) {
5510 tmp = neon_load_reg(rd, 1);
5513 tcg_gen_movi_i32(tmp, 0);
5515 tmp3 = neon_load_reg(rm, 1);
5516 gen_helper_neon_tbl(tmp3, tmp3, tmp, tcg_const_i32(rn),
5518 neon_store_reg(rd, 0, tmp2);
5519 neon_store_reg(rd, 1, tmp2);
5520 } else if ((insn & 0x380) == 0) {
5522 if (insn & (1 << 19)) {
5523 NEON_SET_REG(T0, rm, 1);
5525 NEON_SET_REG(T0, rm, 0);
5527 if (insn & (1 << 16)) {
5528 gen_neon_dup_u8(cpu_T[0], ((insn >> 17) & 3) * 8);
5529 } else if (insn & (1 << 17)) {
5530 if ((insn >> 18) & 1)
5531 gen_neon_dup_high16(cpu_T[0]);
5533 gen_neon_dup_low16(cpu_T[0]);
5535 for (pass = 0; pass < (q ? 4 : 2); pass++) {
5536 NEON_SET_REG(T0, rd, pass);
5546 static int disas_coproc_insn(CPUState * env, DisasContext *s, uint32_t insn)
5550 cpnum = (insn >> 8) & 0xf;
5551 if (arm_feature(env, ARM_FEATURE_XSCALE)
5552 && ((env->cp15.c15_cpar ^ 0x3fff) & (1 << cpnum)))
5558 if (arm_feature(env, ARM_FEATURE_IWMMXT)) {
5559 return disas_iwmmxt_insn(env, s, insn);
5560 } else if (arm_feature(env, ARM_FEATURE_XSCALE)) {
5561 return disas_dsp_insn(env, s, insn);
5566 return disas_vfp_insn (env, s, insn);
5568 return disas_cp15_insn (env, s, insn);
5570 /* Unknown coprocessor. See if the board has hooked it. */
5571 return disas_cp_insn (env, s, insn);
5576 /* Store a 64-bit value to a register pair. Clobbers val. */
5577 static void gen_storeq_reg(DisasContext *s, int rlow, int rhigh, TCGv val)
5581 tcg_gen_trunc_i64_i32(tmp, val);
5582 store_reg(s, rlow, tmp);
5584 tcg_gen_shri_i64(val, val, 32);
5585 tcg_gen_trunc_i64_i32(tmp, val);
5586 store_reg(s, rhigh, tmp);
5589 /* load a 32-bit value from a register and perform a 64-bit accumulate. */
5590 static void gen_addq_lo(DisasContext *s, TCGv val, int rlow)
5595 /* Load 64-bit value rd:rn. */
5596 tmp = tcg_temp_new(TCG_TYPE_I64);
5597 tmp2 = load_reg(s, rlow);
5598 tcg_gen_extu_i32_i64(tmp, tmp2);
5600 tcg_gen_add_i64(val, val, tmp);
5603 /* load and add a 64-bit value from a register pair. */
5604 static void gen_addq(DisasContext *s, TCGv val, int rlow, int rhigh)
5609 /* Load 64-bit value rd:rn. */
5610 tmp = tcg_temp_new(TCG_TYPE_I64);
5611 tmp2 = load_reg(s, rhigh);
5612 tcg_gen_extu_i32_i64(tmp, tmp2);
5614 tcg_gen_shli_i64(tmp, tmp, 32);
5615 tcg_gen_add_i64(val, val, tmp);
5617 tmp2 = load_reg(s, rlow);
5618 tcg_gen_extu_i32_i64(tmp, tmp2);
5620 tcg_gen_add_i64(val, val, tmp);
5623 /* Set N and Z flags from a 64-bit value. */
5624 static void gen_logicq_cc(TCGv val)
5626 TCGv tmp = new_tmp();
5627 gen_helper_logicq_cc(tmp, val);
5632 static void disas_arm_insn(CPUState * env, DisasContext *s)
5634 unsigned int cond, insn, val, op1, i, shift, rm, rs, rn, rd, sh;
5640 insn = ldl_code(s->pc);
5643 /* M variants do not implement ARM mode. */
5648 /* Unconditional instructions. */
5649 if (((insn >> 25) & 7) == 1) {
5650 /* NEON Data processing. */
5651 if (!arm_feature(env, ARM_FEATURE_NEON))
5654 if (disas_neon_data_insn(env, s, insn))
5658 if ((insn & 0x0f100000) == 0x04000000) {
5659 /* NEON load/store. */
5660 if (!arm_feature(env, ARM_FEATURE_NEON))
5663 if (disas_neon_ls_insn(env, s, insn))
5667 if ((insn & 0x0d70f000) == 0x0550f000)
5669 else if ((insn & 0x0ffffdff) == 0x01010000) {
5672 if (insn & (1 << 9)) {
5673 /* BE8 mode not implemented. */
5677 } else if ((insn & 0x0fffff00) == 0x057ff000) {
5678 switch ((insn >> 4) & 0xf) {
5681 gen_helper_clrex(cpu_env);
5687 /* We don't emulate caches so these are a no-op. */
5692 } else if ((insn & 0x0e5fffe0) == 0x084d0500) {
5698 op1 = (insn & 0x1f);
5699 if (op1 == (env->uncached_cpsr & CPSR_M)) {
5700 addr = load_reg(s, 13);
5703 gen_helper_get_r13_banked(addr, cpu_env, tcg_const_i32(op1));
5705 i = (insn >> 23) & 3;
5707 case 0: offset = -4; break; /* DA */
5708 case 1: offset = -8; break; /* DB */
5709 case 2: offset = 0; break; /* IA */
5710 case 3: offset = 4; break; /* IB */
5714 tcg_gen_addi_i32(addr, addr, offset);
5715 tmp = load_reg(s, 14);
5716 gen_st32(tmp, addr, 0);
5718 gen_helper_cpsr_read(tmp);
5719 tcg_gen_addi_i32(addr, addr, 4);
5720 gen_st32(tmp, addr, 0);
5721 if (insn & (1 << 21)) {
5722 /* Base writeback. */
5724 case 0: offset = -8; break;
5725 case 1: offset = -4; break;
5726 case 2: offset = 4; break;
5727 case 3: offset = 0; break;
5731 tcg_gen_addi_i32(addr, tmp, offset);
5732 if (op1 == (env->uncached_cpsr & CPSR_M)) {
5733 gen_movl_reg_T1(s, 13);
5735 gen_helper_set_r13_banked(cpu_env, tcg_const_i32(op1), cpu_T[1]);
5740 } else if ((insn & 0x0e5fffe0) == 0x081d0a00) {
5746 rn = (insn >> 16) & 0xf;
5747 addr = load_reg(s, rn);
5748 i = (insn >> 23) & 3;
5750 case 0: offset = -4; break; /* DA */
5751 case 1: offset = -8; break; /* DB */
5752 case 2: offset = 0; break; /* IA */
5753 case 3: offset = 4; break; /* IB */
5757 tcg_gen_addi_i32(addr, addr, offset);
5758 /* Load PC into tmp and CPSR into tmp2. */
5759 tmp = gen_ld32(addr, 0);
5760 tcg_gen_addi_i32(addr, addr, 4);
5761 tmp2 = gen_ld32(addr, 0);
5762 if (insn & (1 << 21)) {
5763 /* Base writeback. */
5765 case 0: offset = -8; break;
5766 case 1: offset = -4; break;
5767 case 2: offset = 4; break;
5768 case 3: offset = 0; break;
5772 tcg_gen_addi_i32(addr, addr, offset);
5773 store_reg(s, rn, addr);
5777 gen_rfe(s, tmp, tmp2);
5778 } else if ((insn & 0x0e000000) == 0x0a000000) {
5779 /* branch link and change to thumb (blx <offset>) */
5782 val = (uint32_t)s->pc;
5784 tcg_gen_movi_i32(tmp, val);
5785 store_reg(s, 14, tmp);
5786 /* Sign-extend the 24-bit offset */
5787 offset = (((int32_t)insn) << 8) >> 8;
5788 /* offset * 4 + bit24 * 2 + (thumb bit) */
5789 val += (offset << 2) | ((insn >> 23) & 2) | 1;
5790 /* pipeline offset */
5794 } else if ((insn & 0x0e000f00) == 0x0c000100) {
5795 if (arm_feature(env, ARM_FEATURE_IWMMXT)) {
5796 /* iWMMXt register transfer. */
5797 if (env->cp15.c15_cpar & (1 << 1))
5798 if (!disas_iwmmxt_insn(env, s, insn))
5801 } else if ((insn & 0x0fe00000) == 0x0c400000) {
5802 /* Coprocessor double register transfer. */
5803 } else if ((insn & 0x0f000010) == 0x0e000010) {
5804 /* Additional coprocessor register transfer. */
5805 } else if ((insn & 0x0ff10010) == 0x01000000) {
5808 /* cps (privileged) */
5812 if (insn & (1 << 19)) {
5813 if (insn & (1 << 8))
5815 if (insn & (1 << 7))
5817 if (insn & (1 << 6))
5819 if (insn & (1 << 18))
5822 if (insn & (1 << 14)) {
5824 val |= (insn & 0x1f);
5827 gen_op_movl_T0_im(val);
5828 gen_set_psr_T0(s, mask, 0);
5835 /* if not always execute, we generate a conditional jump to
5837 s->condlabel = gen_new_label();
5838 gen_test_cc(cond ^ 1, s->condlabel);
5841 if ((insn & 0x0f900000) == 0x03000000) {
5842 if ((insn & (1 << 21)) == 0) {
5844 rd = (insn >> 12) & 0xf;
5845 val = ((insn >> 4) & 0xf000) | (insn & 0xfff);
5846 if ((insn & (1 << 22)) == 0) {
5849 tcg_gen_movi_i32(tmp, val);
5852 tmp = load_reg(s, rd);
5853 tcg_gen_ext16u_i32(tmp, tmp);
5854 tcg_gen_ori_i32(tmp, tmp, val << 16);
5856 store_reg(s, rd, tmp);
5858 if (((insn >> 12) & 0xf) != 0xf)
5860 if (((insn >> 16) & 0xf) == 0) {
5861 gen_nop_hint(s, insn & 0xff);
5863 /* CPSR = immediate */
5865 shift = ((insn >> 8) & 0xf) * 2;
5867 val = (val >> shift) | (val << (32 - shift));
5868 gen_op_movl_T0_im(val);
5869 i = ((insn & (1 << 22)) != 0);
5870 if (gen_set_psr_T0(s, msr_mask(env, s, (insn >> 16) & 0xf, i), i))
5874 } else if ((insn & 0x0f900000) == 0x01000000
5875 && (insn & 0x00000090) != 0x00000090) {
5876 /* miscellaneous instructions */
5877 op1 = (insn >> 21) & 3;
5878 sh = (insn >> 4) & 0xf;
5881 case 0x0: /* move program status register */
5884 gen_movl_T0_reg(s, rm);
5885 i = ((op1 & 2) != 0);
5886 if (gen_set_psr_T0(s, msr_mask(env, s, (insn >> 16) & 0xf, i), i))
5890 rd = (insn >> 12) & 0xf;
5894 tmp = load_cpu_field(spsr);
5897 gen_helper_cpsr_read(tmp);
5899 store_reg(s, rd, tmp);
5904 /* branch/exchange thumb (bx). */
5905 tmp = load_reg(s, rm);
5907 } else if (op1 == 3) {
5909 rd = (insn >> 12) & 0xf;
5910 tmp = load_reg(s, rm);
5911 gen_helper_clz(tmp, tmp);
5912 store_reg(s, rd, tmp);
5920 /* Trivial implementation equivalent to bx. */
5921 tmp = load_reg(s, rm);
5931 /* branch link/exchange thumb (blx) */
5932 tmp = load_reg(s, rm);
5934 tcg_gen_movi_i32(tmp2, s->pc);
5935 store_reg(s, 14, tmp2);
5938 case 0x5: /* saturating add/subtract */
5939 rd = (insn >> 12) & 0xf;
5940 rn = (insn >> 16) & 0xf;
5941 tmp = load_reg(s, rn);
5942 tmp2 = load_reg(s, rn);
5944 gen_helper_double_saturate(tmp2, tmp2);
5946 gen_helper_sub_saturate(tmp, tmp, tmp2);
5948 gen_helper_add_saturate(tmp, tmp, tmp2);
5950 store_reg(s, rd, tmp);
5953 gen_set_condexec(s);
5954 gen_set_pc_im(s->pc - 4);
5955 gen_exception(EXCP_BKPT);
5956 s->is_jmp = DISAS_JUMP;
5958 case 0x8: /* signed multiply */
5962 rs = (insn >> 8) & 0xf;
5963 rn = (insn >> 12) & 0xf;
5964 rd = (insn >> 16) & 0xf;
5966 /* (32 * 16) >> 16 */
5967 tmp = load_reg(s, rm);
5968 tmp2 = load_reg(s, rs);
5970 tcg_gen_sari_i32(tmp2, tmp2, 16);
5973 tmp2 = gen_muls_i64_i32(tmp, tmp2);
5974 tcg_gen_shri_i64(tmp2, tmp2, 16);
5976 tcg_gen_trunc_i64_i32(tmp, tmp2);
5977 if ((sh & 2) == 0) {
5978 tmp2 = load_reg(s, rn);
5979 gen_helper_add_setq(tmp, tmp, tmp2);
5982 store_reg(s, rd, tmp);
5985 tmp = load_reg(s, rm);
5986 tmp2 = load_reg(s, rs);
5987 gen_mulxy(tmp, tmp2, sh & 2, sh & 4);
5990 tmp = tcg_temp_new(TCG_TYPE_I64);
5991 tcg_gen_ext_i32_i64(tmp, cpu_T[0]);
5992 gen_addq(s, tmp, rn, rd);
5993 gen_storeq_reg(s, rn, rd, tmp);
5996 tmp2 = load_reg(s, rn);
5997 gen_helper_add_setq(tmp, tmp, tmp2);
6000 store_reg(s, rd, tmp);
6007 } else if (((insn & 0x0e000000) == 0 &&
6008 (insn & 0x00000090) != 0x90) ||
6009 ((insn & 0x0e000000) == (1 << 25))) {
6010 int set_cc, logic_cc, shiftop;
6012 op1 = (insn >> 21) & 0xf;
6013 set_cc = (insn >> 20) & 1;
6014 logic_cc = table_logic_cc[op1] & set_cc;
6016 /* data processing instruction */
6017 if (insn & (1 << 25)) {
6018 /* immediate operand */
6020 shift = ((insn >> 8) & 0xf) * 2;
6022 val = (val >> shift) | (val << (32 - shift));
6023 gen_op_movl_T1_im(val);
6024 if (logic_cc && shift)
6025 gen_set_CF_bit31(cpu_T[1]);
6029 gen_movl_T1_reg(s, rm);
6030 shiftop = (insn >> 5) & 3;
6031 if (!(insn & (1 << 4))) {
6032 shift = (insn >> 7) & 0x1f;
6033 gen_arm_shift_im(cpu_T[1], shiftop, shift, logic_cc);
6035 rs = (insn >> 8) & 0xf;
6036 tmp = load_reg(s, rs);
6037 gen_arm_shift_reg(cpu_T[1], shiftop, tmp, logic_cc);
6040 if (op1 != 0x0f && op1 != 0x0d) {
6041 rn = (insn >> 16) & 0xf;
6042 gen_movl_T0_reg(s, rn);
6044 rd = (insn >> 12) & 0xf;
6047 gen_op_andl_T0_T1();
6048 gen_movl_reg_T0(s, rd);
6050 gen_op_logic_T0_cc();
6053 gen_op_xorl_T0_T1();
6054 gen_movl_reg_T0(s, rd);
6056 gen_op_logic_T0_cc();
6059 if (set_cc && rd == 15) {
6060 /* SUBS r15, ... is used for exception return. */
6063 gen_op_subl_T0_T1_cc();
6064 gen_exception_return(s);
6067 gen_op_subl_T0_T1_cc();
6069 gen_op_subl_T0_T1();
6070 gen_movl_reg_T0(s, rd);
6075 gen_op_rsbl_T0_T1_cc();
6077 gen_op_rsbl_T0_T1();
6078 gen_movl_reg_T0(s, rd);
6082 gen_op_addl_T0_T1_cc();
6084 gen_op_addl_T0_T1();
6085 gen_movl_reg_T0(s, rd);
6089 gen_op_adcl_T0_T1_cc();
6092 gen_movl_reg_T0(s, rd);
6096 gen_op_sbcl_T0_T1_cc();
6099 gen_movl_reg_T0(s, rd);
6103 gen_op_rscl_T0_T1_cc();
6106 gen_movl_reg_T0(s, rd);
6110 gen_op_andl_T0_T1();
6111 gen_op_logic_T0_cc();
6116 gen_op_xorl_T0_T1();
6117 gen_op_logic_T0_cc();
6122 gen_op_subl_T0_T1_cc();
6127 gen_op_addl_T0_T1_cc();
6132 gen_movl_reg_T0(s, rd);
6134 gen_op_logic_T0_cc();
6137 if (logic_cc && rd == 15) {
6138 /* MOVS r15, ... is used for exception return. */
6141 gen_op_movl_T0_T1();
6142 gen_exception_return(s);
6144 gen_movl_reg_T1(s, rd);
6146 gen_op_logic_T1_cc();
6150 gen_op_bicl_T0_T1();
6151 gen_movl_reg_T0(s, rd);
6153 gen_op_logic_T0_cc();
6158 gen_movl_reg_T1(s, rd);
6160 gen_op_logic_T1_cc();
6164 /* other instructions */
6165 op1 = (insn >> 24) & 0xf;
6169 /* multiplies, extra load/stores */
6170 sh = (insn >> 5) & 3;
6173 rd = (insn >> 16) & 0xf;
6174 rn = (insn >> 12) & 0xf;
6175 rs = (insn >> 8) & 0xf;
6177 op1 = (insn >> 20) & 0xf;
6179 case 0: case 1: case 2: case 3: case 6:
6181 tmp = load_reg(s, rs);
6182 tmp2 = load_reg(s, rm);
6183 tcg_gen_mul_i32(tmp, tmp, tmp2);
6185 if (insn & (1 << 22)) {
6186 /* Subtract (mls) */
6188 tmp2 = load_reg(s, rn);
6189 tcg_gen_sub_i32(tmp, tmp2, tmp);
6191 } else if (insn & (1 << 21)) {
6193 tmp2 = load_reg(s, rn);
6194 tcg_gen_add_i32(tmp, tmp, tmp2);
6197 if (insn & (1 << 20))
6199 store_reg(s, rd, tmp);
6203 tmp = load_reg(s, rs);
6204 tmp2 = load_reg(s, rm);
6205 if (insn & (1 << 22))
6206 tmp = gen_muls_i64_i32(tmp, tmp2);
6208 tmp = gen_mulu_i64_i32(tmp, tmp2);
6209 if (insn & (1 << 21)) /* mult accumulate */
6210 gen_addq(s, tmp, rn, rd);
6211 if (!(insn & (1 << 23))) { /* double accumulate */
6213 gen_addq_lo(s, tmp, rn);
6214 gen_addq_lo(s, tmp, rd);
6216 if (insn & (1 << 20))
6218 gen_storeq_reg(s, rn, rd, tmp);
6222 rn = (insn >> 16) & 0xf;
6223 rd = (insn >> 12) & 0xf;
6224 if (insn & (1 << 23)) {
6225 /* load/store exclusive */
6226 gen_movl_T1_reg(s, rn);
6228 if (insn & (1 << 20)) {
6229 gen_helper_mark_exclusive(cpu_env, cpu_T[1]);
6230 tmp = gen_ld32(addr, IS_USER(s));
6231 store_reg(s, rd, tmp);
6233 int label = gen_new_label();
6235 gen_helper_test_exclusive(cpu_T[0], cpu_env, addr);
6236 tcg_gen_brcond_i32(TCG_COND_NE, cpu_T[0],
6237 tcg_const_i32(0), label);
6238 tmp = load_reg(s,rm);
6239 gen_st32(tmp, cpu_T[1], IS_USER(s));
6240 gen_set_label(label);
6241 gen_movl_reg_T0(s, rd);
6244 /* SWP instruction */
6247 /* ??? This is not really atomic. However we know
6248 we never have multiple CPUs running in parallel,
6249 so it is good enough. */
6250 addr = load_reg(s, rn);
6251 tmp = load_reg(s, rm);
6252 if (insn & (1 << 22)) {
6253 tmp2 = gen_ld8u(addr, IS_USER(s));
6254 gen_st8(tmp, addr, IS_USER(s));
6256 tmp2 = gen_ld32(addr, IS_USER(s));
6257 gen_st32(tmp, addr, IS_USER(s));
6260 store_reg(s, rd, tmp2);
6266 /* Misc load/store */
6267 rn = (insn >> 16) & 0xf;
6268 rd = (insn >> 12) & 0xf;
6269 addr = load_reg(s, rn);
6270 if (insn & (1 << 24))
6271 gen_add_datah_offset(s, insn, 0, addr);
6273 if (insn & (1 << 20)) {
6277 tmp = gen_ld16u(addr, IS_USER(s));
6280 tmp = gen_ld8s(addr, IS_USER(s));
6284 tmp = gen_ld16s(addr, IS_USER(s));
6288 } else if (sh & 2) {
6292 tmp = load_reg(s, rd);
6293 gen_st32(tmp, addr, IS_USER(s));
6294 tcg_gen_addi_i32(addr, addr, 4);
6295 tmp = load_reg(s, rd + 1);
6296 gen_st32(tmp, addr, IS_USER(s));
6300 tmp = gen_ld32(addr, IS_USER(s));
6301 store_reg(s, rd, tmp);
6302 tcg_gen_addi_i32(addr, addr, 4);
6303 tmp = gen_ld32(addr, IS_USER(s));
6307 address_offset = -4;
6310 tmp = load_reg(s, rd);
6311 gen_st16(tmp, addr, IS_USER(s));
6314 /* Perform base writeback before the loaded value to
6315 ensure correct behavior with overlapping index registers.
6316 ldrd with base writeback is is undefined if the
6317 destination and index registers overlap. */
6318 if (!(insn & (1 << 24))) {
6319 gen_add_datah_offset(s, insn, address_offset, addr);
6320 store_reg(s, rn, addr);
6321 } else if (insn & (1 << 21)) {
6323 tcg_gen_addi_i32(addr, addr, address_offset);
6324 store_reg(s, rn, addr);
6329 /* Complete the load. */
6330 store_reg(s, rd, tmp);
6339 if (insn & (1 << 4)) {
6341 /* Armv6 Media instructions. */
6343 rn = (insn >> 16) & 0xf;
6344 rd = (insn >> 12) & 0xf;
6345 rs = (insn >> 8) & 0xf;
6346 switch ((insn >> 23) & 3) {
6347 case 0: /* Parallel add/subtract. */
6348 op1 = (insn >> 20) & 7;
6349 tmp = load_reg(s, rn);
6350 tmp2 = load_reg(s, rm);
6351 sh = (insn >> 5) & 7;
6352 if ((op1 & 3) == 0 || sh == 5 || sh == 6)
6354 gen_arm_parallel_addsub(op1, sh, tmp, tmp2);
6356 store_reg(s, rd, tmp);
6359 if ((insn & 0x00700020) == 0) {
6360 /* Halfword pack. */
6361 tmp = load_reg(s, rn);
6362 tmp2 = load_reg(s, rm);
6363 shift = (insn >> 7) & 0x1f;
6365 tcg_gen_shli_i32(tmp2, tmp2, shift);
6366 if (insn & (1 << 6)) {
6368 tcg_gen_andi_i32(tmp, tmp, 0xffff0000);
6369 tcg_gen_ext16u_i32(tmp2, tmp2);
6372 tcg_gen_ext16u_i32(tmp, tmp);
6373 tcg_gen_andi_i32(tmp2, tmp2, 0xffff0000);
6375 tcg_gen_or_i32(tmp, tmp, tmp2);
6376 store_reg(s, rd, tmp);
6377 } else if ((insn & 0x00200020) == 0x00200000) {
6379 tmp = load_reg(s, rm);
6380 shift = (insn >> 7) & 0x1f;
6381 if (insn & (1 << 6)) {
6384 tcg_gen_sari_i32(tmp, tmp, shift);
6386 tcg_gen_shli_i32(tmp, tmp, shift);
6388 sh = (insn >> 16) & 0x1f;
6390 if (insn & (1 << 22))
6391 gen_helper_usat(tmp, tmp, tcg_const_i32(sh));
6393 gen_helper_ssat(tmp, tmp, tcg_const_i32(sh));
6395 store_reg(s, rd, tmp);
6396 } else if ((insn & 0x00300fe0) == 0x00200f20) {
6398 tmp = load_reg(s, rm);
6399 sh = (insn >> 16) & 0x1f;
6401 if (insn & (1 << 22))
6402 gen_helper_usat16(tmp, tmp, tcg_const_i32(sh));
6404 gen_helper_ssat16(tmp, tmp, tcg_const_i32(sh));
6406 store_reg(s, rd, tmp);
6407 } else if ((insn & 0x00700fe0) == 0x00000fa0) {
6409 tmp = load_reg(s, rn);
6410 tmp2 = load_reg(s, rm);
6412 tcg_gen_ld_i32(tmp3, cpu_env, offsetof(CPUState, GE));
6413 gen_helper_sel_flags(tmp, tmp3, tmp, tmp2);
6416 store_reg(s, rd, tmp);
6417 } else if ((insn & 0x000003e0) == 0x00000060) {
6418 tmp = load_reg(s, rm);
6419 shift = (insn >> 10) & 3;
6420 /* ??? In many cases it's not neccessary to do a
6421 rotate, a shift is sufficient. */
6423 tcg_gen_rori_i32(tmp, tmp, shift * 8);
6424 op1 = (insn >> 20) & 7;
6426 case 0: gen_sxtb16(tmp); break;
6427 case 2: gen_sxtb(tmp); break;
6428 case 3: gen_sxth(tmp); break;
6429 case 4: gen_uxtb16(tmp); break;
6430 case 6: gen_uxtb(tmp); break;
6431 case 7: gen_uxth(tmp); break;
6432 default: goto illegal_op;
6435 tmp2 = load_reg(s, rn);
6436 if ((op1 & 3) == 0) {
6437 gen_add16(tmp, tmp2);
6439 tcg_gen_add_i32(tmp, tmp, tmp2);
6443 store_reg(s, rd, tmp);
6444 } else if ((insn & 0x003f0f60) == 0x003f0f20) {
6446 tmp = load_reg(s, rm);
6447 if (insn & (1 << 22)) {
6448 if (insn & (1 << 7)) {
6452 gen_helper_rbit(tmp, tmp);
6455 if (insn & (1 << 7))
6458 tcg_gen_bswap_i32(tmp, tmp);
6460 store_reg(s, rd, tmp);
6465 case 2: /* Multiplies (Type 3). */
6466 tmp = load_reg(s, rm);
6467 tmp2 = load_reg(s, rs);
6468 if (insn & (1 << 20)) {
6469 /* Signed multiply most significant [accumulate]. */
6470 tmp2 = gen_muls_i64_i32(tmp, tmp2);
6471 if (insn & (1 << 5))
6472 tcg_gen_addi_i64(tmp2, tmp2, 0x80000000u);
6473 tcg_gen_shri_i64(tmp2, tmp2, 32);
6475 tcg_gen_trunc_i64_i32(tmp, tmp2);
6477 tmp2 = load_reg(s, rn);
6478 if (insn & (1 << 6)) {
6479 tcg_gen_sub_i32(tmp, tmp, tmp2);
6481 tcg_gen_add_i32(tmp, tmp, tmp2);
6485 store_reg(s, rd, tmp);
6487 if (insn & (1 << 5))
6488 gen_swap_half(tmp2);
6489 gen_smul_dual(tmp, tmp2);
6490 /* This addition cannot overflow. */
6491 if (insn & (1 << 6)) {
6492 tcg_gen_sub_i32(tmp, tmp, tmp2);
6494 tcg_gen_add_i32(tmp, tmp, tmp2);
6497 if (insn & (1 << 22)) {
6498 /* smlald, smlsld */
6499 tmp2 = tcg_temp_new(TCG_TYPE_I64);
6500 tcg_gen_ext_i32_i64(tmp2, tmp);
6502 gen_addq(s, tmp2, rn, rd);
6503 gen_storeq_reg(s, rn, rd, tmp2);
6505 /* smuad, smusd, smlad, smlsd */
6508 tmp2 = load_reg(s, rn);
6509 gen_helper_add_setq(tmp, tmp, tmp2);
6512 store_reg(s, rd, tmp);
6517 op1 = ((insn >> 17) & 0x38) | ((insn >> 5) & 7);
6519 case 0: /* Unsigned sum of absolute differences. */
6521 tmp = load_reg(s, rm);
6522 tmp2 = load_reg(s, rs);
6523 gen_helper_usad8(tmp, tmp, tmp2);
6526 tmp2 = load_reg(s, rn);
6527 tcg_gen_add_i32(tmp, tmp, tmp2);
6530 store_reg(s, rd, tmp);
6532 case 0x20: case 0x24: case 0x28: case 0x2c:
6533 /* Bitfield insert/clear. */
6535 shift = (insn >> 7) & 0x1f;
6536 i = (insn >> 16) & 0x1f;
6540 tcg_gen_movi_i32(tmp, 0);
6542 tmp = load_reg(s, rm);
6545 tmp2 = load_reg(s, rd);
6546 gen_bfi(tmp, tmp2, tmp, shift, (1u << i) - 1);
6549 store_reg(s, rd, tmp);
6551 case 0x12: case 0x16: case 0x1a: case 0x1e: /* sbfx */
6552 case 0x32: case 0x36: case 0x3a: case 0x3e: /* ubfx */
6553 tmp = load_reg(s, rm);
6554 shift = (insn >> 7) & 0x1f;
6555 i = ((insn >> 16) & 0x1f) + 1;
6560 gen_ubfx(tmp, shift, (1u << i) - 1);
6562 gen_sbfx(tmp, shift, i);
6565 store_reg(s, rd, tmp);
6575 /* Check for undefined extension instructions
6576 * per the ARM Bible IE:
6577 * xxxx 0111 1111 xxxx xxxx xxxx 1111 xxxx
6579 sh = (0xf << 20) | (0xf << 4);
6580 if (op1 == 0x7 && ((insn & sh) == sh))
6584 /* load/store byte/word */
6585 rn = (insn >> 16) & 0xf;
6586 rd = (insn >> 12) & 0xf;
6587 tmp2 = load_reg(s, rn);
6588 i = (IS_USER(s) || (insn & 0x01200000) == 0x00200000);
6589 if (insn & (1 << 24))
6590 gen_add_data_offset(s, insn, tmp2);
6591 if (insn & (1 << 20)) {
6594 if (insn & (1 << 22)) {
6595 tmp = gen_ld8u(tmp2, i);
6597 tmp = gen_ld32(tmp2, i);
6601 tmp = load_reg(s, rd);
6602 if (insn & (1 << 22))
6603 gen_st8(tmp, tmp2, i);
6605 gen_st32(tmp, tmp2, i);
6607 if (!(insn & (1 << 24))) {
6608 gen_add_data_offset(s, insn, tmp2);
6609 store_reg(s, rn, tmp2);
6610 } else if (insn & (1 << 21)) {
6611 store_reg(s, rn, tmp2);
6615 if (insn & (1 << 20)) {
6616 /* Complete the load. */
6620 store_reg(s, rd, tmp);
6626 int j, n, user, loaded_base;
6628 /* load/store multiple words */
6629 /* XXX: store correct base if write back */
6631 if (insn & (1 << 22)) {
6633 goto illegal_op; /* only usable in supervisor mode */
6635 if ((insn & (1 << 15)) == 0)
6638 rn = (insn >> 16) & 0xf;
6639 addr = load_reg(s, rn);
6641 /* compute total size */
6645 if (insn & (1 << i))
6648 /* XXX: test invalid n == 0 case ? */
6649 if (insn & (1 << 23)) {
6650 if (insn & (1 << 24)) {
6652 tcg_gen_addi_i32(addr, addr, 4);
6654 /* post increment */
6657 if (insn & (1 << 24)) {
6659 tcg_gen_addi_i32(addr, addr, -(n * 4));
6661 /* post decrement */
6663 tcg_gen_addi_i32(addr, addr, -((n - 1) * 4));
6668 if (insn & (1 << i)) {
6669 if (insn & (1 << 20)) {
6671 tmp = gen_ld32(addr, IS_USER(s));
6675 gen_helper_set_user_reg(tcg_const_i32(i), tmp);
6677 } else if (i == rn) {
6681 store_reg(s, i, tmp);
6686 /* special case: r15 = PC + 8 */
6687 val = (long)s->pc + 4;
6689 tcg_gen_movi_i32(tmp, val);
6692 gen_helper_get_user_reg(tmp, tcg_const_i32(i));
6694 tmp = load_reg(s, i);
6696 gen_st32(tmp, addr, IS_USER(s));
6699 /* no need to add after the last transfer */
6701 tcg_gen_addi_i32(addr, addr, 4);
6704 if (insn & (1 << 21)) {
6706 if (insn & (1 << 23)) {
6707 if (insn & (1 << 24)) {
6710 /* post increment */
6711 tcg_gen_addi_i32(addr, addr, 4);
6714 if (insn & (1 << 24)) {
6717 tcg_gen_addi_i32(addr, addr, -((n - 1) * 4));
6719 /* post decrement */
6720 tcg_gen_addi_i32(addr, addr, -(n * 4));
6723 store_reg(s, rn, addr);
6728 store_reg(s, rn, loaded_var);
6730 if ((insn & (1 << 22)) && !user) {
6731 /* Restore CPSR from SPSR. */
6732 tmp = load_cpu_field(spsr);
6733 gen_set_cpsr(tmp, 0xffffffff);
6735 s->is_jmp = DISAS_UPDATE;
6744 /* branch (and link) */
6745 val = (int32_t)s->pc;
6746 if (insn & (1 << 24)) {
6748 tcg_gen_movi_i32(tmp, val);
6749 store_reg(s, 14, tmp);
6751 offset = (((int32_t)insn << 8) >> 8);
6752 val += (offset << 2) + 4;
6760 if (disas_coproc_insn(env, s, insn))
6765 gen_set_pc_im(s->pc);
6766 s->is_jmp = DISAS_SWI;
6770 gen_set_condexec(s);
6771 gen_set_pc_im(s->pc - 4);
6772 gen_exception(EXCP_UDEF);
6773 s->is_jmp = DISAS_JUMP;
6779 /* Return true if this is a Thumb-2 logical op. */
6781 thumb2_logic_op(int op)
6786 /* Generate code for a Thumb-2 data processing operation. If CONDS is nonzero
6787 then set condition code flags based on the result of the operation.
6788 If SHIFTER_OUT is nonzero then set the carry flag for logical operations
6789 to the high bit of T1.
6790 Returns zero if the opcode is valid. */
6793 gen_thumb2_data_op(DisasContext *s, int op, int conds, uint32_t shifter_out)
6800 gen_op_andl_T0_T1();
6804 gen_op_bicl_T0_T1();
6817 gen_op_xorl_T0_T1();
6822 gen_op_addl_T0_T1_cc();
6824 gen_op_addl_T0_T1();
6828 gen_op_adcl_T0_T1_cc();
6834 gen_op_sbcl_T0_T1_cc();
6840 gen_op_subl_T0_T1_cc();
6842 gen_op_subl_T0_T1();
6846 gen_op_rsbl_T0_T1_cc();
6848 gen_op_rsbl_T0_T1();
6850 default: /* 5, 6, 7, 9, 12, 15. */
6854 gen_op_logic_T0_cc();
6856 gen_set_CF_bit31(cpu_T[1]);
6861 /* Translate a 32-bit thumb instruction. Returns nonzero if the instruction
6863 static int disas_thumb2_insn(CPUState *env, DisasContext *s, uint16_t insn_hw1)
6865 uint32_t insn, imm, shift, offset;
6866 uint32_t rd, rn, rm, rs;
6876 if (!(arm_feature(env, ARM_FEATURE_THUMB2)
6877 || arm_feature (env, ARM_FEATURE_M))) {
6878 /* Thumb-1 cores may need to treat bl and blx as a pair of
6879 16-bit instructions to get correct prefetch abort behavior. */
6881 if ((insn & (1 << 12)) == 0) {
6882 /* Second half of blx. */
6883 offset = ((insn & 0x7ff) << 1);
6884 tmp = load_reg(s, 14);
6885 tcg_gen_addi_i32(tmp, tmp, offset);
6886 tcg_gen_andi_i32(tmp, tmp, 0xfffffffc);
6889 tcg_gen_movi_i32(tmp2, s->pc | 1);
6890 store_reg(s, 14, tmp2);
6894 if (insn & (1 << 11)) {
6895 /* Second half of bl. */
6896 offset = ((insn & 0x7ff) << 1) | 1;
6897 tmp = load_reg(s, 14);
6898 tcg_gen_addi_i32(tmp, tmp, offset);
6901 tcg_gen_movi_i32(tmp2, s->pc | 1);
6902 store_reg(s, 14, tmp2);
6906 if ((s->pc & ~TARGET_PAGE_MASK) == 0) {
6907 /* Instruction spans a page boundary. Implement it as two
6908 16-bit instructions in case the second half causes an
6910 offset = ((int32_t)insn << 21) >> 9;
6911 gen_op_movl_T0_im(s->pc + 2 + offset);
6912 gen_movl_reg_T0(s, 14);
6915 /* Fall through to 32-bit decode. */
6918 insn = lduw_code(s->pc);
6920 insn |= (uint32_t)insn_hw1 << 16;
6922 if ((insn & 0xf800e800) != 0xf000e800) {
6926 rn = (insn >> 16) & 0xf;
6927 rs = (insn >> 12) & 0xf;
6928 rd = (insn >> 8) & 0xf;
6930 switch ((insn >> 25) & 0xf) {
6931 case 0: case 1: case 2: case 3:
6932 /* 16-bit instructions. Should never happen. */
6935 if (insn & (1 << 22)) {
6936 /* Other load/store, table branch. */
6937 if (insn & 0x01200000) {
6938 /* Load/store doubleword. */
6941 tcg_gen_movi_i32(addr, s->pc & ~3);
6943 addr = load_reg(s, rn);
6945 offset = (insn & 0xff) * 4;
6946 if ((insn & (1 << 23)) == 0)
6948 if (insn & (1 << 24)) {
6949 tcg_gen_addi_i32(addr, addr, offset);
6952 if (insn & (1 << 20)) {
6954 tmp = gen_ld32(addr, IS_USER(s));
6955 store_reg(s, rs, tmp);
6956 tcg_gen_addi_i32(addr, addr, 4);
6957 tmp = gen_ld32(addr, IS_USER(s));
6958 store_reg(s, rd, tmp);
6961 tmp = load_reg(s, rs);
6962 gen_st32(tmp, addr, IS_USER(s));
6963 tcg_gen_addi_i32(addr, addr, 4);
6964 tmp = load_reg(s, rd);
6965 gen_st32(tmp, addr, IS_USER(s));
6967 if (insn & (1 << 21)) {
6968 /* Base writeback. */
6971 tcg_gen_addi_i32(addr, addr, offset - 4);
6972 store_reg(s, rn, addr);
6976 } else if ((insn & (1 << 23)) == 0) {
6977 /* Load/store exclusive word. */
6978 gen_movl_T1_reg(s, rn);
6980 if (insn & (1 << 20)) {
6981 gen_helper_mark_exclusive(cpu_env, cpu_T[1]);
6982 tmp = gen_ld32(addr, IS_USER(s));
6983 store_reg(s, rd, tmp);
6985 int label = gen_new_label();
6986 gen_helper_test_exclusive(cpu_T[0], cpu_env, addr);
6987 tcg_gen_brcond_i32(TCG_COND_NE, cpu_T[0],
6988 tcg_const_i32(0), label);
6989 tmp = load_reg(s, rs);
6990 gen_st32(tmp, cpu_T[1], IS_USER(s));
6991 gen_set_label(label);
6992 gen_movl_reg_T0(s, rd);
6994 } else if ((insn & (1 << 6)) == 0) {
6998 tcg_gen_movi_i32(addr, s->pc);
7000 addr = load_reg(s, rn);
7002 tmp = load_reg(s, rm);
7003 tcg_gen_add_i32(addr, addr, tmp);
7004 if (insn & (1 << 4)) {
7006 tcg_gen_add_i32(addr, addr, tmp);
7008 tmp = gen_ld16u(addr, IS_USER(s));
7011 tmp = gen_ld8u(addr, IS_USER(s));
7014 tcg_gen_shli_i32(tmp, tmp, 1);
7015 tcg_gen_addi_i32(tmp, tmp, s->pc);
7016 store_reg(s, 15, tmp);
7018 /* Load/store exclusive byte/halfword/doubleword. */
7019 /* ??? These are not really atomic. However we know
7020 we never have multiple CPUs running in parallel,
7021 so it is good enough. */
7022 op = (insn >> 4) & 0x3;
7023 /* Must use a global reg for the address because we have
7024 a conditional branch in the store instruction. */
7025 gen_movl_T1_reg(s, rn);
7027 if (insn & (1 << 20)) {
7028 gen_helper_mark_exclusive(cpu_env, addr);
7031 tmp = gen_ld8u(addr, IS_USER(s));
7034 tmp = gen_ld16u(addr, IS_USER(s));
7037 tmp = gen_ld32(addr, IS_USER(s));
7038 tcg_gen_addi_i32(addr, addr, 4);
7039 tmp2 = gen_ld32(addr, IS_USER(s));
7040 store_reg(s, rd, tmp2);
7045 store_reg(s, rs, tmp);
7047 int label = gen_new_label();
7048 /* Must use a global that is not killed by the branch. */
7049 gen_helper_test_exclusive(cpu_T[0], cpu_env, addr);
7050 tcg_gen_brcond_i32(TCG_COND_NE, cpu_T[0], tcg_const_i32(0),
7052 tmp = load_reg(s, rs);
7055 gen_st8(tmp, addr, IS_USER(s));
7058 gen_st16(tmp, addr, IS_USER(s));
7061 gen_st32(tmp, addr, IS_USER(s));
7062 tcg_gen_addi_i32(addr, addr, 4);
7063 tmp = load_reg(s, rd);
7064 gen_st32(tmp, addr, IS_USER(s));
7069 gen_set_label(label);
7070 gen_movl_reg_T0(s, rm);
7074 /* Load/store multiple, RFE, SRS. */
7075 if (((insn >> 23) & 1) == ((insn >> 24) & 1)) {
7076 /* Not available in user mode. */
7079 if (insn & (1 << 20)) {
7081 addr = load_reg(s, rn);
7082 if ((insn & (1 << 24)) == 0)
7083 tcg_gen_addi_i32(addr, addr, -8);
7084 /* Load PC into tmp and CPSR into tmp2. */
7085 tmp = gen_ld32(addr, 0);
7086 tcg_gen_addi_i32(addr, addr, 4);
7087 tmp2 = gen_ld32(addr, 0);
7088 if (insn & (1 << 21)) {
7089 /* Base writeback. */
7090 if (insn & (1 << 24)) {
7091 tcg_gen_addi_i32(addr, addr, 4);
7093 tcg_gen_addi_i32(addr, addr, -4);
7095 store_reg(s, rn, addr);
7099 gen_rfe(s, tmp, tmp2);
7103 if (op == (env->uncached_cpsr & CPSR_M)) {
7104 addr = load_reg(s, 13);
7107 gen_helper_get_r13_banked(addr, cpu_env, tcg_const_i32(op));
7109 if ((insn & (1 << 24)) == 0) {
7110 tcg_gen_addi_i32(addr, addr, -8);
7112 tmp = load_reg(s, 14);
7113 gen_st32(tmp, addr, 0);
7114 tcg_gen_addi_i32(addr, addr, 4);
7116 gen_helper_cpsr_read(tmp);
7117 gen_st32(tmp, addr, 0);
7118 if (insn & (1 << 21)) {
7119 if ((insn & (1 << 24)) == 0) {
7120 tcg_gen_addi_i32(addr, addr, -4);
7122 tcg_gen_addi_i32(addr, addr, 4);
7124 if (op == (env->uncached_cpsr & CPSR_M)) {
7125 store_reg(s, 13, addr);
7127 gen_helper_set_r13_banked(cpu_env,
7128 tcg_const_i32(op), addr);
7136 /* Load/store multiple. */
7137 addr = load_reg(s, rn);
7139 for (i = 0; i < 16; i++) {
7140 if (insn & (1 << i))
7143 if (insn & (1 << 24)) {
7144 tcg_gen_addi_i32(addr, addr, -offset);
7147 for (i = 0; i < 16; i++) {
7148 if ((insn & (1 << i)) == 0)
7150 if (insn & (1 << 20)) {
7152 tmp = gen_ld32(addr, IS_USER(s));
7156 store_reg(s, i, tmp);
7160 tmp = load_reg(s, i);
7161 gen_st32(tmp, addr, IS_USER(s));
7163 tcg_gen_addi_i32(addr, addr, 4);
7165 if (insn & (1 << 21)) {
7166 /* Base register writeback. */
7167 if (insn & (1 << 24)) {
7168 tcg_gen_addi_i32(addr, addr, -offset);
7170 /* Fault if writeback register is in register list. */
7171 if (insn & (1 << rn))
7173 store_reg(s, rn, addr);
7180 case 5: /* Data processing register constant shift. */
7182 gen_op_movl_T0_im(0);
7184 gen_movl_T0_reg(s, rn);
7185 gen_movl_T1_reg(s, rm);
7186 op = (insn >> 21) & 0xf;
7187 shiftop = (insn >> 4) & 3;
7188 shift = ((insn >> 6) & 3) | ((insn >> 10) & 0x1c);
7189 conds = (insn & (1 << 20)) != 0;
7190 logic_cc = (conds && thumb2_logic_op(op));
7191 gen_arm_shift_im(cpu_T[1], shiftop, shift, logic_cc);
7192 if (gen_thumb2_data_op(s, op, conds, 0))
7195 gen_movl_reg_T0(s, rd);
7197 case 13: /* Misc data processing. */
7198 op = ((insn >> 22) & 6) | ((insn >> 7) & 1);
7199 if (op < 4 && (insn & 0xf000) != 0xf000)
7202 case 0: /* Register controlled shift. */
7203 tmp = load_reg(s, rn);
7204 tmp2 = load_reg(s, rm);
7205 if ((insn & 0x70) != 0)
7207 op = (insn >> 21) & 3;
7208 logic_cc = (insn & (1 << 20)) != 0;
7209 gen_arm_shift_reg(tmp, op, tmp2, logic_cc);
7212 store_reg(s, rd, tmp);
7214 case 1: /* Sign/zero extend. */
7215 tmp = load_reg(s, rm);
7216 shift = (insn >> 4) & 3;
7217 /* ??? In many cases it's not neccessary to do a
7218 rotate, a shift is sufficient. */
7220 tcg_gen_rori_i32(tmp, tmp, shift * 8);
7221 op = (insn >> 20) & 7;
7223 case 0: gen_sxth(tmp); break;
7224 case 1: gen_uxth(tmp); break;
7225 case 2: gen_sxtb16(tmp); break;
7226 case 3: gen_uxtb16(tmp); break;
7227 case 4: gen_sxtb(tmp); break;
7228 case 5: gen_uxtb(tmp); break;
7229 default: goto illegal_op;
7232 tmp2 = load_reg(s, rn);
7233 if ((op >> 1) == 1) {
7234 gen_add16(tmp, tmp2);
7236 tcg_gen_add_i32(tmp, tmp, tmp2);
7240 store_reg(s, rd, tmp);
7242 case 2: /* SIMD add/subtract. */
7243 op = (insn >> 20) & 7;
7244 shift = (insn >> 4) & 7;
7245 if ((op & 3) == 3 || (shift & 3) == 3)
7247 tmp = load_reg(s, rn);
7248 tmp2 = load_reg(s, rm);
7249 gen_thumb2_parallel_addsub(op, shift, tmp, tmp2);
7251 store_reg(s, rd, tmp);
7253 case 3: /* Other data processing. */
7254 op = ((insn >> 17) & 0x38) | ((insn >> 4) & 7);
7256 /* Saturating add/subtract. */
7257 tmp = load_reg(s, rn);
7258 tmp2 = load_reg(s, rm);
7260 gen_helper_double_saturate(tmp, tmp);
7262 gen_helper_sub_saturate(tmp, tmp2, tmp);
7264 gen_helper_add_saturate(tmp, tmp, tmp2);
7267 tmp = load_reg(s, rn);
7269 case 0x0a: /* rbit */
7270 gen_helper_rbit(tmp, tmp);
7272 case 0x08: /* rev */
7273 tcg_gen_bswap_i32(tmp, tmp);
7275 case 0x09: /* rev16 */
7278 case 0x0b: /* revsh */
7281 case 0x10: /* sel */
7282 tmp2 = load_reg(s, rm);
7284 tcg_gen_ld_i32(tmp3, cpu_env, offsetof(CPUState, GE));
7285 gen_helper_sel_flags(tmp, tmp3, tmp, tmp2);
7289 case 0x18: /* clz */
7290 gen_helper_clz(tmp, tmp);
7296 store_reg(s, rd, tmp);
7298 case 4: case 5: /* 32-bit multiply. Sum of absolute differences. */
7299 op = (insn >> 4) & 0xf;
7300 tmp = load_reg(s, rn);
7301 tmp2 = load_reg(s, rm);
7302 switch ((insn >> 20) & 7) {
7303 case 0: /* 32 x 32 -> 32 */
7304 tcg_gen_mul_i32(tmp, tmp, tmp2);
7307 tmp2 = load_reg(s, rs);
7309 tcg_gen_sub_i32(tmp, tmp2, tmp);
7311 tcg_gen_add_i32(tmp, tmp, tmp2);
7315 case 1: /* 16 x 16 -> 32 */
7316 gen_mulxy(tmp, tmp2, op & 2, op & 1);
7319 tmp2 = load_reg(s, rs);
7320 gen_helper_add_setq(tmp, tmp, tmp2);
7324 case 2: /* Dual multiply add. */
7325 case 4: /* Dual multiply subtract. */
7327 gen_swap_half(tmp2);
7328 gen_smul_dual(tmp, tmp2);
7329 /* This addition cannot overflow. */
7330 if (insn & (1 << 22)) {
7331 tcg_gen_sub_i32(tmp, tmp, tmp2);
7333 tcg_gen_add_i32(tmp, tmp, tmp2);
7338 tmp2 = load_reg(s, rs);
7339 gen_helper_add_setq(tmp, tmp, tmp2);
7343 case 3: /* 32 * 16 -> 32msb */
7345 tcg_gen_sari_i32(tmp2, tmp2, 16);
7348 tmp2 = gen_muls_i64_i32(tmp, tmp2);
7349 tcg_gen_shri_i64(tmp2, tmp2, 16);
7351 tcg_gen_trunc_i64_i32(tmp, tmp2);
7354 tmp2 = load_reg(s, rs);
7355 gen_helper_add_setq(tmp, tmp, tmp2);
7359 case 5: case 6: /* 32 * 32 -> 32msb */
7360 gen_imull(tmp, tmp2);
7361 if (insn & (1 << 5)) {
7362 gen_roundqd(tmp, tmp2);
7369 tmp2 = load_reg(s, rs);
7370 if (insn & (1 << 21)) {
7371 tcg_gen_add_i32(tmp, tmp, tmp2);
7373 tcg_gen_sub_i32(tmp, tmp2, tmp);
7378 case 7: /* Unsigned sum of absolute differences. */
7379 gen_helper_usad8(tmp, tmp, tmp2);
7382 tmp2 = load_reg(s, rs);
7383 tcg_gen_add_i32(tmp, tmp, tmp2);
7388 store_reg(s, rd, tmp);
7390 case 6: case 7: /* 64-bit multiply, Divide. */
7391 op = ((insn >> 4) & 0xf) | ((insn >> 16) & 0x70);
7392 tmp = load_reg(s, rn);
7393 tmp2 = load_reg(s, rm);
7394 if ((op & 0x50) == 0x10) {
7396 if (!arm_feature(env, ARM_FEATURE_DIV))
7399 gen_helper_udiv(tmp, tmp, tmp2);
7401 gen_helper_sdiv(tmp, tmp, tmp2);
7403 store_reg(s, rd, tmp);
7404 } else if ((op & 0xe) == 0xc) {
7405 /* Dual multiply accumulate long. */
7407 gen_swap_half(tmp2);
7408 gen_smul_dual(tmp, tmp2);
7410 tcg_gen_sub_i32(tmp, tmp, tmp2);
7412 tcg_gen_add_i32(tmp, tmp, tmp2);
7415 tmp2 = tcg_temp_new(TCG_TYPE_I64);
7416 gen_addq(s, tmp, rs, rd);
7417 gen_storeq_reg(s, rs, rd, tmp);
7420 /* Unsigned 64-bit multiply */
7421 tmp = gen_mulu_i64_i32(tmp, tmp2);
7425 gen_mulxy(tmp, tmp2, op & 2, op & 1);
7427 tmp2 = tcg_temp_new(TCG_TYPE_I64);
7428 tcg_gen_ext_i32_i64(tmp2, tmp);
7432 /* Signed 64-bit multiply */
7433 tmp = gen_muls_i64_i32(tmp, tmp2);
7438 gen_addq_lo(s, tmp, rs);
7439 gen_addq_lo(s, tmp, rd);
7440 } else if (op & 0x40) {
7441 /* 64-bit accumulate. */
7442 gen_addq(s, tmp, rs, rd);
7444 gen_storeq_reg(s, rs, rd, tmp);
7449 case 6: case 7: case 14: case 15:
7451 if (((insn >> 24) & 3) == 3) {
7452 /* Translate into the equivalent ARM encoding. */
7453 insn = (insn & 0xe2ffffff) | ((insn & (1 << 28)) >> 4);
7454 if (disas_neon_data_insn(env, s, insn))
7457 if (insn & (1 << 28))
7459 if (disas_coproc_insn (env, s, insn))
7463 case 8: case 9: case 10: case 11:
7464 if (insn & (1 << 15)) {
7465 /* Branches, misc control. */
7466 if (insn & 0x5000) {
7467 /* Unconditional branch. */
7468 /* signextend(hw1[10:0]) -> offset[:12]. */
7469 offset = ((int32_t)insn << 5) >> 9 & ~(int32_t)0xfff;
7470 /* hw1[10:0] -> offset[11:1]. */
7471 offset |= (insn & 0x7ff) << 1;
7472 /* (~hw2[13, 11] ^ offset[24]) -> offset[23,22]
7473 offset[24:22] already have the same value because of the
7474 sign extension above. */
7475 offset ^= ((~insn) & (1 << 13)) << 10;
7476 offset ^= ((~insn) & (1 << 11)) << 11;
7478 if (insn & (1 << 14)) {
7479 /* Branch and link. */
7480 gen_op_movl_T1_im(s->pc | 1);
7481 gen_movl_reg_T1(s, 14);
7485 if (insn & (1 << 12)) {
7490 offset &= ~(uint32_t)2;
7491 gen_bx_im(s, offset);
7493 } else if (((insn >> 23) & 7) == 7) {
7495 if (insn & (1 << 13))
7498 if (insn & (1 << 26)) {
7499 /* Secure monitor call (v6Z) */
7500 goto illegal_op; /* not implemented. */
7502 op = (insn >> 20) & 7;
7504 case 0: /* msr cpsr. */
7506 tmp = load_reg(s, rn);
7507 addr = tcg_const_i32(insn & 0xff);
7508 gen_helper_v7m_msr(cpu_env, addr, tmp);
7513 case 1: /* msr spsr. */
7516 gen_movl_T0_reg(s, rn);
7517 if (gen_set_psr_T0(s,
7518 msr_mask(env, s, (insn >> 8) & 0xf, op == 1),
7522 case 2: /* cps, nop-hint. */
7523 if (((insn >> 8) & 7) == 0) {
7524 gen_nop_hint(s, insn & 0xff);
7526 /* Implemented as NOP in user mode. */
7531 if (insn & (1 << 10)) {
7532 if (insn & (1 << 7))
7534 if (insn & (1 << 6))
7536 if (insn & (1 << 5))
7538 if (insn & (1 << 9))
7539 imm = CPSR_A | CPSR_I | CPSR_F;
7541 if (insn & (1 << 8)) {
7543 imm |= (insn & 0x1f);
7546 gen_op_movl_T0_im(imm);
7547 gen_set_psr_T0(s, offset, 0);
7550 case 3: /* Special control operations. */
7551 op = (insn >> 4) & 0xf;
7554 gen_helper_clrex(cpu_env);
7559 /* These execute as NOPs. */
7567 /* Trivial implementation equivalent to bx. */
7568 tmp = load_reg(s, rn);
7571 case 5: /* Exception return. */
7572 /* Unpredictable in user mode. */
7574 case 6: /* mrs cpsr. */
7577 addr = tcg_const_i32(insn & 0xff);
7578 gen_helper_v7m_mrs(tmp, cpu_env, addr);
7580 gen_helper_cpsr_read(tmp);
7582 store_reg(s, rd, tmp);
7584 case 7: /* mrs spsr. */
7585 /* Not accessible in user mode. */
7586 if (IS_USER(s) || IS_M(env))
7588 tmp = load_cpu_field(spsr);
7589 store_reg(s, rd, tmp);
7594 /* Conditional branch. */
7595 op = (insn >> 22) & 0xf;
7596 /* Generate a conditional jump to next instruction. */
7597 s->condlabel = gen_new_label();
7598 gen_test_cc(op ^ 1, s->condlabel);
7601 /* offset[11:1] = insn[10:0] */
7602 offset = (insn & 0x7ff) << 1;
7603 /* offset[17:12] = insn[21:16]. */
7604 offset |= (insn & 0x003f0000) >> 4;
7605 /* offset[31:20] = insn[26]. */
7606 offset |= ((int32_t)((insn << 5) & 0x80000000)) >> 11;
7607 /* offset[18] = insn[13]. */
7608 offset |= (insn & (1 << 13)) << 5;
7609 /* offset[19] = insn[11]. */
7610 offset |= (insn & (1 << 11)) << 8;
7612 /* jump to the offset */
7613 gen_jmp(s, s->pc + offset);
7616 /* Data processing immediate. */
7617 if (insn & (1 << 25)) {
7618 if (insn & (1 << 24)) {
7619 if (insn & (1 << 20))
7621 /* Bitfield/Saturate. */
7622 op = (insn >> 21) & 7;
7624 shift = ((insn >> 6) & 3) | ((insn >> 10) & 0x1c);
7627 tcg_gen_movi_i32(tmp, 0);
7629 tmp = load_reg(s, rn);
7632 case 2: /* Signed bitfield extract. */
7634 if (shift + imm > 32)
7637 gen_sbfx(tmp, shift, imm);
7639 case 6: /* Unsigned bitfield extract. */
7641 if (shift + imm > 32)
7644 gen_ubfx(tmp, shift, (1u << imm) - 1);
7646 case 3: /* Bitfield insert/clear. */
7649 imm = imm + 1 - shift;
7651 tmp2 = load_reg(s, rd);
7652 gen_bfi(tmp, tmp2, tmp, shift, (1u << imm) - 1);
7658 default: /* Saturate. */
7661 tcg_gen_sari_i32(tmp, tmp, shift);
7663 tcg_gen_shli_i32(tmp, tmp, shift);
7665 tmp2 = tcg_const_i32(imm);
7668 if ((op & 1) && shift == 0)
7669 gen_helper_usat16(tmp, tmp, tmp2);
7671 gen_helper_usat(tmp, tmp, tmp2);
7674 if ((op & 1) && shift == 0)
7675 gen_helper_ssat16(tmp, tmp, tmp2);
7677 gen_helper_ssat(tmp, tmp, tmp2);
7681 store_reg(s, rd, tmp);
7683 imm = ((insn & 0x04000000) >> 15)
7684 | ((insn & 0x7000) >> 4) | (insn & 0xff);
7685 if (insn & (1 << 22)) {
7686 /* 16-bit immediate. */
7687 imm |= (insn >> 4) & 0xf000;
7688 if (insn & (1 << 23)) {
7690 tmp = load_reg(s, rd);
7691 tcg_gen_ext16u_i32(tmp, tmp);
7692 tcg_gen_ori_i32(tmp, tmp, imm << 16);
7696 tcg_gen_movi_i32(tmp, imm);
7699 /* Add/sub 12-bit immediate. */
7701 offset = s->pc & ~(uint32_t)3;
7702 if (insn & (1 << 23))
7707 tcg_gen_movi_i32(tmp, offset);
7709 tmp = load_reg(s, rn);
7710 if (insn & (1 << 23))
7711 tcg_gen_subi_i32(tmp, tmp, imm);
7713 tcg_gen_addi_i32(tmp, tmp, imm);
7716 store_reg(s, rd, tmp);
7719 int shifter_out = 0;
7720 /* modified 12-bit immediate. */
7721 shift = ((insn & 0x04000000) >> 23) | ((insn & 0x7000) >> 12);
7722 imm = (insn & 0xff);
7725 /* Nothing to do. */
7727 case 1: /* 00XY00XY */
7730 case 2: /* XY00XY00 */
7734 case 3: /* XYXYXYXY */
7738 default: /* Rotated constant. */
7739 shift = (shift << 1) | (imm >> 7);
7741 imm = imm << (32 - shift);
7745 gen_op_movl_T1_im(imm);
7746 rn = (insn >> 16) & 0xf;
7748 gen_op_movl_T0_im(0);
7750 gen_movl_T0_reg(s, rn);
7751 op = (insn >> 21) & 0xf;
7752 if (gen_thumb2_data_op(s, op, (insn & (1 << 20)) != 0,
7755 rd = (insn >> 8) & 0xf;
7757 gen_movl_reg_T0(s, rd);
7762 case 12: /* Load/store single data item. */
7767 if ((insn & 0x01100000) == 0x01000000) {
7768 if (disas_neon_ls_insn(env, s, insn))
7776 /* s->pc has already been incremented by 4. */
7777 imm = s->pc & 0xfffffffc;
7778 if (insn & (1 << 23))
7779 imm += insn & 0xfff;
7781 imm -= insn & 0xfff;
7782 tcg_gen_movi_i32(addr, imm);
7784 addr = load_reg(s, rn);
7785 if (insn & (1 << 23)) {
7786 /* Positive offset. */
7788 tcg_gen_addi_i32(addr, addr, imm);
7790 op = (insn >> 8) & 7;
7793 case 0: case 8: /* Shifted Register. */
7794 shift = (insn >> 4) & 0xf;
7797 tmp = load_reg(s, rm);
7799 tcg_gen_shli_i32(tmp, tmp, shift);
7800 tcg_gen_add_i32(addr, addr, tmp);
7803 case 4: /* Negative offset. */
7804 tcg_gen_addi_i32(addr, addr, -imm);
7806 case 6: /* User privilege. */
7807 tcg_gen_addi_i32(addr, addr, imm);
7810 case 1: /* Post-decrement. */
7813 case 3: /* Post-increment. */
7817 case 5: /* Pre-decrement. */
7820 case 7: /* Pre-increment. */
7821 tcg_gen_addi_i32(addr, addr, imm);
7829 op = ((insn >> 21) & 3) | ((insn >> 22) & 4);
7830 if (insn & (1 << 20)) {
7832 if (rs == 15 && op != 2) {
7835 /* Memory hint. Implemented as NOP. */
7838 case 0: tmp = gen_ld8u(addr, user); break;
7839 case 4: tmp = gen_ld8s(addr, user); break;
7840 case 1: tmp = gen_ld16u(addr, user); break;
7841 case 5: tmp = gen_ld16s(addr, user); break;
7842 case 2: tmp = gen_ld32(addr, user); break;
7843 default: goto illegal_op;
7848 store_reg(s, rs, tmp);
7855 tmp = load_reg(s, rs);
7857 case 0: gen_st8(tmp, addr, user); break;
7858 case 1: gen_st16(tmp, addr, user); break;
7859 case 2: gen_st32(tmp, addr, user); break;
7860 default: goto illegal_op;
7864 tcg_gen_addi_i32(addr, addr, imm);
7866 store_reg(s, rn, addr);
7880 static void disas_thumb_insn(CPUState *env, DisasContext *s)
7882 uint32_t val, insn, op, rm, rn, rd, shift, cond;
7889 if (s->condexec_mask) {
7890 cond = s->condexec_cond;
7891 s->condlabel = gen_new_label();
7892 gen_test_cc(cond ^ 1, s->condlabel);
7896 insn = lduw_code(s->pc);
7899 switch (insn >> 12) {
7902 op = (insn >> 11) & 3;
7905 rn = (insn >> 3) & 7;
7906 gen_movl_T0_reg(s, rn);
7907 if (insn & (1 << 10)) {
7909 gen_op_movl_T1_im((insn >> 6) & 7);
7912 rm = (insn >> 6) & 7;
7913 gen_movl_T1_reg(s, rm);
7915 if (insn & (1 << 9)) {
7916 if (s->condexec_mask)
7917 gen_op_subl_T0_T1();
7919 gen_op_subl_T0_T1_cc();
7921 if (s->condexec_mask)
7922 gen_op_addl_T0_T1();
7924 gen_op_addl_T0_T1_cc();
7926 gen_movl_reg_T0(s, rd);
7928 /* shift immediate */
7929 rm = (insn >> 3) & 7;
7930 shift = (insn >> 6) & 0x1f;
7931 tmp = load_reg(s, rm);
7932 gen_arm_shift_im(tmp, op, shift, s->condexec_mask == 0);
7933 if (!s->condexec_mask)
7935 store_reg(s, rd, tmp);
7939 /* arithmetic large immediate */
7940 op = (insn >> 11) & 3;
7941 rd = (insn >> 8) & 0x7;
7943 gen_op_movl_T0_im(insn & 0xff);
7945 gen_movl_T0_reg(s, rd);
7946 gen_op_movl_T1_im(insn & 0xff);
7950 if (!s->condexec_mask)
7951 gen_op_logic_T0_cc();
7954 gen_op_subl_T0_T1_cc();
7957 if (s->condexec_mask)
7958 gen_op_addl_T0_T1();
7960 gen_op_addl_T0_T1_cc();
7963 if (s->condexec_mask)
7964 gen_op_subl_T0_T1();
7966 gen_op_subl_T0_T1_cc();
7970 gen_movl_reg_T0(s, rd);
7973 if (insn & (1 << 11)) {
7974 rd = (insn >> 8) & 7;
7975 /* load pc-relative. Bit 1 of PC is ignored. */
7976 val = s->pc + 2 + ((insn & 0xff) * 4);
7977 val &= ~(uint32_t)2;
7979 tcg_gen_movi_i32(addr, val);
7980 tmp = gen_ld32(addr, IS_USER(s));
7982 store_reg(s, rd, tmp);
7985 if (insn & (1 << 10)) {
7986 /* data processing extended or blx */
7987 rd = (insn & 7) | ((insn >> 4) & 8);
7988 rm = (insn >> 3) & 0xf;
7989 op = (insn >> 8) & 3;
7992 gen_movl_T0_reg(s, rd);
7993 gen_movl_T1_reg(s, rm);
7994 gen_op_addl_T0_T1();
7995 gen_movl_reg_T0(s, rd);
7998 gen_movl_T0_reg(s, rd);
7999 gen_movl_T1_reg(s, rm);
8000 gen_op_subl_T0_T1_cc();
8002 case 2: /* mov/cpy */
8003 gen_movl_T0_reg(s, rm);
8004 gen_movl_reg_T0(s, rd);
8006 case 3:/* branch [and link] exchange thumb register */
8007 tmp = load_reg(s, rm);
8008 if (insn & (1 << 7)) {
8009 val = (uint32_t)s->pc | 1;
8011 tcg_gen_movi_i32(tmp2, val);
8012 store_reg(s, 14, tmp2);
8020 /* data processing register */
8022 rm = (insn >> 3) & 7;
8023 op = (insn >> 6) & 0xf;
8024 if (op == 2 || op == 3 || op == 4 || op == 7) {
8025 /* the shift/rotate ops want the operands backwards */
8034 if (op == 9) /* neg */
8035 gen_op_movl_T0_im(0);
8036 else if (op != 0xf) /* mvn doesn't read its first operand */
8037 gen_movl_T0_reg(s, rd);
8039 gen_movl_T1_reg(s, rm);
8042 gen_op_andl_T0_T1();
8043 if (!s->condexec_mask)
8044 gen_op_logic_T0_cc();
8047 gen_op_xorl_T0_T1();
8048 if (!s->condexec_mask)
8049 gen_op_logic_T0_cc();
8052 if (s->condexec_mask) {
8053 gen_helper_shl(cpu_T[1], cpu_T[1], cpu_T[0]);
8055 gen_helper_shl_cc(cpu_T[1], cpu_T[1], cpu_T[0]);
8056 gen_op_logic_T1_cc();
8060 if (s->condexec_mask) {
8061 gen_helper_shr(cpu_T[1], cpu_T[1], cpu_T[0]);
8063 gen_helper_shr_cc(cpu_T[1], cpu_T[1], cpu_T[0]);
8064 gen_op_logic_T1_cc();
8068 if (s->condexec_mask) {
8069 gen_helper_sar(cpu_T[1], cpu_T[1], cpu_T[0]);
8071 gen_helper_sar_cc(cpu_T[1], cpu_T[1], cpu_T[0]);
8072 gen_op_logic_T1_cc();
8076 if (s->condexec_mask)
8079 gen_op_adcl_T0_T1_cc();
8082 if (s->condexec_mask)
8085 gen_op_sbcl_T0_T1_cc();
8088 if (s->condexec_mask) {
8089 gen_helper_ror(cpu_T[1], cpu_T[1], cpu_T[0]);
8091 gen_helper_ror_cc(cpu_T[1], cpu_T[1], cpu_T[0]);
8092 gen_op_logic_T1_cc();
8096 gen_op_andl_T0_T1();
8097 gen_op_logic_T0_cc();
8101 if (s->condexec_mask)
8102 tcg_gen_neg_i32(cpu_T[0], cpu_T[1]);
8104 gen_op_subl_T0_T1_cc();
8107 gen_op_subl_T0_T1_cc();
8111 gen_op_addl_T0_T1_cc();
8116 if (!s->condexec_mask)
8117 gen_op_logic_T0_cc();
8120 gen_op_mull_T0_T1();
8121 if (!s->condexec_mask)
8122 gen_op_logic_T0_cc();
8125 gen_op_bicl_T0_T1();
8126 if (!s->condexec_mask)
8127 gen_op_logic_T0_cc();
8131 if (!s->condexec_mask)
8132 gen_op_logic_T1_cc();
8139 gen_movl_reg_T1(s, rm);
8141 gen_movl_reg_T0(s, rd);
8146 /* load/store register offset. */
8148 rn = (insn >> 3) & 7;
8149 rm = (insn >> 6) & 7;
8150 op = (insn >> 9) & 7;
8151 addr = load_reg(s, rn);
8152 tmp = load_reg(s, rm);
8153 tcg_gen_add_i32(addr, addr, tmp);
8156 if (op < 3) /* store */
8157 tmp = load_reg(s, rd);
8161 gen_st32(tmp, addr, IS_USER(s));
8164 gen_st16(tmp, addr, IS_USER(s));
8167 gen_st8(tmp, addr, IS_USER(s));
8170 tmp = gen_ld8s(addr, IS_USER(s));
8173 tmp = gen_ld32(addr, IS_USER(s));
8176 tmp = gen_ld16u(addr, IS_USER(s));
8179 tmp = gen_ld8u(addr, IS_USER(s));
8182 tmp = gen_ld16s(addr, IS_USER(s));
8185 if (op >= 3) /* load */
8186 store_reg(s, rd, tmp);
8191 /* load/store word immediate offset */
8193 rn = (insn >> 3) & 7;
8194 addr = load_reg(s, rn);
8195 val = (insn >> 4) & 0x7c;
8196 tcg_gen_addi_i32(addr, addr, val);
8198 if (insn & (1 << 11)) {
8200 tmp = gen_ld32(addr, IS_USER(s));
8201 store_reg(s, rd, tmp);
8204 tmp = load_reg(s, rd);
8205 gen_st32(tmp, addr, IS_USER(s));
8211 /* load/store byte immediate offset */
8213 rn = (insn >> 3) & 7;
8214 addr = load_reg(s, rn);
8215 val = (insn >> 6) & 0x1f;
8216 tcg_gen_addi_i32(addr, addr, val);
8218 if (insn & (1 << 11)) {
8220 tmp = gen_ld8u(addr, IS_USER(s));
8221 store_reg(s, rd, tmp);
8224 tmp = load_reg(s, rd);
8225 gen_st8(tmp, addr, IS_USER(s));
8231 /* load/store halfword immediate offset */
8233 rn = (insn >> 3) & 7;
8234 addr = load_reg(s, rn);
8235 val = (insn >> 5) & 0x3e;
8236 tcg_gen_addi_i32(addr, addr, val);
8238 if (insn & (1 << 11)) {
8240 tmp = gen_ld16u(addr, IS_USER(s));
8241 store_reg(s, rd, tmp);
8244 tmp = load_reg(s, rd);
8245 gen_st16(tmp, addr, IS_USER(s));
8251 /* load/store from stack */
8252 rd = (insn >> 8) & 7;
8253 addr = load_reg(s, 13);
8254 val = (insn & 0xff) * 4;
8255 tcg_gen_addi_i32(addr, addr, val);
8257 if (insn & (1 << 11)) {
8259 tmp = gen_ld32(addr, IS_USER(s));
8260 store_reg(s, rd, tmp);
8263 tmp = load_reg(s, rd);
8264 gen_st32(tmp, addr, IS_USER(s));
8270 /* add to high reg */
8271 rd = (insn >> 8) & 7;
8272 if (insn & (1 << 11)) {
8274 tmp = load_reg(s, 13);
8276 /* PC. bit 1 is ignored. */
8278 tcg_gen_movi_i32(tmp, (s->pc + 2) & ~(uint32_t)2);
8280 val = (insn & 0xff) * 4;
8281 tcg_gen_addi_i32(tmp, tmp, val);
8282 store_reg(s, rd, tmp);
8287 op = (insn >> 8) & 0xf;
8290 /* adjust stack pointer */
8291 tmp = load_reg(s, 13);
8292 val = (insn & 0x7f) * 4;
8293 if (insn & (1 << 7))
8294 val = -(int32_t)val;
8295 tcg_gen_addi_i32(tmp, tmp, val);
8296 store_reg(s, 13, tmp);
8299 case 2: /* sign/zero extend. */
8302 rm = (insn >> 3) & 7;
8303 tmp = load_reg(s, rm);
8304 switch ((insn >> 6) & 3) {
8305 case 0: gen_sxth(tmp); break;
8306 case 1: gen_sxtb(tmp); break;
8307 case 2: gen_uxth(tmp); break;
8308 case 3: gen_uxtb(tmp); break;
8310 store_reg(s, rd, tmp);
8312 case 4: case 5: case 0xc: case 0xd:
8314 addr = load_reg(s, 13);
8315 if (insn & (1 << 8))
8319 for (i = 0; i < 8; i++) {
8320 if (insn & (1 << i))
8323 if ((insn & (1 << 11)) == 0) {
8324 tcg_gen_addi_i32(addr, addr, -offset);
8326 for (i = 0; i < 8; i++) {
8327 if (insn & (1 << i)) {
8328 if (insn & (1 << 11)) {
8330 tmp = gen_ld32(addr, IS_USER(s));
8331 store_reg(s, i, tmp);
8334 tmp = load_reg(s, i);
8335 gen_st32(tmp, addr, IS_USER(s));
8337 /* advance to the next address. */
8338 tcg_gen_addi_i32(addr, addr, 4);
8341 if (insn & (1 << 8)) {
8342 if (insn & (1 << 11)) {
8344 tmp = gen_ld32(addr, IS_USER(s));
8345 /* don't set the pc until the rest of the instruction
8349 tmp = load_reg(s, 14);
8350 gen_st32(tmp, addr, IS_USER(s));
8352 tcg_gen_addi_i32(addr, addr, 4);
8354 if ((insn & (1 << 11)) == 0) {
8355 tcg_gen_addi_i32(addr, addr, -offset);
8357 /* write back the new stack pointer */
8358 store_reg(s, 13, addr);
8359 /* set the new PC value */
8360 if ((insn & 0x0900) == 0x0900)
8364 case 1: case 3: case 9: case 11: /* czb */
8366 tmp = load_reg(s, rm);
8367 tmp2 = tcg_const_i32(0);
8368 s->condlabel = gen_new_label();
8370 if (insn & (1 << 11))
8371 tcg_gen_brcond_i32(TCG_COND_EQ, tmp, tmp2, s->condlabel);
8373 tcg_gen_brcond_i32(TCG_COND_NE, tmp, tmp2, 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;
8546 /* generate intermediate code */
8548 memset(temps, 0, sizeof(temps));
8554 gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
8556 dc->is_jmp = DISAS_NEXT;
8558 dc->singlestep_enabled = env->singlestep_enabled;
8560 dc->thumb = env->thumb;
8561 dc->condexec_mask = (env->condexec_bits & 0xf) << 1;
8562 dc->condexec_cond = env->condexec_bits >> 4;
8564 #if !defined(CONFIG_USER_ONLY)
8566 dc->user = ((env->v7m.exception == 0) && (env->v7m.control & 1));
8568 dc->user = (env->uncached_cpsr & 0x1f) == ARM_CPU_MODE_USR;
8571 cpu_F0s = tcg_temp_new(TCG_TYPE_I32);
8572 cpu_F1s = tcg_temp_new(TCG_TYPE_I32);
8573 cpu_F0d = tcg_temp_new(TCG_TYPE_I64);
8574 cpu_F1d = tcg_temp_new(TCG_TYPE_I64);
8577 /* FIXME: cpu_M0 can probably be the same as cpu_V0. */
8578 cpu_M0 = tcg_temp_new(TCG_TYPE_I64);
8579 next_page_start = (pc_start & TARGET_PAGE_MASK) + TARGET_PAGE_SIZE;
8581 /* Reset the conditional execution bits immediately. This avoids
8582 complications trying to do it at the end of the block. */
8583 if (env->condexec_bits)
8585 TCGv tmp = new_tmp();
8586 tcg_gen_movi_i32(tmp, 0);
8587 store_cpu_field(tmp, condexec_bits);
8590 #ifndef CONFIG_USER_ONLY
8591 if (dc->pc >= 0xfffffff0 && IS_M(env)) {
8592 /* We always get here via a jump, so know we are not in a
8593 conditional execution block. */
8594 gen_exception(EXCP_EXCEPTION_EXIT);
8598 if (env->nb_breakpoints > 0) {
8599 for(j = 0; j < env->nb_breakpoints; j++) {
8600 if (env->breakpoints[j] == dc->pc) {
8601 gen_set_condexec(dc);
8602 gen_set_pc_im(dc->pc);
8603 gen_exception(EXCP_DEBUG);
8604 dc->is_jmp = DISAS_JUMP;
8605 /* Advance PC so that clearing the breakpoint will
8606 invalidate this TB. */
8608 goto done_generating;
8614 j = gen_opc_ptr - gen_opc_buf;
8618 gen_opc_instr_start[lj++] = 0;
8620 gen_opc_pc[lj] = dc->pc;
8621 gen_opc_instr_start[lj] = 1;
8625 disas_thumb_insn(env, dc);
8626 if (dc->condexec_mask) {
8627 dc->condexec_cond = (dc->condexec_cond & 0xe)
8628 | ((dc->condexec_mask >> 4) & 1);
8629 dc->condexec_mask = (dc->condexec_mask << 1) & 0x1f;
8630 if (dc->condexec_mask == 0) {
8631 dc->condexec_cond = 0;
8635 disas_arm_insn(env, dc);
8638 fprintf(stderr, "Internal resource leak before %08x\n", dc->pc);
8642 if (dc->condjmp && !dc->is_jmp) {
8643 gen_set_label(dc->condlabel);
8646 /* Terminate the TB on memory ops if watchpoints are present. */
8647 /* FIXME: This should be replacd by the deterministic execution
8648 * IRQ raising bits. */
8649 if (dc->is_mem && env->nb_watchpoints)
8652 /* Translation stops when a conditional branch is enoutered.
8653 * Otherwise the subsequent code could get translated several times.
8654 * Also stop translation when a page boundary is reached. This
8655 * ensures prefech aborts occur at the right place. */
8656 } while (!dc->is_jmp && gen_opc_ptr < gen_opc_end &&
8657 !env->singlestep_enabled &&
8658 dc->pc < next_page_start);
8660 /* At this stage dc->condjmp will only be set when the skipped
8661 instruction was a conditional branch or trap, and the PC has
8662 already been written. */
8663 if (__builtin_expect(env->singlestep_enabled, 0)) {
8664 /* Make sure the pc is updated, and raise a debug exception. */
8666 gen_set_condexec(dc);
8667 if (dc->is_jmp == DISAS_SWI) {
8668 gen_exception(EXCP_SWI);
8670 gen_exception(EXCP_DEBUG);
8672 gen_set_label(dc->condlabel);
8674 if (dc->condjmp || !dc->is_jmp) {
8675 gen_set_pc_im(dc->pc);
8678 gen_set_condexec(dc);
8679 if (dc->is_jmp == DISAS_SWI && !dc->condjmp) {
8680 gen_exception(EXCP_SWI);
8682 /* FIXME: Single stepping a WFI insn will not halt
8684 gen_exception(EXCP_DEBUG);
8687 /* While branches must always occur at the end of an IT block,
8688 there are a few other things that can cause us to terminate
8689 the TB in the middel of an IT block:
8690 - Exception generating instructions (bkpt, swi, undefined).
8692 - Hardware watchpoints.
8693 Hardware breakpoints have already been handled and skip this code.
8695 gen_set_condexec(dc);
8696 switch(dc->is_jmp) {
8698 gen_goto_tb(dc, 1, dc->pc);
8703 /* indicate that the hash table must be used to find the next TB */
8707 /* nothing more to generate */
8713 gen_exception(EXCP_SWI);
8717 gen_set_label(dc->condlabel);
8718 gen_set_condexec(dc);
8719 gen_goto_tb(dc, 1, dc->pc);
8724 *gen_opc_ptr = INDEX_op_end;
8727 if (loglevel & CPU_LOG_TB_IN_ASM) {
8728 fprintf(logfile, "----------------\n");
8729 fprintf(logfile, "IN: %s\n", lookup_symbol(pc_start));
8730 target_disas(logfile, pc_start, dc->pc - pc_start, env->thumb);
8731 fprintf(logfile, "\n");
8735 j = gen_opc_ptr - gen_opc_buf;
8738 gen_opc_instr_start[lj++] = 0;
8740 tb->size = dc->pc - pc_start;
8745 int gen_intermediate_code(CPUState *env, TranslationBlock *tb)
8747 return gen_intermediate_code_internal(env, tb, 0);
8750 int gen_intermediate_code_pc(CPUState *env, TranslationBlock *tb)
8752 return gen_intermediate_code_internal(env, tb, 1);
8755 static const char *cpu_mode_names[16] = {
8756 "usr", "fiq", "irq", "svc", "???", "???", "???", "abt",
8757 "???", "???", "???", "und", "???", "???", "???", "sys"
8760 void cpu_dump_state(CPUState *env, FILE *f,
8761 int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
8770 /* ??? This assumes float64 and double have the same layout.
8771 Oh well, it's only debug dumps. */
8779 cpu_fprintf(f, "R%02d=%08x", i, env->regs[i]);
8781 cpu_fprintf(f, "\n");
8783 cpu_fprintf(f, " ");
8785 psr = cpsr_read(env);
8786 cpu_fprintf(f, "PSR=%08x %c%c%c%c %c %s%d\n",
8788 psr & (1 << 31) ? 'N' : '-',
8789 psr & (1 << 30) ? 'Z' : '-',
8790 psr & (1 << 29) ? 'C' : '-',
8791 psr & (1 << 28) ? 'V' : '-',
8792 psr & CPSR_T ? 'T' : 'A',
8793 cpu_mode_names[psr & 0xf], (psr & 0x10) ? 32 : 26);
8796 for (i = 0; i < 16; i++) {
8797 d.d = env->vfp.regs[i];
8801 cpu_fprintf(f, "s%02d=%08x(%8g) s%02d=%08x(%8g) d%02d=%08x%08x(%8g)\n",
8802 i * 2, (int)s0.i, s0.s,
8803 i * 2 + 1, (int)s1.i, s1.s,
8804 i, (int)(uint32_t)d.l.upper, (int)(uint32_t)d.l.lower,
8807 cpu_fprintf(f, "FPSCR: %08x\n", (int)env->vfp.xregs[ARM_VFP_FPSCR]);
8811 void gen_pc_load(CPUState *env, TranslationBlock *tb,
8812 unsigned long searched_pc, int pc_pos, void *puc)
8814 env->regs[15] = gen_opc_pc[pc_pos];