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 /* FIXME: Implement this natively. */
455 static inline void tcg_gen_not_i32(TCGv t0, TCGv t1)
457 tcg_gen_xori_i32(t0, t1, ~0);
460 /* T0 &= ~T1. Clobbers T1. */
461 /* FIXME: Implement bic natively. */
462 static inline void tcg_gen_bic_i32(TCGv dest, TCGv t0, TCGv t1)
464 TCGv tmp = new_tmp();
465 tcg_gen_not_i32(tmp, t1);
466 tcg_gen_and_i32(dest, t0, tmp);
469 static inline void gen_op_bicl_T0_T1(void)
475 /* FIXME: Implement this natively. */
476 #define tcg_gen_abs_i32(t0, t1) gen_helper_abs(t0, t1)
478 /* FIXME: Implement this natively. */
479 static void tcg_gen_rori_i32(TCGv t0, TCGv t1, int i)
487 tcg_gen_shri_i32(tmp, t1, i);
488 tcg_gen_shli_i32(t1, t1, 32 - i);
489 tcg_gen_or_i32(t0, t1, tmp);
493 static void shifter_out_im(TCGv var, int shift)
495 TCGv tmp = new_tmp();
497 tcg_gen_andi_i32(tmp, var, 1);
499 tcg_gen_shri_i32(tmp, var, shift);
501 tcg_gen_andi_i32(tmp, tmp, 1);
507 /* Shift by immediate. Includes special handling for shift == 0. */
508 static inline void gen_arm_shift_im(TCGv var, int shiftop, int shift, int flags)
514 shifter_out_im(var, 32 - shift);
515 tcg_gen_shli_i32(var, var, shift);
521 tcg_gen_shri_i32(var, var, 31);
524 tcg_gen_movi_i32(var, 0);
527 shifter_out_im(var, shift - 1);
528 tcg_gen_shri_i32(var, var, shift);
535 shifter_out_im(var, shift - 1);
538 tcg_gen_sari_i32(var, var, shift);
540 case 3: /* ROR/RRX */
543 shifter_out_im(var, shift - 1);
544 tcg_gen_rori_i32(var, var, shift); break;
546 TCGv tmp = load_cpu_field(CF);
548 shifter_out_im(var, 0);
549 tcg_gen_shri_i32(var, var, 1);
550 tcg_gen_shli_i32(tmp, tmp, 31);
551 tcg_gen_or_i32(var, var, tmp);
557 static inline void gen_arm_shift_reg(TCGv var, int shiftop,
558 TCGv shift, int flags)
562 case 0: gen_helper_shl_cc(var, var, shift); break;
563 case 1: gen_helper_shr_cc(var, var, shift); break;
564 case 2: gen_helper_sar_cc(var, var, shift); break;
565 case 3: gen_helper_ror_cc(var, var, shift); break;
569 case 0: gen_helper_shl(var, var, shift); break;
570 case 1: gen_helper_shr(var, var, shift); break;
571 case 2: gen_helper_sar(var, var, shift); break;
572 case 3: gen_helper_ror(var, var, shift); break;
578 #define PAS_OP(pfx) \
580 case 0: gen_pas_helper(glue(pfx,add16)); break; \
581 case 1: gen_pas_helper(glue(pfx,addsubx)); break; \
582 case 2: gen_pas_helper(glue(pfx,subaddx)); break; \
583 case 3: gen_pas_helper(glue(pfx,sub16)); break; \
584 case 4: gen_pas_helper(glue(pfx,add8)); break; \
585 case 7: gen_pas_helper(glue(pfx,sub8)); break; \
587 static void gen_arm_parallel_addsub(int op1, int op2, TCGv a, TCGv b)
592 #define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b, tmp)
594 tmp = tcg_temp_new(TCG_TYPE_PTR);
595 tcg_gen_addi_ptr(tmp, cpu_env, offsetof(CPUState, GE));
599 tmp = tcg_temp_new(TCG_TYPE_PTR);
600 tcg_gen_addi_ptr(tmp, cpu_env, offsetof(CPUState, GE));
603 #undef gen_pas_helper
604 #define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b)
617 #undef gen_pas_helper
622 /* For unknown reasons Arm and Thumb-2 use arbitrarily different encodings. */
623 #define PAS_OP(pfx) \
625 case 0: gen_pas_helper(glue(pfx,add8)); break; \
626 case 1: gen_pas_helper(glue(pfx,add16)); break; \
627 case 2: gen_pas_helper(glue(pfx,addsubx)); break; \
628 case 4: gen_pas_helper(glue(pfx,sub8)); break; \
629 case 5: gen_pas_helper(glue(pfx,sub16)); break; \
630 case 6: gen_pas_helper(glue(pfx,subaddx)); break; \
632 static void gen_thumb2_parallel_addsub(int op1, int op2, TCGv a, TCGv b)
637 #define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b, tmp)
639 tmp = tcg_temp_new(TCG_TYPE_PTR);
640 tcg_gen_addi_ptr(tmp, cpu_env, offsetof(CPUState, GE));
644 tmp = tcg_temp_new(TCG_TYPE_PTR);
645 tcg_gen_addi_ptr(tmp, cpu_env, offsetof(CPUState, GE));
648 #undef gen_pas_helper
649 #define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b)
662 #undef gen_pas_helper
667 static void gen_test_cc(int cc, int label)
674 zero = tcg_const_i32(0);
677 tmp = load_cpu_field(ZF);
678 tcg_gen_brcond_i32(TCG_COND_EQ, tmp, zero, label);
681 tmp = load_cpu_field(ZF);
682 tcg_gen_brcond_i32(TCG_COND_NE, tmp, zero, label);
685 tmp = load_cpu_field(CF);
686 tcg_gen_brcond_i32(TCG_COND_NE, tmp, zero, label);
689 tmp = load_cpu_field(CF);
690 tcg_gen_brcond_i32(TCG_COND_EQ, tmp, zero, label);
693 tmp = load_cpu_field(NF);
694 tcg_gen_brcond_i32(TCG_COND_LT, tmp, zero, label);
697 tmp = load_cpu_field(NF);
698 tcg_gen_brcond_i32(TCG_COND_GE, tmp, zero, label);
701 tmp = load_cpu_field(VF);
702 tcg_gen_brcond_i32(TCG_COND_LT, tmp, zero, label);
705 tmp = load_cpu_field(VF);
706 tcg_gen_brcond_i32(TCG_COND_GE, tmp, zero, label);
708 case 8: /* hi: C && !Z */
709 inv = gen_new_label();
710 tmp = load_cpu_field(CF);
711 tcg_gen_brcond_i32(TCG_COND_EQ, tmp, zero, inv);
713 tmp = load_cpu_field(ZF);
714 tcg_gen_brcond_i32(TCG_COND_NE, tmp, zero, label);
717 case 9: /* ls: !C || Z */
718 tmp = load_cpu_field(CF);
719 tcg_gen_brcond_i32(TCG_COND_EQ, tmp, zero, label);
721 tmp = load_cpu_field(ZF);
722 tcg_gen_brcond_i32(TCG_COND_EQ, tmp, zero, label);
724 case 10: /* ge: N == V -> N ^ V == 0 */
725 tmp = load_cpu_field(VF);
726 tmp2 = load_cpu_field(NF);
727 tcg_gen_xor_i32(tmp, tmp, tmp2);
729 tcg_gen_brcond_i32(TCG_COND_GE, tmp, zero, label);
731 case 11: /* lt: N != V -> N ^ V != 0 */
732 tmp = load_cpu_field(VF);
733 tmp2 = load_cpu_field(NF);
734 tcg_gen_xor_i32(tmp, tmp, tmp2);
736 tcg_gen_brcond_i32(TCG_COND_LT, tmp, zero, label);
738 case 12: /* gt: !Z && N == V */
739 inv = gen_new_label();
740 tmp = load_cpu_field(ZF);
741 tcg_gen_brcond_i32(TCG_COND_EQ, tmp, zero, inv);
743 tmp = load_cpu_field(VF);
744 tmp2 = load_cpu_field(NF);
745 tcg_gen_xor_i32(tmp, tmp, tmp2);
747 tcg_gen_brcond_i32(TCG_COND_GE, tmp, zero, label);
750 case 13: /* le: Z || N != V */
751 tmp = load_cpu_field(ZF);
752 tcg_gen_brcond_i32(TCG_COND_EQ, tmp, zero, label);
754 tmp = load_cpu_field(VF);
755 tmp2 = load_cpu_field(NF);
756 tcg_gen_xor_i32(tmp, tmp, tmp2);
758 tcg_gen_brcond_i32(TCG_COND_LT, tmp, zero, label);
761 fprintf(stderr, "Bad condition code 0x%x\n", cc);
767 const uint8_t table_logic_cc[16] = {
786 /* Set PC and Thumb state from an immediate address. */
787 static inline void gen_bx_im(DisasContext *s, uint32_t addr)
791 s->is_jmp = DISAS_UPDATE;
793 if (s->thumb != (addr & 1)) {
794 tcg_gen_movi_i32(tmp, addr & 1);
795 tcg_gen_st_i32(tmp, cpu_env, offsetof(CPUState, thumb));
797 tcg_gen_movi_i32(tmp, addr & ~1);
798 tcg_gen_st_i32(tmp, cpu_env, offsetof(CPUState, regs[15]));
802 /* Set PC and Thumb state from var. var is marked as dead. */
803 static inline void gen_bx(DisasContext *s, TCGv var)
807 s->is_jmp = DISAS_UPDATE;
809 tcg_gen_andi_i32(tmp, var, 1);
810 store_cpu_field(tmp, thumb);
811 tcg_gen_andi_i32(var, var, ~1);
812 store_cpu_field(var, regs[15]);
815 /* TODO: This should be removed. Use gen_bx instead. */
816 static inline void gen_bx_T0(DisasContext *s)
818 TCGv tmp = new_tmp();
819 tcg_gen_mov_i32(tmp, cpu_T[0]);
823 #if defined(CONFIG_USER_ONLY)
824 #define gen_ldst(name, s) gen_op_##name##_raw()
826 #define gen_ldst(name, s) do { \
829 gen_op_##name##_user(); \
831 gen_op_##name##_kernel(); \
834 static inline TCGv gen_ld8s(TCGv addr, int index)
836 TCGv tmp = new_tmp();
837 tcg_gen_qemu_ld8s(tmp, addr, index);
840 static inline TCGv gen_ld8u(TCGv addr, int index)
842 TCGv tmp = new_tmp();
843 tcg_gen_qemu_ld8u(tmp, addr, index);
846 static inline TCGv gen_ld16s(TCGv addr, int index)
848 TCGv tmp = new_tmp();
849 tcg_gen_qemu_ld16s(tmp, addr, index);
852 static inline TCGv gen_ld16u(TCGv addr, int index)
854 TCGv tmp = new_tmp();
855 tcg_gen_qemu_ld16u(tmp, addr, index);
858 static inline TCGv gen_ld32(TCGv addr, int index)
860 TCGv tmp = new_tmp();
861 tcg_gen_qemu_ld32u(tmp, addr, index);
864 static inline void gen_st8(TCGv val, TCGv addr, int index)
866 tcg_gen_qemu_st8(val, addr, index);
869 static inline void gen_st16(TCGv val, TCGv addr, int index)
871 tcg_gen_qemu_st16(val, addr, index);
874 static inline void gen_st32(TCGv val, TCGv addr, int index)
876 tcg_gen_qemu_st32(val, addr, index);
880 static inline void gen_movl_T0_reg(DisasContext *s, int reg)
882 load_reg_var(s, cpu_T[0], reg);
885 static inline void gen_movl_T1_reg(DisasContext *s, int reg)
887 load_reg_var(s, cpu_T[1], reg);
890 static inline void gen_movl_T2_reg(DisasContext *s, int reg)
892 load_reg_var(s, cpu_T[2], reg);
895 static inline void gen_set_pc_im(uint32_t val)
897 TCGv tmp = new_tmp();
898 tcg_gen_movi_i32(tmp, val);
899 store_cpu_field(tmp, regs[15]);
902 static inline void gen_movl_reg_TN(DisasContext *s, int reg, int t)
907 tcg_gen_andi_i32(tmp, cpu_T[t], ~1);
911 tcg_gen_st_i32(tmp, cpu_env, offsetof(CPUState, regs[reg]));
914 s->is_jmp = DISAS_JUMP;
918 static inline void gen_movl_reg_T0(DisasContext *s, int reg)
920 gen_movl_reg_TN(s, reg, 0);
923 static inline void gen_movl_reg_T1(DisasContext *s, int reg)
925 gen_movl_reg_TN(s, reg, 1);
928 /* Force a TB lookup after an instruction that changes the CPU state. */
929 static inline void gen_lookup_tb(DisasContext *s)
931 gen_op_movl_T0_im(s->pc);
932 gen_movl_reg_T0(s, 15);
933 s->is_jmp = DISAS_UPDATE;
936 static inline void gen_add_data_offset(DisasContext *s, unsigned int insn,
939 int val, rm, shift, shiftop;
942 if (!(insn & (1 << 25))) {
945 if (!(insn & (1 << 23)))
948 tcg_gen_addi_i32(var, var, val);
952 shift = (insn >> 7) & 0x1f;
953 shiftop = (insn >> 5) & 3;
954 offset = load_reg(s, rm);
955 gen_arm_shift_im(offset, shiftop, shift, 0);
956 if (!(insn & (1 << 23)))
957 tcg_gen_sub_i32(var, var, offset);
959 tcg_gen_add_i32(var, var, offset);
964 static inline void gen_add_datah_offset(DisasContext *s, unsigned int insn,
970 if (insn & (1 << 22)) {
972 val = (insn & 0xf) | ((insn >> 4) & 0xf0);
973 if (!(insn & (1 << 23)))
977 tcg_gen_addi_i32(var, var, val);
981 tcg_gen_addi_i32(var, var, extra);
983 offset = load_reg(s, rm);
984 if (!(insn & (1 << 23)))
985 tcg_gen_sub_i32(var, var, offset);
987 tcg_gen_add_i32(var, var, offset);
992 #define VFP_OP2(name) \
993 static inline void gen_vfp_##name(int dp) \
996 gen_helper_vfp_##name##d(cpu_F0d, cpu_F0d, cpu_F1d, cpu_env); \
998 gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, cpu_F1s, cpu_env); \
1001 #define VFP_OP1(name) \
1002 static inline void gen_vfp_##name(int dp, int arg) \
1005 gen_op_vfp_##name##d(arg); \
1007 gen_op_vfp_##name##s(arg); \
1017 static inline void gen_vfp_abs(int dp)
1020 gen_helper_vfp_absd(cpu_F0d, cpu_F0d);
1022 gen_helper_vfp_abss(cpu_F0s, cpu_F0s);
1025 static inline void gen_vfp_neg(int dp)
1028 gen_helper_vfp_negd(cpu_F0d, cpu_F0d);
1030 gen_helper_vfp_negs(cpu_F0s, cpu_F0s);
1033 static inline void gen_vfp_sqrt(int dp)
1036 gen_helper_vfp_sqrtd(cpu_F0d, cpu_F0d, cpu_env);
1038 gen_helper_vfp_sqrts(cpu_F0s, cpu_F0s, cpu_env);
1041 static inline void gen_vfp_cmp(int dp)
1044 gen_helper_vfp_cmpd(cpu_F0d, cpu_F1d, cpu_env);
1046 gen_helper_vfp_cmps(cpu_F0s, cpu_F1s, cpu_env);
1049 static inline void gen_vfp_cmpe(int dp)
1052 gen_helper_vfp_cmped(cpu_F0d, cpu_F1d, cpu_env);
1054 gen_helper_vfp_cmpes(cpu_F0s, cpu_F1s, cpu_env);
1057 static inline void gen_vfp_F1_ld0(int dp)
1060 tcg_gen_movi_i64(cpu_F1d, 0);
1062 tcg_gen_movi_i32(cpu_F1s, 0);
1065 static inline void gen_vfp_uito(int dp)
1068 gen_helper_vfp_uitod(cpu_F0d, cpu_F0s, cpu_env);
1070 gen_helper_vfp_uitos(cpu_F0s, cpu_F0s, cpu_env);
1073 static inline void gen_vfp_sito(int dp)
1076 gen_helper_vfp_sitod(cpu_F0d, cpu_F0s, cpu_env);
1078 gen_helper_vfp_sitos(cpu_F0s, cpu_F0s, cpu_env);
1081 static inline void gen_vfp_toui(int dp)
1084 gen_helper_vfp_touid(cpu_F0s, cpu_F0d, cpu_env);
1086 gen_helper_vfp_touis(cpu_F0s, cpu_F0s, cpu_env);
1089 static inline void gen_vfp_touiz(int dp)
1092 gen_helper_vfp_touizd(cpu_F0s, cpu_F0d, cpu_env);
1094 gen_helper_vfp_touizs(cpu_F0s, cpu_F0s, cpu_env);
1097 static inline void gen_vfp_tosi(int dp)
1100 gen_helper_vfp_tosid(cpu_F0s, cpu_F0d, cpu_env);
1102 gen_helper_vfp_tosis(cpu_F0s, cpu_F0s, cpu_env);
1105 static inline void gen_vfp_tosiz(int dp)
1108 gen_helper_vfp_tosizd(cpu_F0s, cpu_F0d, cpu_env);
1110 gen_helper_vfp_tosizs(cpu_F0s, cpu_F0s, cpu_env);
1113 #define VFP_GEN_FIX(name) \
1114 static inline void gen_vfp_##name(int dp, int shift) \
1117 gen_helper_vfp_##name##d(cpu_F0d, cpu_F0d, tcg_const_i32(shift), cpu_env);\
1119 gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, tcg_const_i32(shift), cpu_env);\
1131 static inline void gen_vfp_ld(DisasContext *s, int dp)
1134 tcg_gen_qemu_ld64(cpu_F0d, cpu_T[1], IS_USER(s));
1136 tcg_gen_qemu_ld32u(cpu_F0s, cpu_T[1], IS_USER(s));
1139 static inline void gen_vfp_st(DisasContext *s, int dp)
1142 tcg_gen_qemu_st64(cpu_F0d, cpu_T[1], IS_USER(s));
1144 tcg_gen_qemu_st32(cpu_F0s, cpu_T[1], IS_USER(s));
1148 vfp_reg_offset (int dp, int reg)
1151 return offsetof(CPUARMState, vfp.regs[reg]);
1153 return offsetof(CPUARMState, vfp.regs[reg >> 1])
1154 + offsetof(CPU_DoubleU, l.upper);
1156 return offsetof(CPUARMState, vfp.regs[reg >> 1])
1157 + offsetof(CPU_DoubleU, l.lower);
1161 /* Return the offset of a 32-bit piece of a NEON register.
1162 zero is the least significant end of the register. */
1164 neon_reg_offset (int reg, int n)
1168 return vfp_reg_offset(0, sreg);
1171 /* FIXME: Remove these. */
1172 #define neon_T0 cpu_T[0]
1173 #define neon_T1 cpu_T[1]
1174 #define NEON_GET_REG(T, reg, n) \
1175 tcg_gen_ld_i32(neon_##T, cpu_env, neon_reg_offset(reg, n))
1176 #define NEON_SET_REG(T, reg, n) \
1177 tcg_gen_st_i32(neon_##T, cpu_env, neon_reg_offset(reg, n))
1179 static TCGv neon_load_reg(int reg, int pass)
1181 TCGv tmp = new_tmp();
1182 tcg_gen_ld_i32(tmp, cpu_env, neon_reg_offset(reg, pass));
1186 static void neon_store_reg(int reg, int pass, TCGv var)
1188 tcg_gen_st_i32(var, cpu_env, neon_reg_offset(reg, pass));
1192 static inline void neon_load_reg64(TCGv var, int reg)
1194 tcg_gen_ld_i64(var, cpu_env, vfp_reg_offset(1, reg));
1197 static inline void neon_store_reg64(TCGv var, int reg)
1199 tcg_gen_st_i64(var, cpu_env, vfp_reg_offset(1, reg));
1202 #define tcg_gen_ld_f32 tcg_gen_ld_i32
1203 #define tcg_gen_ld_f64 tcg_gen_ld_i64
1204 #define tcg_gen_st_f32 tcg_gen_st_i32
1205 #define tcg_gen_st_f64 tcg_gen_st_i64
1207 static inline void gen_mov_F0_vreg(int dp, int reg)
1210 tcg_gen_ld_f64(cpu_F0d, cpu_env, vfp_reg_offset(dp, reg));
1212 tcg_gen_ld_f32(cpu_F0s, cpu_env, vfp_reg_offset(dp, reg));
1215 static inline void gen_mov_F1_vreg(int dp, int reg)
1218 tcg_gen_ld_f64(cpu_F1d, cpu_env, vfp_reg_offset(dp, reg));
1220 tcg_gen_ld_f32(cpu_F1s, cpu_env, vfp_reg_offset(dp, reg));
1223 static inline void gen_mov_vreg_F0(int dp, int reg)
1226 tcg_gen_st_f64(cpu_F0d, cpu_env, vfp_reg_offset(dp, reg));
1228 tcg_gen_st_f32(cpu_F0s, cpu_env, vfp_reg_offset(dp, reg));
1231 #define ARM_CP_RW_BIT (1 << 20)
1233 static inline void iwmmxt_load_reg(TCGv var, int reg)
1235 tcg_gen_ld_i64(var, cpu_env, offsetof(CPUState, iwmmxt.regs[reg]));
1238 static inline void iwmmxt_store_reg(TCGv var, int reg)
1240 tcg_gen_st_i64(var, cpu_env, offsetof(CPUState, iwmmxt.regs[reg]));
1243 static inline void gen_op_iwmmxt_movl_wCx_T0(int reg)
1245 tcg_gen_st_i32(cpu_T[0], cpu_env, offsetof(CPUState, iwmmxt.cregs[reg]));
1248 static inline void gen_op_iwmmxt_movl_T0_wCx(int reg)
1250 tcg_gen_ld_i32(cpu_T[0], cpu_env, offsetof(CPUState, iwmmxt.cregs[reg]));
1253 static inline void gen_op_iwmmxt_movl_T1_wCx(int reg)
1255 tcg_gen_ld_i32(cpu_T[1], cpu_env, offsetof(CPUState, iwmmxt.cregs[reg]));
1258 static inline void gen_op_iwmmxt_movq_wRn_M0(int rn)
1260 iwmmxt_store_reg(cpu_M0, rn);
1263 static inline void gen_op_iwmmxt_movq_M0_wRn(int rn)
1265 iwmmxt_load_reg(cpu_M0, rn);
1268 static inline void gen_op_iwmmxt_orq_M0_wRn(int rn)
1270 iwmmxt_load_reg(cpu_V1, rn);
1271 tcg_gen_or_i64(cpu_M0, cpu_M0, cpu_V1);
1274 static inline void gen_op_iwmmxt_andq_M0_wRn(int rn)
1276 iwmmxt_load_reg(cpu_V1, rn);
1277 tcg_gen_and_i64(cpu_M0, cpu_M0, cpu_V1);
1280 static inline void gen_op_iwmmxt_xorq_M0_wRn(int rn)
1282 iwmmxt_load_reg(cpu_V1, rn);
1283 tcg_gen_xor_i64(cpu_M0, cpu_M0, cpu_V1);
1286 #define IWMMXT_OP(name) \
1287 static inline void gen_op_iwmmxt_##name##_M0_wRn(int rn) \
1289 iwmmxt_load_reg(cpu_V1, rn); \
1290 gen_helper_iwmmxt_##name(cpu_M0, cpu_M0, cpu_V1); \
1293 #define IWMMXT_OP_ENV(name) \
1294 static inline void gen_op_iwmmxt_##name##_M0_wRn(int rn) \
1296 iwmmxt_load_reg(cpu_V1, rn); \
1297 gen_helper_iwmmxt_##name(cpu_M0, cpu_env, cpu_M0, cpu_V1); \
1300 #define IWMMXT_OP_ENV_SIZE(name) \
1301 IWMMXT_OP_ENV(name##b) \
1302 IWMMXT_OP_ENV(name##w) \
1303 IWMMXT_OP_ENV(name##l)
1305 #define IWMMXT_OP_ENV1(name) \
1306 static inline void gen_op_iwmmxt_##name##_M0(void) \
1308 gen_helper_iwmmxt_##name(cpu_M0, cpu_env, cpu_M0); \
1322 IWMMXT_OP_ENV_SIZE(unpackl)
1323 IWMMXT_OP_ENV_SIZE(unpackh)
1325 IWMMXT_OP_ENV1(unpacklub)
1326 IWMMXT_OP_ENV1(unpackluw)
1327 IWMMXT_OP_ENV1(unpacklul)
1328 IWMMXT_OP_ENV1(unpackhub)
1329 IWMMXT_OP_ENV1(unpackhuw)
1330 IWMMXT_OP_ENV1(unpackhul)
1331 IWMMXT_OP_ENV1(unpacklsb)
1332 IWMMXT_OP_ENV1(unpacklsw)
1333 IWMMXT_OP_ENV1(unpacklsl)
1334 IWMMXT_OP_ENV1(unpackhsb)
1335 IWMMXT_OP_ENV1(unpackhsw)
1336 IWMMXT_OP_ENV1(unpackhsl)
1338 IWMMXT_OP_ENV_SIZE(cmpeq)
1339 IWMMXT_OP_ENV_SIZE(cmpgtu)
1340 IWMMXT_OP_ENV_SIZE(cmpgts)
1342 IWMMXT_OP_ENV_SIZE(mins)
1343 IWMMXT_OP_ENV_SIZE(minu)
1344 IWMMXT_OP_ENV_SIZE(maxs)
1345 IWMMXT_OP_ENV_SIZE(maxu)
1347 IWMMXT_OP_ENV_SIZE(subn)
1348 IWMMXT_OP_ENV_SIZE(addn)
1349 IWMMXT_OP_ENV_SIZE(subu)
1350 IWMMXT_OP_ENV_SIZE(addu)
1351 IWMMXT_OP_ENV_SIZE(subs)
1352 IWMMXT_OP_ENV_SIZE(adds)
1354 IWMMXT_OP_ENV(avgb0)
1355 IWMMXT_OP_ENV(avgb1)
1356 IWMMXT_OP_ENV(avgw0)
1357 IWMMXT_OP_ENV(avgw1)
1361 IWMMXT_OP_ENV(packuw)
1362 IWMMXT_OP_ENV(packul)
1363 IWMMXT_OP_ENV(packuq)
1364 IWMMXT_OP_ENV(packsw)
1365 IWMMXT_OP_ENV(packsl)
1366 IWMMXT_OP_ENV(packsq)
1368 static inline void gen_op_iwmmxt_muladdsl_M0_T0_T1(void)
1370 gen_helper_iwmmxt_muladdsl(cpu_M0, cpu_M0, cpu_T[0], cpu_T[1]);
1373 static inline void gen_op_iwmmxt_muladdsw_M0_T0_T1(void)
1375 gen_helper_iwmmxt_muladdsw(cpu_M0, cpu_M0, cpu_T[0], cpu_T[1]);
1378 static inline void gen_op_iwmmxt_muladdswl_M0_T0_T1(void)
1380 gen_helper_iwmmxt_muladdswl(cpu_M0, cpu_M0, cpu_T[0], cpu_T[1]);
1383 static inline void gen_op_iwmmxt_align_M0_T0_wRn(int rn)
1385 iwmmxt_load_reg(cpu_V1, rn);
1386 gen_helper_iwmmxt_align(cpu_M0, cpu_M0, cpu_V1, cpu_T[0]);
1389 static inline void gen_op_iwmmxt_insr_M0_T0_T1(int shift)
1391 TCGv tmp = tcg_const_i32(shift);
1392 gen_helper_iwmmxt_insr(cpu_M0, cpu_M0, cpu_T[0], cpu_T[1], tmp);
1395 static inline void gen_op_iwmmxt_extrsb_T0_M0(int shift)
1397 tcg_gen_shri_i64(cpu_M0, cpu_M0, shift);
1398 tcg_gen_trunc_i64_i32(cpu_T[0], cpu_M0);
1399 tcg_gen_ext8s_i32(cpu_T[0], cpu_T[0]);
1402 static inline void gen_op_iwmmxt_extrsw_T0_M0(int shift)
1404 tcg_gen_shri_i64(cpu_M0, cpu_M0, shift);
1405 tcg_gen_trunc_i64_i32(cpu_T[0], cpu_M0);
1406 tcg_gen_ext16s_i32(cpu_T[0], cpu_T[0]);
1409 static inline void gen_op_iwmmxt_extru_T0_M0(int shift, uint32_t mask)
1411 tcg_gen_shri_i64(cpu_M0, cpu_M0, shift);
1412 tcg_gen_trunc_i64_i32(cpu_T[0], cpu_M0);
1414 tcg_gen_andi_i32(cpu_T[0], cpu_T[0], mask);
1417 static void gen_op_iwmmxt_set_mup(void)
1420 tmp = load_cpu_field(iwmmxt.cregs[ARM_IWMMXT_wCon]);
1421 tcg_gen_ori_i32(tmp, tmp, 2);
1422 store_cpu_field(tmp, iwmmxt.cregs[ARM_IWMMXT_wCon]);
1425 static void gen_op_iwmmxt_set_cup(void)
1428 tmp = load_cpu_field(iwmmxt.cregs[ARM_IWMMXT_wCon]);
1429 tcg_gen_ori_i32(tmp, tmp, 1);
1430 store_cpu_field(tmp, iwmmxt.cregs[ARM_IWMMXT_wCon]);
1433 static void gen_op_iwmmxt_setpsr_nz(void)
1435 TCGv tmp = new_tmp();
1436 gen_helper_iwmmxt_setpsr_nz(tmp, cpu_M0);
1437 store_cpu_field(tmp, iwmmxt.cregs[ARM_IWMMXT_wCASF]);
1440 static inline void gen_op_iwmmxt_addl_M0_wRn(int rn)
1442 iwmmxt_load_reg(cpu_V1, rn);
1443 tcg_gen_ext32u_i64(cpu_V1, cpu_V1);
1444 tcg_gen_add_i64(cpu_M0, cpu_M0, cpu_V1);
1448 static void gen_iwmmxt_movl_T0_T1_wRn(int rn)
1450 iwmmxt_load_reg(cpu_V0, rn);
1451 tcg_gen_trunc_i64_i32(cpu_T[0], cpu_V0);
1452 tcg_gen_shri_i64(cpu_V0, cpu_V0, 32);
1453 tcg_gen_trunc_i64_i32(cpu_T[1], cpu_V0);
1456 static void gen_iwmmxt_movl_wRn_T0_T1(int rn)
1458 tcg_gen_extu_i32_i64(cpu_V0, cpu_T[0]);
1459 tcg_gen_extu_i32_i64(cpu_V1, cpu_T[0]);
1460 tcg_gen_shli_i64(cpu_V1, cpu_V1, 32);
1461 tcg_gen_or_i64(cpu_V0, cpu_V0, cpu_V1);
1462 iwmmxt_store_reg(cpu_V0, rn);
1465 static inline int gen_iwmmxt_address(DisasContext *s, uint32_t insn)
1470 rd = (insn >> 16) & 0xf;
1471 gen_movl_T1_reg(s, rd);
1473 offset = (insn & 0xff) << ((insn >> 7) & 2);
1474 if (insn & (1 << 24)) {
1476 if (insn & (1 << 23))
1477 gen_op_addl_T1_im(offset);
1479 gen_op_addl_T1_im(-offset);
1481 if (insn & (1 << 21))
1482 gen_movl_reg_T1(s, rd);
1483 } else if (insn & (1 << 21)) {
1485 if (insn & (1 << 23))
1486 gen_op_movl_T0_im(offset);
1488 gen_op_movl_T0_im(- offset);
1489 gen_op_addl_T0_T1();
1490 gen_movl_reg_T0(s, rd);
1491 } else if (!(insn & (1 << 23)))
1496 static inline int gen_iwmmxt_shift(uint32_t insn, uint32_t mask)
1498 int rd = (insn >> 0) & 0xf;
1500 if (insn & (1 << 8))
1501 if (rd < ARM_IWMMXT_wCGR0 || rd > ARM_IWMMXT_wCGR3)
1504 gen_op_iwmmxt_movl_T0_wCx(rd);
1506 gen_iwmmxt_movl_T0_T1_wRn(rd);
1508 gen_op_movl_T1_im(mask);
1509 gen_op_andl_T0_T1();
1513 /* Disassemble an iwMMXt instruction. Returns nonzero if an error occured
1514 (ie. an undefined instruction). */
1515 static int disas_iwmmxt_insn(CPUState *env, DisasContext *s, uint32_t insn)
1518 int rdhi, rdlo, rd0, rd1, i;
1521 if ((insn & 0x0e000e00) == 0x0c000000) {
1522 if ((insn & 0x0fe00ff0) == 0x0c400000) {
1524 rdlo = (insn >> 12) & 0xf;
1525 rdhi = (insn >> 16) & 0xf;
1526 if (insn & ARM_CP_RW_BIT) { /* TMRRC */
1527 gen_iwmmxt_movl_T0_T1_wRn(wrd);
1528 gen_movl_reg_T0(s, rdlo);
1529 gen_movl_reg_T1(s, rdhi);
1530 } else { /* TMCRR */
1531 gen_movl_T0_reg(s, rdlo);
1532 gen_movl_T1_reg(s, rdhi);
1533 gen_iwmmxt_movl_wRn_T0_T1(wrd);
1534 gen_op_iwmmxt_set_mup();
1539 wrd = (insn >> 12) & 0xf;
1540 if (gen_iwmmxt_address(s, insn))
1542 if (insn & ARM_CP_RW_BIT) {
1543 if ((insn >> 28) == 0xf) { /* WLDRW wCx */
1544 tmp = gen_ld32(cpu_T[1], IS_USER(s));
1545 tcg_gen_mov_i32(cpu_T[0], tmp);
1547 gen_op_iwmmxt_movl_wCx_T0(wrd);
1550 if (insn & (1 << 8)) {
1551 if (insn & (1 << 22)) { /* WLDRD */
1552 tcg_gen_qemu_ld64(cpu_M0, cpu_T[1], IS_USER(s));
1554 } else { /* WLDRW wRd */
1555 tmp = gen_ld32(cpu_T[1], IS_USER(s));
1558 if (insn & (1 << 22)) { /* WLDRH */
1559 tmp = gen_ld16u(cpu_T[1], IS_USER(s));
1560 } else { /* WLDRB */
1561 tmp = gen_ld8u(cpu_T[1], IS_USER(s));
1565 tcg_gen_extu_i32_i64(cpu_M0, tmp);
1568 gen_op_iwmmxt_movq_wRn_M0(wrd);
1571 if ((insn >> 28) == 0xf) { /* WSTRW wCx */
1572 gen_op_iwmmxt_movl_T0_wCx(wrd);
1574 tcg_gen_mov_i32(tmp, cpu_T[0]);
1575 gen_st32(tmp, cpu_T[1], IS_USER(s));
1577 gen_op_iwmmxt_movq_M0_wRn(wrd);
1579 if (insn & (1 << 8)) {
1580 if (insn & (1 << 22)) { /* WSTRD */
1582 tcg_gen_qemu_st64(cpu_M0, cpu_T[1], IS_USER(s));
1583 } else { /* WSTRW wRd */
1584 tcg_gen_trunc_i64_i32(tmp, cpu_M0);
1585 gen_st32(tmp, cpu_T[1], IS_USER(s));
1588 if (insn & (1 << 22)) { /* WSTRH */
1589 tcg_gen_trunc_i64_i32(tmp, cpu_M0);
1590 gen_st16(tmp, cpu_T[1], IS_USER(s));
1591 } else { /* WSTRB */
1592 tcg_gen_trunc_i64_i32(tmp, cpu_M0);
1593 gen_st8(tmp, cpu_T[1], IS_USER(s));
1601 if ((insn & 0x0f000000) != 0x0e000000)
1604 switch (((insn >> 12) & 0xf00) | ((insn >> 4) & 0xff)) {
1605 case 0x000: /* WOR */
1606 wrd = (insn >> 12) & 0xf;
1607 rd0 = (insn >> 0) & 0xf;
1608 rd1 = (insn >> 16) & 0xf;
1609 gen_op_iwmmxt_movq_M0_wRn(rd0);
1610 gen_op_iwmmxt_orq_M0_wRn(rd1);
1611 gen_op_iwmmxt_setpsr_nz();
1612 gen_op_iwmmxt_movq_wRn_M0(wrd);
1613 gen_op_iwmmxt_set_mup();
1614 gen_op_iwmmxt_set_cup();
1616 case 0x011: /* TMCR */
1619 rd = (insn >> 12) & 0xf;
1620 wrd = (insn >> 16) & 0xf;
1622 case ARM_IWMMXT_wCID:
1623 case ARM_IWMMXT_wCASF:
1625 case ARM_IWMMXT_wCon:
1626 gen_op_iwmmxt_set_cup();
1628 case ARM_IWMMXT_wCSSF:
1629 gen_op_iwmmxt_movl_T0_wCx(wrd);
1630 gen_movl_T1_reg(s, rd);
1631 gen_op_bicl_T0_T1();
1632 gen_op_iwmmxt_movl_wCx_T0(wrd);
1634 case ARM_IWMMXT_wCGR0:
1635 case ARM_IWMMXT_wCGR1:
1636 case ARM_IWMMXT_wCGR2:
1637 case ARM_IWMMXT_wCGR3:
1638 gen_op_iwmmxt_set_cup();
1639 gen_movl_reg_T0(s, rd);
1640 gen_op_iwmmxt_movl_wCx_T0(wrd);
1646 case 0x100: /* WXOR */
1647 wrd = (insn >> 12) & 0xf;
1648 rd0 = (insn >> 0) & 0xf;
1649 rd1 = (insn >> 16) & 0xf;
1650 gen_op_iwmmxt_movq_M0_wRn(rd0);
1651 gen_op_iwmmxt_xorq_M0_wRn(rd1);
1652 gen_op_iwmmxt_setpsr_nz();
1653 gen_op_iwmmxt_movq_wRn_M0(wrd);
1654 gen_op_iwmmxt_set_mup();
1655 gen_op_iwmmxt_set_cup();
1657 case 0x111: /* TMRC */
1660 rd = (insn >> 12) & 0xf;
1661 wrd = (insn >> 16) & 0xf;
1662 gen_op_iwmmxt_movl_T0_wCx(wrd);
1663 gen_movl_reg_T0(s, rd);
1665 case 0x300: /* WANDN */
1666 wrd = (insn >> 12) & 0xf;
1667 rd0 = (insn >> 0) & 0xf;
1668 rd1 = (insn >> 16) & 0xf;
1669 gen_op_iwmmxt_movq_M0_wRn(rd0);
1670 tcg_gen_neg_i64(cpu_M0, cpu_M0);
1671 gen_op_iwmmxt_andq_M0_wRn(rd1);
1672 gen_op_iwmmxt_setpsr_nz();
1673 gen_op_iwmmxt_movq_wRn_M0(wrd);
1674 gen_op_iwmmxt_set_mup();
1675 gen_op_iwmmxt_set_cup();
1677 case 0x200: /* WAND */
1678 wrd = (insn >> 12) & 0xf;
1679 rd0 = (insn >> 0) & 0xf;
1680 rd1 = (insn >> 16) & 0xf;
1681 gen_op_iwmmxt_movq_M0_wRn(rd0);
1682 gen_op_iwmmxt_andq_M0_wRn(rd1);
1683 gen_op_iwmmxt_setpsr_nz();
1684 gen_op_iwmmxt_movq_wRn_M0(wrd);
1685 gen_op_iwmmxt_set_mup();
1686 gen_op_iwmmxt_set_cup();
1688 case 0x810: case 0xa10: /* WMADD */
1689 wrd = (insn >> 12) & 0xf;
1690 rd0 = (insn >> 0) & 0xf;
1691 rd1 = (insn >> 16) & 0xf;
1692 gen_op_iwmmxt_movq_M0_wRn(rd0);
1693 if (insn & (1 << 21))
1694 gen_op_iwmmxt_maddsq_M0_wRn(rd1);
1696 gen_op_iwmmxt_madduq_M0_wRn(rd1);
1697 gen_op_iwmmxt_movq_wRn_M0(wrd);
1698 gen_op_iwmmxt_set_mup();
1700 case 0x10e: case 0x50e: case 0x90e: case 0xd0e: /* WUNPCKIL */
1701 wrd = (insn >> 12) & 0xf;
1702 rd0 = (insn >> 16) & 0xf;
1703 rd1 = (insn >> 0) & 0xf;
1704 gen_op_iwmmxt_movq_M0_wRn(rd0);
1705 switch ((insn >> 22) & 3) {
1707 gen_op_iwmmxt_unpacklb_M0_wRn(rd1);
1710 gen_op_iwmmxt_unpacklw_M0_wRn(rd1);
1713 gen_op_iwmmxt_unpackll_M0_wRn(rd1);
1718 gen_op_iwmmxt_movq_wRn_M0(wrd);
1719 gen_op_iwmmxt_set_mup();
1720 gen_op_iwmmxt_set_cup();
1722 case 0x10c: case 0x50c: case 0x90c: case 0xd0c: /* WUNPCKIH */
1723 wrd = (insn >> 12) & 0xf;
1724 rd0 = (insn >> 16) & 0xf;
1725 rd1 = (insn >> 0) & 0xf;
1726 gen_op_iwmmxt_movq_M0_wRn(rd0);
1727 switch ((insn >> 22) & 3) {
1729 gen_op_iwmmxt_unpackhb_M0_wRn(rd1);
1732 gen_op_iwmmxt_unpackhw_M0_wRn(rd1);
1735 gen_op_iwmmxt_unpackhl_M0_wRn(rd1);
1740 gen_op_iwmmxt_movq_wRn_M0(wrd);
1741 gen_op_iwmmxt_set_mup();
1742 gen_op_iwmmxt_set_cup();
1744 case 0x012: case 0x112: case 0x412: case 0x512: /* WSAD */
1745 wrd = (insn >> 12) & 0xf;
1746 rd0 = (insn >> 16) & 0xf;
1747 rd1 = (insn >> 0) & 0xf;
1748 gen_op_iwmmxt_movq_M0_wRn(rd0);
1749 if (insn & (1 << 22))
1750 gen_op_iwmmxt_sadw_M0_wRn(rd1);
1752 gen_op_iwmmxt_sadb_M0_wRn(rd1);
1753 if (!(insn & (1 << 20)))
1754 gen_op_iwmmxt_addl_M0_wRn(wrd);
1755 gen_op_iwmmxt_movq_wRn_M0(wrd);
1756 gen_op_iwmmxt_set_mup();
1758 case 0x010: case 0x110: case 0x210: case 0x310: /* WMUL */
1759 wrd = (insn >> 12) & 0xf;
1760 rd0 = (insn >> 16) & 0xf;
1761 rd1 = (insn >> 0) & 0xf;
1762 gen_op_iwmmxt_movq_M0_wRn(rd0);
1763 if (insn & (1 << 21)) {
1764 if (insn & (1 << 20))
1765 gen_op_iwmmxt_mulshw_M0_wRn(rd1);
1767 gen_op_iwmmxt_mulslw_M0_wRn(rd1);
1769 if (insn & (1 << 20))
1770 gen_op_iwmmxt_muluhw_M0_wRn(rd1);
1772 gen_op_iwmmxt_mululw_M0_wRn(rd1);
1774 gen_op_iwmmxt_movq_wRn_M0(wrd);
1775 gen_op_iwmmxt_set_mup();
1777 case 0x410: case 0x510: case 0x610: case 0x710: /* WMAC */
1778 wrd = (insn >> 12) & 0xf;
1779 rd0 = (insn >> 16) & 0xf;
1780 rd1 = (insn >> 0) & 0xf;
1781 gen_op_iwmmxt_movq_M0_wRn(rd0);
1782 if (insn & (1 << 21))
1783 gen_op_iwmmxt_macsw_M0_wRn(rd1);
1785 gen_op_iwmmxt_macuw_M0_wRn(rd1);
1786 if (!(insn & (1 << 20))) {
1787 iwmmxt_load_reg(cpu_V1, wrd);
1788 tcg_gen_add_i64(cpu_M0, cpu_M0, cpu_V1);
1790 gen_op_iwmmxt_movq_wRn_M0(wrd);
1791 gen_op_iwmmxt_set_mup();
1793 case 0x006: case 0x406: case 0x806: case 0xc06: /* WCMPEQ */
1794 wrd = (insn >> 12) & 0xf;
1795 rd0 = (insn >> 16) & 0xf;
1796 rd1 = (insn >> 0) & 0xf;
1797 gen_op_iwmmxt_movq_M0_wRn(rd0);
1798 switch ((insn >> 22) & 3) {
1800 gen_op_iwmmxt_cmpeqb_M0_wRn(rd1);
1803 gen_op_iwmmxt_cmpeqw_M0_wRn(rd1);
1806 gen_op_iwmmxt_cmpeql_M0_wRn(rd1);
1811 gen_op_iwmmxt_movq_wRn_M0(wrd);
1812 gen_op_iwmmxt_set_mup();
1813 gen_op_iwmmxt_set_cup();
1815 case 0x800: case 0x900: case 0xc00: case 0xd00: /* WAVG2 */
1816 wrd = (insn >> 12) & 0xf;
1817 rd0 = (insn >> 16) & 0xf;
1818 rd1 = (insn >> 0) & 0xf;
1819 gen_op_iwmmxt_movq_M0_wRn(rd0);
1820 if (insn & (1 << 22)) {
1821 if (insn & (1 << 20))
1822 gen_op_iwmmxt_avgw1_M0_wRn(rd1);
1824 gen_op_iwmmxt_avgw0_M0_wRn(rd1);
1826 if (insn & (1 << 20))
1827 gen_op_iwmmxt_avgb1_M0_wRn(rd1);
1829 gen_op_iwmmxt_avgb0_M0_wRn(rd1);
1831 gen_op_iwmmxt_movq_wRn_M0(wrd);
1832 gen_op_iwmmxt_set_mup();
1833 gen_op_iwmmxt_set_cup();
1835 case 0x802: case 0x902: case 0xa02: case 0xb02: /* WALIGNR */
1836 wrd = (insn >> 12) & 0xf;
1837 rd0 = (insn >> 16) & 0xf;
1838 rd1 = (insn >> 0) & 0xf;
1839 gen_op_iwmmxt_movq_M0_wRn(rd0);
1840 gen_op_iwmmxt_movl_T0_wCx(ARM_IWMMXT_wCGR0 + ((insn >> 20) & 3));
1841 gen_op_movl_T1_im(7);
1842 gen_op_andl_T0_T1();
1843 gen_op_iwmmxt_align_M0_T0_wRn(rd1);
1844 gen_op_iwmmxt_movq_wRn_M0(wrd);
1845 gen_op_iwmmxt_set_mup();
1847 case 0x601: case 0x605: case 0x609: case 0x60d: /* TINSR */
1848 rd = (insn >> 12) & 0xf;
1849 wrd = (insn >> 16) & 0xf;
1850 gen_movl_T0_reg(s, rd);
1851 gen_op_iwmmxt_movq_M0_wRn(wrd);
1852 switch ((insn >> 6) & 3) {
1854 gen_op_movl_T1_im(0xff);
1855 gen_op_iwmmxt_insr_M0_T0_T1((insn & 7) << 3);
1858 gen_op_movl_T1_im(0xffff);
1859 gen_op_iwmmxt_insr_M0_T0_T1((insn & 3) << 4);
1862 gen_op_movl_T1_im(0xffffffff);
1863 gen_op_iwmmxt_insr_M0_T0_T1((insn & 1) << 5);
1868 gen_op_iwmmxt_movq_wRn_M0(wrd);
1869 gen_op_iwmmxt_set_mup();
1871 case 0x107: case 0x507: case 0x907: case 0xd07: /* TEXTRM */
1872 rd = (insn >> 12) & 0xf;
1873 wrd = (insn >> 16) & 0xf;
1876 gen_op_iwmmxt_movq_M0_wRn(wrd);
1877 switch ((insn >> 22) & 3) {
1880 gen_op_iwmmxt_extrsb_T0_M0((insn & 7) << 3);
1882 gen_op_iwmmxt_extru_T0_M0((insn & 7) << 3, 0xff);
1887 gen_op_iwmmxt_extrsw_T0_M0((insn & 3) << 4);
1889 gen_op_iwmmxt_extru_T0_M0((insn & 3) << 4, 0xffff);
1893 gen_op_iwmmxt_extru_T0_M0((insn & 1) << 5, ~0u);
1898 gen_movl_reg_T0(s, rd);
1900 case 0x117: case 0x517: case 0x917: case 0xd17: /* TEXTRC */
1901 if ((insn & 0x000ff008) != 0x0003f000)
1903 gen_op_iwmmxt_movl_T1_wCx(ARM_IWMMXT_wCASF);
1904 switch ((insn >> 22) & 3) {
1906 gen_op_shrl_T1_im(((insn & 7) << 2) + 0);
1909 gen_op_shrl_T1_im(((insn & 3) << 3) + 4);
1912 gen_op_shrl_T1_im(((insn & 1) << 4) + 12);
1917 gen_op_shll_T1_im(28);
1918 gen_set_nzcv(cpu_T[1]);
1920 case 0x401: case 0x405: case 0x409: case 0x40d: /* TBCST */
1921 rd = (insn >> 12) & 0xf;
1922 wrd = (insn >> 16) & 0xf;
1923 gen_movl_T0_reg(s, rd);
1924 switch ((insn >> 6) & 3) {
1926 gen_helper_iwmmxt_bcstb(cpu_M0, cpu_T[0]);
1929 gen_helper_iwmmxt_bcstw(cpu_M0, cpu_T[0]);
1932 gen_helper_iwmmxt_bcstl(cpu_M0, cpu_T[0]);
1937 gen_op_iwmmxt_movq_wRn_M0(wrd);
1938 gen_op_iwmmxt_set_mup();
1940 case 0x113: case 0x513: case 0x913: case 0xd13: /* TANDC */
1941 if ((insn & 0x000ff00f) != 0x0003f000)
1943 gen_op_iwmmxt_movl_T1_wCx(ARM_IWMMXT_wCASF);
1944 switch ((insn >> 22) & 3) {
1946 for (i = 0; i < 7; i ++) {
1947 gen_op_shll_T1_im(4);
1948 gen_op_andl_T0_T1();
1952 for (i = 0; i < 3; i ++) {
1953 gen_op_shll_T1_im(8);
1954 gen_op_andl_T0_T1();
1958 gen_op_shll_T1_im(16);
1959 gen_op_andl_T0_T1();
1964 gen_set_nzcv(cpu_T[0]);
1966 case 0x01c: case 0x41c: case 0x81c: case 0xc1c: /* WACC */
1967 wrd = (insn >> 12) & 0xf;
1968 rd0 = (insn >> 16) & 0xf;
1969 gen_op_iwmmxt_movq_M0_wRn(rd0);
1970 switch ((insn >> 22) & 3) {
1972 gen_helper_iwmmxt_addcb(cpu_M0, cpu_M0);
1975 gen_helper_iwmmxt_addcw(cpu_M0, cpu_M0);
1978 gen_helper_iwmmxt_addcl(cpu_M0, cpu_M0);
1983 gen_op_iwmmxt_movq_wRn_M0(wrd);
1984 gen_op_iwmmxt_set_mup();
1986 case 0x115: case 0x515: case 0x915: case 0xd15: /* TORC */
1987 if ((insn & 0x000ff00f) != 0x0003f000)
1989 gen_op_iwmmxt_movl_T1_wCx(ARM_IWMMXT_wCASF);
1990 switch ((insn >> 22) & 3) {
1992 for (i = 0; i < 7; i ++) {
1993 gen_op_shll_T1_im(4);
1998 for (i = 0; i < 3; i ++) {
1999 gen_op_shll_T1_im(8);
2004 gen_op_shll_T1_im(16);
2010 gen_set_nzcv(cpu_T[0]);
2012 case 0x103: case 0x503: case 0x903: case 0xd03: /* TMOVMSK */
2013 rd = (insn >> 12) & 0xf;
2014 rd0 = (insn >> 16) & 0xf;
2015 if ((insn & 0xf) != 0)
2017 gen_op_iwmmxt_movq_M0_wRn(rd0);
2018 switch ((insn >> 22) & 3) {
2020 gen_helper_iwmmxt_msbb(cpu_T[0], cpu_M0);
2023 gen_helper_iwmmxt_msbw(cpu_T[0], cpu_M0);
2026 gen_helper_iwmmxt_msbl(cpu_T[0], cpu_M0);
2031 gen_movl_reg_T0(s, rd);
2033 case 0x106: case 0x306: case 0x506: case 0x706: /* WCMPGT */
2034 case 0x906: case 0xb06: case 0xd06: case 0xf06:
2035 wrd = (insn >> 12) & 0xf;
2036 rd0 = (insn >> 16) & 0xf;
2037 rd1 = (insn >> 0) & 0xf;
2038 gen_op_iwmmxt_movq_M0_wRn(rd0);
2039 switch ((insn >> 22) & 3) {
2041 if (insn & (1 << 21))
2042 gen_op_iwmmxt_cmpgtsb_M0_wRn(rd1);
2044 gen_op_iwmmxt_cmpgtub_M0_wRn(rd1);
2047 if (insn & (1 << 21))
2048 gen_op_iwmmxt_cmpgtsw_M0_wRn(rd1);
2050 gen_op_iwmmxt_cmpgtuw_M0_wRn(rd1);
2053 if (insn & (1 << 21))
2054 gen_op_iwmmxt_cmpgtsl_M0_wRn(rd1);
2056 gen_op_iwmmxt_cmpgtul_M0_wRn(rd1);
2061 gen_op_iwmmxt_movq_wRn_M0(wrd);
2062 gen_op_iwmmxt_set_mup();
2063 gen_op_iwmmxt_set_cup();
2065 case 0x00e: case 0x20e: case 0x40e: case 0x60e: /* WUNPCKEL */
2066 case 0x80e: case 0xa0e: case 0xc0e: case 0xe0e:
2067 wrd = (insn >> 12) & 0xf;
2068 rd0 = (insn >> 16) & 0xf;
2069 gen_op_iwmmxt_movq_M0_wRn(rd0);
2070 switch ((insn >> 22) & 3) {
2072 if (insn & (1 << 21))
2073 gen_op_iwmmxt_unpacklsb_M0();
2075 gen_op_iwmmxt_unpacklub_M0();
2078 if (insn & (1 << 21))
2079 gen_op_iwmmxt_unpacklsw_M0();
2081 gen_op_iwmmxt_unpackluw_M0();
2084 if (insn & (1 << 21))
2085 gen_op_iwmmxt_unpacklsl_M0();
2087 gen_op_iwmmxt_unpacklul_M0();
2092 gen_op_iwmmxt_movq_wRn_M0(wrd);
2093 gen_op_iwmmxt_set_mup();
2094 gen_op_iwmmxt_set_cup();
2096 case 0x00c: case 0x20c: case 0x40c: case 0x60c: /* WUNPCKEH */
2097 case 0x80c: case 0xa0c: case 0xc0c: case 0xe0c:
2098 wrd = (insn >> 12) & 0xf;
2099 rd0 = (insn >> 16) & 0xf;
2100 gen_op_iwmmxt_movq_M0_wRn(rd0);
2101 switch ((insn >> 22) & 3) {
2103 if (insn & (1 << 21))
2104 gen_op_iwmmxt_unpackhsb_M0();
2106 gen_op_iwmmxt_unpackhub_M0();
2109 if (insn & (1 << 21))
2110 gen_op_iwmmxt_unpackhsw_M0();
2112 gen_op_iwmmxt_unpackhuw_M0();
2115 if (insn & (1 << 21))
2116 gen_op_iwmmxt_unpackhsl_M0();
2118 gen_op_iwmmxt_unpackhul_M0();
2123 gen_op_iwmmxt_movq_wRn_M0(wrd);
2124 gen_op_iwmmxt_set_mup();
2125 gen_op_iwmmxt_set_cup();
2127 case 0x204: case 0x604: case 0xa04: case 0xe04: /* WSRL */
2128 case 0x214: case 0x614: case 0xa14: case 0xe14:
2129 wrd = (insn >> 12) & 0xf;
2130 rd0 = (insn >> 16) & 0xf;
2131 gen_op_iwmmxt_movq_M0_wRn(rd0);
2132 if (gen_iwmmxt_shift(insn, 0xff))
2134 switch ((insn >> 22) & 3) {
2138 gen_helper_iwmmxt_srlw(cpu_M0, cpu_env, cpu_M0, cpu_T[0]);
2141 gen_helper_iwmmxt_srll(cpu_M0, cpu_env, cpu_M0, cpu_T[0]);
2144 gen_helper_iwmmxt_srlq(cpu_M0, cpu_env, cpu_M0, cpu_T[0]);
2147 gen_op_iwmmxt_movq_wRn_M0(wrd);
2148 gen_op_iwmmxt_set_mup();
2149 gen_op_iwmmxt_set_cup();
2151 case 0x004: case 0x404: case 0x804: case 0xc04: /* WSRA */
2152 case 0x014: case 0x414: case 0x814: case 0xc14:
2153 wrd = (insn >> 12) & 0xf;
2154 rd0 = (insn >> 16) & 0xf;
2155 gen_op_iwmmxt_movq_M0_wRn(rd0);
2156 if (gen_iwmmxt_shift(insn, 0xff))
2158 switch ((insn >> 22) & 3) {
2162 gen_helper_iwmmxt_sraw(cpu_M0, cpu_env, cpu_M0, cpu_T[0]);
2165 gen_helper_iwmmxt_sral(cpu_M0, cpu_env, cpu_M0, cpu_T[0]);
2168 gen_helper_iwmmxt_sraq(cpu_M0, cpu_env, cpu_M0, cpu_T[0]);
2171 gen_op_iwmmxt_movq_wRn_M0(wrd);
2172 gen_op_iwmmxt_set_mup();
2173 gen_op_iwmmxt_set_cup();
2175 case 0x104: case 0x504: case 0x904: case 0xd04: /* WSLL */
2176 case 0x114: case 0x514: case 0x914: case 0xd14:
2177 wrd = (insn >> 12) & 0xf;
2178 rd0 = (insn >> 16) & 0xf;
2179 gen_op_iwmmxt_movq_M0_wRn(rd0);
2180 if (gen_iwmmxt_shift(insn, 0xff))
2182 switch ((insn >> 22) & 3) {
2186 gen_helper_iwmmxt_sllw(cpu_M0, cpu_env, cpu_M0, cpu_T[0]);
2189 gen_helper_iwmmxt_slll(cpu_M0, cpu_env, cpu_M0, cpu_T[0]);
2192 gen_helper_iwmmxt_sllq(cpu_M0, cpu_env, cpu_M0, cpu_T[0]);
2195 gen_op_iwmmxt_movq_wRn_M0(wrd);
2196 gen_op_iwmmxt_set_mup();
2197 gen_op_iwmmxt_set_cup();
2199 case 0x304: case 0x704: case 0xb04: case 0xf04: /* WROR */
2200 case 0x314: case 0x714: case 0xb14: case 0xf14:
2201 wrd = (insn >> 12) & 0xf;
2202 rd0 = (insn >> 16) & 0xf;
2203 gen_op_iwmmxt_movq_M0_wRn(rd0);
2204 switch ((insn >> 22) & 3) {
2208 if (gen_iwmmxt_shift(insn, 0xf))
2210 gen_helper_iwmmxt_rorw(cpu_M0, cpu_env, cpu_M0, cpu_T[0]);
2213 if (gen_iwmmxt_shift(insn, 0x1f))
2215 gen_helper_iwmmxt_rorl(cpu_M0, cpu_env, cpu_M0, cpu_T[0]);
2218 if (gen_iwmmxt_shift(insn, 0x3f))
2220 gen_helper_iwmmxt_rorq(cpu_M0, cpu_env, cpu_M0, cpu_T[0]);
2223 gen_op_iwmmxt_movq_wRn_M0(wrd);
2224 gen_op_iwmmxt_set_mup();
2225 gen_op_iwmmxt_set_cup();
2227 case 0x116: case 0x316: case 0x516: case 0x716: /* WMIN */
2228 case 0x916: case 0xb16: case 0xd16: case 0xf16:
2229 wrd = (insn >> 12) & 0xf;
2230 rd0 = (insn >> 16) & 0xf;
2231 rd1 = (insn >> 0) & 0xf;
2232 gen_op_iwmmxt_movq_M0_wRn(rd0);
2233 switch ((insn >> 22) & 3) {
2235 if (insn & (1 << 21))
2236 gen_op_iwmmxt_minsb_M0_wRn(rd1);
2238 gen_op_iwmmxt_minub_M0_wRn(rd1);
2241 if (insn & (1 << 21))
2242 gen_op_iwmmxt_minsw_M0_wRn(rd1);
2244 gen_op_iwmmxt_minuw_M0_wRn(rd1);
2247 if (insn & (1 << 21))
2248 gen_op_iwmmxt_minsl_M0_wRn(rd1);
2250 gen_op_iwmmxt_minul_M0_wRn(rd1);
2255 gen_op_iwmmxt_movq_wRn_M0(wrd);
2256 gen_op_iwmmxt_set_mup();
2258 case 0x016: case 0x216: case 0x416: case 0x616: /* WMAX */
2259 case 0x816: case 0xa16: case 0xc16: case 0xe16:
2260 wrd = (insn >> 12) & 0xf;
2261 rd0 = (insn >> 16) & 0xf;
2262 rd1 = (insn >> 0) & 0xf;
2263 gen_op_iwmmxt_movq_M0_wRn(rd0);
2264 switch ((insn >> 22) & 3) {
2266 if (insn & (1 << 21))
2267 gen_op_iwmmxt_maxsb_M0_wRn(rd1);
2269 gen_op_iwmmxt_maxub_M0_wRn(rd1);
2272 if (insn & (1 << 21))
2273 gen_op_iwmmxt_maxsw_M0_wRn(rd1);
2275 gen_op_iwmmxt_maxuw_M0_wRn(rd1);
2278 if (insn & (1 << 21))
2279 gen_op_iwmmxt_maxsl_M0_wRn(rd1);
2281 gen_op_iwmmxt_maxul_M0_wRn(rd1);
2286 gen_op_iwmmxt_movq_wRn_M0(wrd);
2287 gen_op_iwmmxt_set_mup();
2289 case 0x002: case 0x102: case 0x202: case 0x302: /* WALIGNI */
2290 case 0x402: case 0x502: case 0x602: case 0x702:
2291 wrd = (insn >> 12) & 0xf;
2292 rd0 = (insn >> 16) & 0xf;
2293 rd1 = (insn >> 0) & 0xf;
2294 gen_op_iwmmxt_movq_M0_wRn(rd0);
2295 gen_op_movl_T0_im((insn >> 20) & 3);
2296 gen_op_iwmmxt_align_M0_T0_wRn(rd1);
2297 gen_op_iwmmxt_movq_wRn_M0(wrd);
2298 gen_op_iwmmxt_set_mup();
2300 case 0x01a: case 0x11a: case 0x21a: case 0x31a: /* WSUB */
2301 case 0x41a: case 0x51a: case 0x61a: case 0x71a:
2302 case 0x81a: case 0x91a: case 0xa1a: case 0xb1a:
2303 case 0xc1a: case 0xd1a: case 0xe1a: case 0xf1a:
2304 wrd = (insn >> 12) & 0xf;
2305 rd0 = (insn >> 16) & 0xf;
2306 rd1 = (insn >> 0) & 0xf;
2307 gen_op_iwmmxt_movq_M0_wRn(rd0);
2308 switch ((insn >> 20) & 0xf) {
2310 gen_op_iwmmxt_subnb_M0_wRn(rd1);
2313 gen_op_iwmmxt_subub_M0_wRn(rd1);
2316 gen_op_iwmmxt_subsb_M0_wRn(rd1);
2319 gen_op_iwmmxt_subnw_M0_wRn(rd1);
2322 gen_op_iwmmxt_subuw_M0_wRn(rd1);
2325 gen_op_iwmmxt_subsw_M0_wRn(rd1);
2328 gen_op_iwmmxt_subnl_M0_wRn(rd1);
2331 gen_op_iwmmxt_subul_M0_wRn(rd1);
2334 gen_op_iwmmxt_subsl_M0_wRn(rd1);
2339 gen_op_iwmmxt_movq_wRn_M0(wrd);
2340 gen_op_iwmmxt_set_mup();
2341 gen_op_iwmmxt_set_cup();
2343 case 0x01e: case 0x11e: case 0x21e: case 0x31e: /* WSHUFH */
2344 case 0x41e: case 0x51e: case 0x61e: case 0x71e:
2345 case 0x81e: case 0x91e: case 0xa1e: case 0xb1e:
2346 case 0xc1e: case 0xd1e: case 0xe1e: case 0xf1e:
2347 wrd = (insn >> 12) & 0xf;
2348 rd0 = (insn >> 16) & 0xf;
2349 gen_op_iwmmxt_movq_M0_wRn(rd0);
2350 gen_op_movl_T0_im(((insn >> 16) & 0xf0) | (insn & 0x0f));
2351 gen_helper_iwmmxt_shufh(cpu_M0, cpu_env, cpu_M0, cpu_T[0]);
2352 gen_op_iwmmxt_movq_wRn_M0(wrd);
2353 gen_op_iwmmxt_set_mup();
2354 gen_op_iwmmxt_set_cup();
2356 case 0x018: case 0x118: case 0x218: case 0x318: /* WADD */
2357 case 0x418: case 0x518: case 0x618: case 0x718:
2358 case 0x818: case 0x918: case 0xa18: case 0xb18:
2359 case 0xc18: case 0xd18: case 0xe18: case 0xf18:
2360 wrd = (insn >> 12) & 0xf;
2361 rd0 = (insn >> 16) & 0xf;
2362 rd1 = (insn >> 0) & 0xf;
2363 gen_op_iwmmxt_movq_M0_wRn(rd0);
2364 switch ((insn >> 20) & 0xf) {
2366 gen_op_iwmmxt_addnb_M0_wRn(rd1);
2369 gen_op_iwmmxt_addub_M0_wRn(rd1);
2372 gen_op_iwmmxt_addsb_M0_wRn(rd1);
2375 gen_op_iwmmxt_addnw_M0_wRn(rd1);
2378 gen_op_iwmmxt_adduw_M0_wRn(rd1);
2381 gen_op_iwmmxt_addsw_M0_wRn(rd1);
2384 gen_op_iwmmxt_addnl_M0_wRn(rd1);
2387 gen_op_iwmmxt_addul_M0_wRn(rd1);
2390 gen_op_iwmmxt_addsl_M0_wRn(rd1);
2395 gen_op_iwmmxt_movq_wRn_M0(wrd);
2396 gen_op_iwmmxt_set_mup();
2397 gen_op_iwmmxt_set_cup();
2399 case 0x008: case 0x108: case 0x208: case 0x308: /* WPACK */
2400 case 0x408: case 0x508: case 0x608: case 0x708:
2401 case 0x808: case 0x908: case 0xa08: case 0xb08:
2402 case 0xc08: case 0xd08: case 0xe08: case 0xf08:
2403 wrd = (insn >> 12) & 0xf;
2404 rd0 = (insn >> 16) & 0xf;
2405 rd1 = (insn >> 0) & 0xf;
2406 gen_op_iwmmxt_movq_M0_wRn(rd0);
2407 if (!(insn & (1 << 20)))
2409 switch ((insn >> 22) & 3) {
2413 if (insn & (1 << 21))
2414 gen_op_iwmmxt_packsw_M0_wRn(rd1);
2416 gen_op_iwmmxt_packuw_M0_wRn(rd1);
2419 if (insn & (1 << 21))
2420 gen_op_iwmmxt_packsl_M0_wRn(rd1);
2422 gen_op_iwmmxt_packul_M0_wRn(rd1);
2425 if (insn & (1 << 21))
2426 gen_op_iwmmxt_packsq_M0_wRn(rd1);
2428 gen_op_iwmmxt_packuq_M0_wRn(rd1);
2431 gen_op_iwmmxt_movq_wRn_M0(wrd);
2432 gen_op_iwmmxt_set_mup();
2433 gen_op_iwmmxt_set_cup();
2435 case 0x201: case 0x203: case 0x205: case 0x207:
2436 case 0x209: case 0x20b: case 0x20d: case 0x20f:
2437 case 0x211: case 0x213: case 0x215: case 0x217:
2438 case 0x219: case 0x21b: case 0x21d: case 0x21f:
2439 wrd = (insn >> 5) & 0xf;
2440 rd0 = (insn >> 12) & 0xf;
2441 rd1 = (insn >> 0) & 0xf;
2442 if (rd0 == 0xf || rd1 == 0xf)
2444 gen_op_iwmmxt_movq_M0_wRn(wrd);
2445 switch ((insn >> 16) & 0xf) {
2446 case 0x0: /* TMIA */
2447 gen_movl_T0_reg(s, rd0);
2448 gen_movl_T1_reg(s, rd1);
2449 gen_op_iwmmxt_muladdsl_M0_T0_T1();
2451 case 0x8: /* TMIAPH */
2452 gen_movl_T0_reg(s, rd0);
2453 gen_movl_T1_reg(s, rd1);
2454 gen_op_iwmmxt_muladdsw_M0_T0_T1();
2456 case 0xc: case 0xd: case 0xe: case 0xf: /* TMIAxy */
2457 gen_movl_T1_reg(s, rd0);
2458 if (insn & (1 << 16))
2459 gen_op_shrl_T1_im(16);
2460 gen_op_movl_T0_T1();
2461 gen_movl_T1_reg(s, rd1);
2462 if (insn & (1 << 17))
2463 gen_op_shrl_T1_im(16);
2464 gen_op_iwmmxt_muladdswl_M0_T0_T1();
2469 gen_op_iwmmxt_movq_wRn_M0(wrd);
2470 gen_op_iwmmxt_set_mup();
2479 /* Disassemble an XScale DSP instruction. Returns nonzero if an error occured
2480 (ie. an undefined instruction). */
2481 static int disas_dsp_insn(CPUState *env, DisasContext *s, uint32_t insn)
2483 int acc, rd0, rd1, rdhi, rdlo;
2485 if ((insn & 0x0ff00f10) == 0x0e200010) {
2486 /* Multiply with Internal Accumulate Format */
2487 rd0 = (insn >> 12) & 0xf;
2489 acc = (insn >> 5) & 7;
2494 switch ((insn >> 16) & 0xf) {
2496 gen_movl_T0_reg(s, rd0);
2497 gen_movl_T1_reg(s, rd1);
2498 gen_op_iwmmxt_muladdsl_M0_T0_T1();
2500 case 0x8: /* MIAPH */
2501 gen_movl_T0_reg(s, rd0);
2502 gen_movl_T1_reg(s, rd1);
2503 gen_op_iwmmxt_muladdsw_M0_T0_T1();
2505 case 0xc: /* MIABB */
2506 case 0xd: /* MIABT */
2507 case 0xe: /* MIATB */
2508 case 0xf: /* MIATT */
2509 gen_movl_T1_reg(s, rd0);
2510 if (insn & (1 << 16))
2511 gen_op_shrl_T1_im(16);
2512 gen_op_movl_T0_T1();
2513 gen_movl_T1_reg(s, rd1);
2514 if (insn & (1 << 17))
2515 gen_op_shrl_T1_im(16);
2516 gen_op_iwmmxt_muladdswl_M0_T0_T1();
2522 gen_op_iwmmxt_movq_wRn_M0(acc);
2526 if ((insn & 0x0fe00ff8) == 0x0c400000) {
2527 /* Internal Accumulator Access Format */
2528 rdhi = (insn >> 16) & 0xf;
2529 rdlo = (insn >> 12) & 0xf;
2535 if (insn & ARM_CP_RW_BIT) { /* MRA */
2536 gen_iwmmxt_movl_T0_T1_wRn(acc);
2537 gen_movl_reg_T0(s, rdlo);
2538 gen_op_movl_T0_im((1 << (40 - 32)) - 1);
2539 gen_op_andl_T0_T1();
2540 gen_movl_reg_T0(s, rdhi);
2542 gen_movl_T0_reg(s, rdlo);
2543 gen_movl_T1_reg(s, rdhi);
2544 gen_iwmmxt_movl_wRn_T0_T1(acc);
2552 /* Disassemble system coprocessor instruction. Return nonzero if
2553 instruction is not defined. */
2554 static int disas_cp_insn(CPUState *env, DisasContext *s, uint32_t insn)
2557 uint32_t rd = (insn >> 12) & 0xf;
2558 uint32_t cp = (insn >> 8) & 0xf;
2563 if (insn & ARM_CP_RW_BIT) {
2564 if (!env->cp[cp].cp_read)
2566 gen_set_pc_im(s->pc);
2568 gen_helper_get_cp(tmp, cpu_env, tcg_const_i32(insn));
2569 store_reg(s, rd, tmp);
2571 if (!env->cp[cp].cp_write)
2573 gen_set_pc_im(s->pc);
2574 tmp = load_reg(s, rd);
2575 gen_helper_set_cp(cpu_env, tcg_const_i32(insn), tmp);
2580 static int cp15_user_ok(uint32_t insn)
2582 int cpn = (insn >> 16) & 0xf;
2583 int cpm = insn & 0xf;
2584 int op = ((insn >> 5) & 7) | ((insn >> 18) & 0x38);
2586 if (cpn == 13 && cpm == 0) {
2588 if (op == 2 || (op == 3 && (insn & ARM_CP_RW_BIT)))
2592 /* ISB, DSB, DMB. */
2593 if ((cpm == 5 && op == 4)
2594 || (cpm == 10 && (op == 4 || op == 5)))
2600 /* Disassemble system coprocessor (cp15) instruction. Return nonzero if
2601 instruction is not defined. */
2602 static int disas_cp15_insn(CPUState *env, DisasContext *s, uint32_t insn)
2607 /* M profile cores use memory mapped registers instead of cp15. */
2608 if (arm_feature(env, ARM_FEATURE_M))
2611 if ((insn & (1 << 25)) == 0) {
2612 if (insn & (1 << 20)) {
2616 /* mcrr. Used for block cache operations, so implement as no-op. */
2619 if ((insn & (1 << 4)) == 0) {
2623 if (IS_USER(s) && !cp15_user_ok(insn)) {
2626 if ((insn & 0x0fff0fff) == 0x0e070f90
2627 || (insn & 0x0fff0fff) == 0x0e070f58) {
2628 /* Wait for interrupt. */
2629 gen_set_pc_im(s->pc);
2630 s->is_jmp = DISAS_WFI;
2633 rd = (insn >> 12) & 0xf;
2634 if (insn & ARM_CP_RW_BIT) {
2636 gen_helper_get_cp15(tmp, cpu_env, tcg_const_i32(insn));
2637 /* If the destination register is r15 then sets condition codes. */
2639 store_reg(s, rd, tmp);
2643 tmp = load_reg(s, rd);
2644 gen_helper_set_cp15(cpu_env, tcg_const_i32(insn), tmp);
2646 /* Normally we would always end the TB here, but Linux
2647 * arch/arm/mach-pxa/sleep.S expects two instructions following
2648 * an MMU enable to execute from cache. Imitate this behaviour. */
2649 if (!arm_feature(env, ARM_FEATURE_XSCALE) ||
2650 (insn & 0x0fff0fff) != 0x0e010f10)
2656 #define VFP_REG_SHR(x, n) (((n) > 0) ? (x) >> (n) : (x) << -(n))
2657 #define VFP_SREG(insn, bigbit, smallbit) \
2658 ((VFP_REG_SHR(insn, bigbit - 1) & 0x1e) | (((insn) >> (smallbit)) & 1))
2659 #define VFP_DREG(reg, insn, bigbit, smallbit) do { \
2660 if (arm_feature(env, ARM_FEATURE_VFP3)) { \
2661 reg = (((insn) >> (bigbit)) & 0x0f) \
2662 | (((insn) >> ((smallbit) - 4)) & 0x10); \
2664 if (insn & (1 << (smallbit))) \
2666 reg = ((insn) >> (bigbit)) & 0x0f; \
2669 #define VFP_SREG_D(insn) VFP_SREG(insn, 12, 22)
2670 #define VFP_DREG_D(reg, insn) VFP_DREG(reg, insn, 12, 22)
2671 #define VFP_SREG_N(insn) VFP_SREG(insn, 16, 7)
2672 #define VFP_DREG_N(reg, insn) VFP_DREG(reg, insn, 16, 7)
2673 #define VFP_SREG_M(insn) VFP_SREG(insn, 0, 5)
2674 #define VFP_DREG_M(reg, insn) VFP_DREG(reg, insn, 0, 5)
2676 /* Move between integer and VFP cores. */
2677 static TCGv gen_vfp_mrs(void)
2679 TCGv tmp = new_tmp();
2680 tcg_gen_mov_i32(tmp, cpu_F0s);
2684 static void gen_vfp_msr(TCGv tmp)
2686 tcg_gen_mov_i32(cpu_F0s, tmp);
2691 vfp_enabled(CPUState * env)
2693 return ((env->vfp.xregs[ARM_VFP_FPEXC] & (1 << 30)) != 0);
2696 static void gen_neon_dup_u8(TCGv var, int shift)
2698 TCGv tmp = new_tmp();
2700 tcg_gen_shri_i32(var, var, shift);
2701 tcg_gen_ext8u_i32(var, var);
2702 tcg_gen_shli_i32(tmp, var, 8);
2703 tcg_gen_or_i32(var, var, tmp);
2704 tcg_gen_shli_i32(tmp, var, 16);
2705 tcg_gen_or_i32(var, var, tmp);
2709 static void gen_neon_dup_low16(TCGv var)
2711 TCGv tmp = new_tmp();
2712 tcg_gen_ext16u_i32(var, var);
2713 tcg_gen_shli_i32(tmp, var, 16);
2714 tcg_gen_or_i32(var, var, tmp);
2718 static void gen_neon_dup_high16(TCGv var)
2720 TCGv tmp = new_tmp();
2721 tcg_gen_andi_i32(var, var, 0xffff0000);
2722 tcg_gen_shri_i32(tmp, var, 16);
2723 tcg_gen_or_i32(var, var, tmp);
2727 /* Disassemble a VFP instruction. Returns nonzero if an error occured
2728 (ie. an undefined instruction). */
2729 static int disas_vfp_insn(CPUState * env, DisasContext *s, uint32_t insn)
2731 uint32_t rd, rn, rm, op, i, n, offset, delta_d, delta_m, bank_mask;
2736 if (!arm_feature(env, ARM_FEATURE_VFP))
2739 if (!vfp_enabled(env)) {
2740 /* VFP disabled. Only allow fmxr/fmrx to/from some control regs. */
2741 if ((insn & 0x0fe00fff) != 0x0ee00a10)
2743 rn = (insn >> 16) & 0xf;
2744 if (rn != ARM_VFP_FPSID && rn != ARM_VFP_FPEXC
2745 && rn != ARM_VFP_MVFR1 && rn != ARM_VFP_MVFR0)
2748 dp = ((insn & 0xf00) == 0xb00);
2749 switch ((insn >> 24) & 0xf) {
2751 if (insn & (1 << 4)) {
2752 /* single register transfer */
2753 rd = (insn >> 12) & 0xf;
2758 VFP_DREG_N(rn, insn);
2761 if (insn & 0x00c00060
2762 && !arm_feature(env, ARM_FEATURE_NEON))
2765 pass = (insn >> 21) & 1;
2766 if (insn & (1 << 22)) {
2768 offset = ((insn >> 5) & 3) * 8;
2769 } else if (insn & (1 << 5)) {
2771 offset = (insn & (1 << 6)) ? 16 : 0;
2776 if (insn & ARM_CP_RW_BIT) {
2778 tmp = neon_load_reg(rn, pass);
2782 tcg_gen_shri_i32(tmp, tmp, offset);
2783 if (insn & (1 << 23))
2789 if (insn & (1 << 23)) {
2791 tcg_gen_shri_i32(tmp, tmp, 16);
2797 tcg_gen_sari_i32(tmp, tmp, 16);
2806 store_reg(s, rd, tmp);
2809 tmp = load_reg(s, rd);
2810 if (insn & (1 << 23)) {
2813 gen_neon_dup_u8(tmp, 0);
2814 } else if (size == 1) {
2815 gen_neon_dup_low16(tmp);
2818 tcg_gen_mov_i32(tmp2, tmp);
2819 neon_store_reg(rn, 0, tmp2);
2820 neon_store_reg(rn, 0, tmp);
2825 tmp2 = neon_load_reg(rn, pass);
2826 gen_bfi(tmp, tmp2, tmp, offset, 0xff);
2830 tmp2 = neon_load_reg(rn, pass);
2831 gen_bfi(tmp, tmp2, tmp, offset, 0xffff);
2837 neon_store_reg(rn, pass, tmp);
2841 if ((insn & 0x6f) != 0x00)
2843 rn = VFP_SREG_N(insn);
2844 if (insn & ARM_CP_RW_BIT) {
2846 if (insn & (1 << 21)) {
2847 /* system register */
2852 /* VFP2 allows access to FSID from userspace.
2853 VFP3 restricts all id registers to privileged
2856 && arm_feature(env, ARM_FEATURE_VFP3))
2858 tmp = load_cpu_field(vfp.xregs[rn]);
2863 tmp = load_cpu_field(vfp.xregs[rn]);
2865 case ARM_VFP_FPINST:
2866 case ARM_VFP_FPINST2:
2867 /* Not present in VFP3. */
2869 || arm_feature(env, ARM_FEATURE_VFP3))
2871 tmp = load_cpu_field(vfp.xregs[rn]);
2875 tmp = load_cpu_field(vfp.xregs[ARM_VFP_FPSCR]);
2876 tcg_gen_andi_i32(tmp, tmp, 0xf0000000);
2879 gen_helper_vfp_get_fpscr(tmp, cpu_env);
2885 || !arm_feature(env, ARM_FEATURE_VFP3))
2887 tmp = load_cpu_field(vfp.xregs[rn]);
2893 gen_mov_F0_vreg(0, rn);
2894 tmp = gen_vfp_mrs();
2897 /* Set the 4 flag bits in the CPSR. */
2901 store_reg(s, rd, tmp);
2905 tmp = load_reg(s, rd);
2906 if (insn & (1 << 21)) {
2908 /* system register */
2913 /* Writes are ignored. */
2916 gen_helper_vfp_set_fpscr(cpu_env, tmp);
2923 store_cpu_field(tmp, vfp.xregs[rn]);
2926 case ARM_VFP_FPINST:
2927 case ARM_VFP_FPINST2:
2928 store_cpu_field(tmp, vfp.xregs[rn]);
2935 gen_mov_vreg_F0(0, rn);
2940 /* data processing */
2941 /* The opcode is in bits 23, 21, 20 and 6. */
2942 op = ((insn >> 20) & 8) | ((insn >> 19) & 6) | ((insn >> 6) & 1);
2946 rn = ((insn >> 15) & 0x1e) | ((insn >> 7) & 1);
2948 /* rn is register number */
2949 VFP_DREG_N(rn, insn);
2952 if (op == 15 && (rn == 15 || rn > 17)) {
2953 /* Integer or single precision destination. */
2954 rd = VFP_SREG_D(insn);
2956 VFP_DREG_D(rd, insn);
2959 if (op == 15 && (rn == 16 || rn == 17)) {
2960 /* Integer source. */
2961 rm = ((insn << 1) & 0x1e) | ((insn >> 5) & 1);
2963 VFP_DREG_M(rm, insn);
2966 rn = VFP_SREG_N(insn);
2967 if (op == 15 && rn == 15) {
2968 /* Double precision destination. */
2969 VFP_DREG_D(rd, insn);
2971 rd = VFP_SREG_D(insn);
2973 rm = VFP_SREG_M(insn);
2976 veclen = env->vfp.vec_len;
2977 if (op == 15 && rn > 3)
2980 /* Shut up compiler warnings. */
2991 /* Figure out what type of vector operation this is. */
2992 if ((rd & bank_mask) == 0) {
2997 delta_d = (env->vfp.vec_stride >> 1) + 1;
2999 delta_d = env->vfp.vec_stride + 1;
3001 if ((rm & bank_mask) == 0) {
3002 /* mixed scalar/vector */
3011 /* Load the initial operands. */
3016 /* Integer source */
3017 gen_mov_F0_vreg(0, rm);
3022 gen_mov_F0_vreg(dp, rd);
3023 gen_mov_F1_vreg(dp, rm);
3027 /* Compare with zero */
3028 gen_mov_F0_vreg(dp, rd);
3035 /* Source and destination the same. */
3036 gen_mov_F0_vreg(dp, rd);
3039 /* One source operand. */
3040 gen_mov_F0_vreg(dp, rm);
3044 /* Two source operands. */
3045 gen_mov_F0_vreg(dp, rn);
3046 gen_mov_F1_vreg(dp, rm);
3050 /* Perform the calculation. */
3052 case 0: /* mac: fd + (fn * fm) */
3054 gen_mov_F1_vreg(dp, rd);
3057 case 1: /* nmac: fd - (fn * fm) */
3060 gen_mov_F1_vreg(dp, rd);
3063 case 2: /* msc: -fd + (fn * fm) */
3065 gen_mov_F1_vreg(dp, rd);
3068 case 3: /* nmsc: -fd - (fn * fm) */
3070 gen_mov_F1_vreg(dp, rd);
3074 case 4: /* mul: fn * fm */
3077 case 5: /* nmul: -(fn * fm) */
3081 case 6: /* add: fn + fm */
3084 case 7: /* sub: fn - fm */
3087 case 8: /* div: fn / fm */
3090 case 14: /* fconst */
3091 if (!arm_feature(env, ARM_FEATURE_VFP3))
3094 n = (insn << 12) & 0x80000000;
3095 i = ((insn >> 12) & 0x70) | (insn & 0xf);
3102 tcg_gen_movi_i64(cpu_F0d, ((uint64_t)n) << 32);
3109 tcg_gen_movi_i32(cpu_F0s, n);
3112 case 15: /* extension space */
3135 case 11: /* cmpez */
3139 case 15: /* single<->double conversion */
3141 gen_helper_vfp_fcvtsd(cpu_F0s, cpu_F0d, cpu_env);
3143 gen_helper_vfp_fcvtds(cpu_F0d, cpu_F0s, cpu_env);
3145 case 16: /* fuito */
3148 case 17: /* fsito */
3151 case 20: /* fshto */
3152 if (!arm_feature(env, ARM_FEATURE_VFP3))
3154 gen_vfp_shto(dp, rm);
3156 case 21: /* fslto */
3157 if (!arm_feature(env, ARM_FEATURE_VFP3))
3159 gen_vfp_slto(dp, rm);
3161 case 22: /* fuhto */
3162 if (!arm_feature(env, ARM_FEATURE_VFP3))
3164 gen_vfp_uhto(dp, rm);
3166 case 23: /* fulto */
3167 if (!arm_feature(env, ARM_FEATURE_VFP3))
3169 gen_vfp_ulto(dp, rm);
3171 case 24: /* ftoui */
3174 case 25: /* ftouiz */
3177 case 26: /* ftosi */
3180 case 27: /* ftosiz */
3183 case 28: /* ftosh */
3184 if (!arm_feature(env, ARM_FEATURE_VFP3))
3186 gen_vfp_tosh(dp, rm);
3188 case 29: /* ftosl */
3189 if (!arm_feature(env, ARM_FEATURE_VFP3))
3191 gen_vfp_tosl(dp, rm);
3193 case 30: /* ftouh */
3194 if (!arm_feature(env, ARM_FEATURE_VFP3))
3196 gen_vfp_touh(dp, rm);
3198 case 31: /* ftoul */
3199 if (!arm_feature(env, ARM_FEATURE_VFP3))
3201 gen_vfp_toul(dp, rm);
3203 default: /* undefined */
3204 printf ("rn:%d\n", rn);
3208 default: /* undefined */
3209 printf ("op:%d\n", op);
3213 /* Write back the result. */
3214 if (op == 15 && (rn >= 8 && rn <= 11))
3215 ; /* Comparison, do nothing. */
3216 else if (op == 15 && rn > 17)
3217 /* Integer result. */
3218 gen_mov_vreg_F0(0, rd);
3219 else if (op == 15 && rn == 15)
3221 gen_mov_vreg_F0(!dp, rd);
3223 gen_mov_vreg_F0(dp, rd);
3225 /* break out of the loop if we have finished */
3229 if (op == 15 && delta_m == 0) {
3230 /* single source one-many */
3232 rd = ((rd + delta_d) & (bank_mask - 1))
3234 gen_mov_vreg_F0(dp, rd);
3238 /* Setup the next operands. */
3240 rd = ((rd + delta_d) & (bank_mask - 1))
3244 /* One source operand. */
3245 rm = ((rm + delta_m) & (bank_mask - 1))
3247 gen_mov_F0_vreg(dp, rm);
3249 /* Two source operands. */
3250 rn = ((rn + delta_d) & (bank_mask - 1))
3252 gen_mov_F0_vreg(dp, rn);
3254 rm = ((rm + delta_m) & (bank_mask - 1))
3256 gen_mov_F1_vreg(dp, rm);
3264 if (dp && (insn & 0x03e00000) == 0x00400000) {
3265 /* two-register transfer */
3266 rn = (insn >> 16) & 0xf;
3267 rd = (insn >> 12) & 0xf;
3269 VFP_DREG_M(rm, insn);
3271 rm = VFP_SREG_M(insn);
3274 if (insn & ARM_CP_RW_BIT) {
3277 gen_mov_F0_vreg(0, rm * 2);
3278 tmp = gen_vfp_mrs();
3279 store_reg(s, rd, tmp);
3280 gen_mov_F0_vreg(0, rm * 2 + 1);
3281 tmp = gen_vfp_mrs();
3282 store_reg(s, rn, tmp);
3284 gen_mov_F0_vreg(0, rm);
3285 tmp = gen_vfp_mrs();
3286 store_reg(s, rn, tmp);
3287 gen_mov_F0_vreg(0, rm + 1);
3288 tmp = gen_vfp_mrs();
3289 store_reg(s, rd, tmp);
3294 tmp = load_reg(s, rd);
3296 gen_mov_vreg_F0(0, rm * 2);
3297 tmp = load_reg(s, rn);
3299 gen_mov_vreg_F0(0, rm * 2 + 1);
3301 tmp = load_reg(s, rn);
3303 gen_mov_vreg_F0(0, rm);
3304 tmp = load_reg(s, rd);
3306 gen_mov_vreg_F0(0, rm + 1);
3311 rn = (insn >> 16) & 0xf;
3313 VFP_DREG_D(rd, insn);
3315 rd = VFP_SREG_D(insn);
3316 if (s->thumb && rn == 15) {
3317 gen_op_movl_T1_im(s->pc & ~2);
3319 gen_movl_T1_reg(s, rn);
3321 if ((insn & 0x01200000) == 0x01000000) {
3322 /* Single load/store */
3323 offset = (insn & 0xff) << 2;
3324 if ((insn & (1 << 23)) == 0)
3326 gen_op_addl_T1_im(offset);
3327 if (insn & (1 << 20)) {
3329 gen_mov_vreg_F0(dp, rd);
3331 gen_mov_F0_vreg(dp, rd);
3335 /* load/store multiple */
3337 n = (insn >> 1) & 0x7f;
3341 if (insn & (1 << 24)) /* pre-decrement */
3342 gen_op_addl_T1_im(-((insn & 0xff) << 2));
3348 for (i = 0; i < n; i++) {
3349 if (insn & ARM_CP_RW_BIT) {
3352 gen_mov_vreg_F0(dp, rd + i);
3355 gen_mov_F0_vreg(dp, rd + i);
3358 gen_op_addl_T1_im(offset);
3360 if (insn & (1 << 21)) {
3362 if (insn & (1 << 24))
3363 offset = -offset * n;
3364 else if (dp && (insn & 1))
3370 gen_op_addl_T1_im(offset);
3371 gen_movl_reg_T1(s, rn);
3377 /* Should never happen. */
3383 static inline void gen_goto_tb(DisasContext *s, int n, uint32_t dest)
3385 TranslationBlock *tb;
3388 if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK)) {
3390 gen_set_pc_im(dest);
3391 tcg_gen_exit_tb((long)tb + n);
3393 gen_set_pc_im(dest);
3398 static inline void gen_jmp (DisasContext *s, uint32_t dest)
3400 if (__builtin_expect(s->singlestep_enabled, 0)) {
3401 /* An indirect jump so that we still trigger the debug exception. */
3406 gen_goto_tb(s, 0, dest);
3407 s->is_jmp = DISAS_TB_JUMP;
3411 static inline void gen_mulxy(TCGv t0, TCGv t1, int x, int y)
3414 tcg_gen_sari_i32(t0, t0, 16);
3418 tcg_gen_sari_i32(t1, t1, 16);
3421 tcg_gen_mul_i32(t0, t0, t1);
3424 /* Return the mask of PSR bits set by a MSR instruction. */
3425 static uint32_t msr_mask(CPUState *env, DisasContext *s, int flags, int spsr) {
3429 if (flags & (1 << 0))
3431 if (flags & (1 << 1))
3433 if (flags & (1 << 2))
3435 if (flags & (1 << 3))
3438 /* Mask out undefined bits. */
3439 mask &= ~CPSR_RESERVED;
3440 if (!arm_feature(env, ARM_FEATURE_V6))
3441 mask &= ~(CPSR_E | CPSR_GE);
3442 if (!arm_feature(env, ARM_FEATURE_THUMB2))
3444 /* Mask out execution state bits. */
3447 /* Mask out privileged bits. */
3453 /* Returns nonzero if access to the PSR is not permitted. */
3454 static int gen_set_psr_T0(DisasContext *s, uint32_t mask, int spsr)
3458 /* ??? This is also undefined in system mode. */
3462 tmp = load_cpu_field(spsr);
3463 tcg_gen_andi_i32(tmp, tmp, ~mask);
3464 tcg_gen_andi_i32(cpu_T[0], cpu_T[0], mask);
3465 tcg_gen_or_i32(tmp, tmp, cpu_T[0]);
3466 store_cpu_field(tmp, spsr);
3468 gen_set_cpsr(cpu_T[0], mask);
3474 /* Generate an old-style exception return. */
3475 static void gen_exception_return(DisasContext *s)
3478 gen_movl_reg_T0(s, 15);
3479 tmp = load_cpu_field(spsr);
3480 gen_set_cpsr(tmp, 0xffffffff);
3482 s->is_jmp = DISAS_UPDATE;
3485 /* Generate a v6 exception return. Marks both values as dead. */
3486 static void gen_rfe(DisasContext *s, TCGv pc, TCGv cpsr)
3488 gen_set_cpsr(cpsr, 0xffffffff);
3490 store_reg(s, 15, pc);
3491 s->is_jmp = DISAS_UPDATE;
3495 gen_set_condexec (DisasContext *s)
3497 if (s->condexec_mask) {
3498 uint32_t val = (s->condexec_cond << 4) | (s->condexec_mask >> 1);
3499 TCGv tmp = new_tmp();
3500 tcg_gen_movi_i32(tmp, val);
3501 store_cpu_field(tmp, condexec_bits);
3505 static void gen_nop_hint(DisasContext *s, int val)
3509 gen_set_pc_im(s->pc);
3510 s->is_jmp = DISAS_WFI;
3514 /* TODO: Implement SEV and WFE. May help SMP performance. */
3520 /* These macros help make the code more readable when migrating from the
3521 old dyngen helpers. They should probably be removed when
3522 T0/T1 are removed. */
3523 #define CPU_T001 cpu_T[0], cpu_T[0], cpu_T[1]
3524 #define CPU_T0E01 cpu_T[0], cpu_env, cpu_T[0], cpu_T[1]
3526 #define CPU_V001 cpu_V0, cpu_V0, cpu_V1
3528 static inline int gen_neon_add(int size)
3531 case 0: gen_helper_neon_add_u8(CPU_T001); break;
3532 case 1: gen_helper_neon_add_u16(CPU_T001); break;
3533 case 2: gen_op_addl_T0_T1(); break;
3539 static inline void gen_neon_rsb(int size)
3542 case 0: gen_helper_neon_sub_u8(cpu_T[0], cpu_T[1], cpu_T[0]); break;
3543 case 1: gen_helper_neon_sub_u16(cpu_T[0], cpu_T[1], cpu_T[0]); break;
3544 case 2: gen_op_rsbl_T0_T1(); break;
3549 /* 32-bit pairwise ops end up the same as the elementwise versions. */
3550 #define gen_helper_neon_pmax_s32 gen_helper_neon_max_s32
3551 #define gen_helper_neon_pmax_u32 gen_helper_neon_max_u32
3552 #define gen_helper_neon_pmin_s32 gen_helper_neon_min_s32
3553 #define gen_helper_neon_pmin_u32 gen_helper_neon_min_u32
3555 /* FIXME: This is wrong. They set the wrong overflow bit. */
3556 #define gen_helper_neon_qadd_s32(a, e, b, c) gen_helper_add_saturate(a, b, c)
3557 #define gen_helper_neon_qadd_u32(a, e, b, c) gen_helper_add_usaturate(a, b, c)
3558 #define gen_helper_neon_qsub_s32(a, e, b, c) gen_helper_sub_saturate(a, b, c)
3559 #define gen_helper_neon_qsub_u32(a, e, b, c) gen_helper_sub_usaturate(a, b, c)
3561 #define GEN_NEON_INTEGER_OP_ENV(name) do { \
3562 switch ((size << 1) | u) { \
3564 gen_helper_neon_##name##_s8(cpu_T[0], cpu_env, cpu_T[0], cpu_T[1]); \
3567 gen_helper_neon_##name##_u8(cpu_T[0], cpu_env, cpu_T[0], cpu_T[1]); \
3570 gen_helper_neon_##name##_s16(cpu_T[0], cpu_env, cpu_T[0], cpu_T[1]); \
3573 gen_helper_neon_##name##_u16(cpu_T[0], cpu_env, cpu_T[0], cpu_T[1]); \
3576 gen_helper_neon_##name##_s32(cpu_T[0], cpu_env, cpu_T[0], cpu_T[1]); \
3579 gen_helper_neon_##name##_u32(cpu_T[0], cpu_env, cpu_T[0], cpu_T[1]); \
3581 default: return 1; \
3584 #define GEN_NEON_INTEGER_OP(name) do { \
3585 switch ((size << 1) | u) { \
3587 gen_helper_neon_##name##_s8(cpu_T[0], cpu_T[0], cpu_T[1]); \
3590 gen_helper_neon_##name##_u8(cpu_T[0], cpu_T[0], cpu_T[1]); \
3593 gen_helper_neon_##name##_s16(cpu_T[0], cpu_T[0], cpu_T[1]); \
3596 gen_helper_neon_##name##_u16(cpu_T[0], cpu_T[0], cpu_T[1]); \
3599 gen_helper_neon_##name##_s32(cpu_T[0], cpu_T[0], cpu_T[1]); \
3602 gen_helper_neon_##name##_u32(cpu_T[0], cpu_T[0], cpu_T[1]); \
3604 default: return 1; \
3608 gen_neon_movl_scratch_T0(int scratch)
3612 offset = offsetof(CPUARMState, vfp.scratch[scratch]);
3613 tcg_gen_st_i32(cpu_T[0], cpu_env, offset);
3617 gen_neon_movl_scratch_T1(int scratch)
3621 offset = offsetof(CPUARMState, vfp.scratch[scratch]);
3622 tcg_gen_st_i32(cpu_T[1], cpu_env, offset);
3626 gen_neon_movl_T0_scratch(int scratch)
3630 offset = offsetof(CPUARMState, vfp.scratch[scratch]);
3631 tcg_gen_ld_i32(cpu_T[0], cpu_env, offset);
3635 gen_neon_movl_T1_scratch(int scratch)
3639 offset = offsetof(CPUARMState, vfp.scratch[scratch]);
3640 tcg_gen_ld_i32(cpu_T[1], cpu_env, offset);
3643 static inline void gen_neon_get_scalar(int size, int reg)
3646 NEON_GET_REG(T0, reg >> 1, reg & 1);
3648 NEON_GET_REG(T0, reg >> 2, (reg >> 1) & 1);
3650 gen_neon_dup_low16(cpu_T[0]);
3652 gen_neon_dup_high16(cpu_T[0]);
3656 static void gen_neon_unzip(int reg, int q, int tmp, int size)
3660 for (n = 0; n < q + 1; n += 2) {
3661 NEON_GET_REG(T0, reg, n);
3662 NEON_GET_REG(T0, reg, n + n);
3664 case 0: gen_helper_neon_unzip_u8(); break;
3665 case 1: gen_helper_neon_zip_u16(); break; /* zip and unzip are the same. */
3666 case 2: /* no-op */; break;
3669 gen_neon_movl_scratch_T0(tmp + n);
3670 gen_neon_movl_scratch_T1(tmp + n + 1);
3678 } neon_ls_element_type[11] = {
3692 /* Translate a NEON load/store element instruction. Return nonzero if the
3693 instruction is invalid. */
3694 static int disas_neon_ls_insn(CPUState * env, DisasContext *s, uint32_t insn)
3710 if (!vfp_enabled(env))
3712 VFP_DREG_D(rd, insn);
3713 rn = (insn >> 16) & 0xf;
3715 load = (insn & (1 << 21)) != 0;
3716 if ((insn & (1 << 23)) == 0) {
3717 /* Load store all elements. */
3718 op = (insn >> 8) & 0xf;
3719 size = (insn >> 6) & 3;
3720 if (op > 10 || size == 3)
3722 nregs = neon_ls_element_type[op].nregs;
3723 interleave = neon_ls_element_type[op].interleave;
3724 gen_movl_T1_reg(s, rn);
3725 stride = (1 << size) * interleave;
3726 for (reg = 0; reg < nregs; reg++) {
3727 if (interleave > 2 || (interleave == 2 && nregs == 2)) {
3728 gen_movl_T1_reg(s, rn);
3729 gen_op_addl_T1_im((1 << size) * reg);
3730 } else if (interleave == 2 && nregs == 4 && reg == 2) {
3731 gen_movl_T1_reg(s, rn);
3732 gen_op_addl_T1_im(1 << size);
3734 for (pass = 0; pass < 2; pass++) {
3737 tmp = gen_ld32(cpu_T[1], IS_USER(s));
3738 neon_store_reg(rd, pass, tmp);
3740 tmp = neon_load_reg(rd, pass);
3741 gen_st32(tmp, cpu_T[1], IS_USER(s));
3743 gen_op_addl_T1_im(stride);
3744 } else if (size == 1) {
3746 tmp = gen_ld16u(cpu_T[1], IS_USER(s));
3747 gen_op_addl_T1_im(stride);
3748 tmp2 = gen_ld16u(cpu_T[1], IS_USER(s));
3749 gen_op_addl_T1_im(stride);
3750 gen_bfi(tmp, tmp, tmp2, 16, 0xffff);
3752 neon_store_reg(rd, pass, tmp);
3754 tmp = neon_load_reg(rd, pass);
3756 tcg_gen_shri_i32(tmp2, tmp, 16);
3757 gen_st16(tmp, cpu_T[1], IS_USER(s));
3758 gen_op_addl_T1_im(stride);
3759 gen_st16(tmp2, cpu_T[1], IS_USER(s));
3760 gen_op_addl_T1_im(stride);
3762 } else /* size == 0 */ {
3764 for (n = 0; n < 4; n++) {
3765 tmp = gen_ld8u(cpu_T[1], IS_USER(s));
3766 gen_op_addl_T1_im(stride);
3770 gen_bfi(tmp2, tmp2, tmp, n * 8, 0xff);
3774 neon_store_reg(rd, pass, tmp2);
3776 tmp2 = neon_load_reg(rd, pass);
3777 for (n = 0; n < 4; n++) {
3780 tcg_gen_mov_i32(tmp, tmp2);
3782 tcg_gen_shri_i32(tmp, tmp2, n * 8);
3784 gen_st8(tmp, cpu_T[1], IS_USER(s));
3785 gen_op_addl_T1_im(stride);
3791 rd += neon_ls_element_type[op].spacing;
3795 size = (insn >> 10) & 3;
3797 /* Load single element to all lanes. */
3800 size = (insn >> 6) & 3;
3801 nregs = ((insn >> 8) & 3) + 1;
3802 stride = (insn & (1 << 5)) ? 2 : 1;
3803 gen_movl_T1_reg(s, rn);
3804 for (reg = 0; reg < nregs; reg++) {
3807 tmp = gen_ld8u(cpu_T[1], IS_USER(s));
3808 gen_neon_dup_u8(tmp, 0);
3811 tmp = gen_ld16u(cpu_T[1], IS_USER(s));
3812 gen_neon_dup_low16(tmp);
3815 tmp = gen_ld32(cpu_T[0], IS_USER(s));
3820 gen_op_addl_T1_im(1 << size);
3822 tcg_gen_mov_i32(tmp2, tmp);
3823 neon_store_reg(rd, 0, tmp2);
3824 neon_store_reg(rd, 0, tmp);
3827 stride = (1 << size) * nregs;
3829 /* Single element. */
3830 pass = (insn >> 7) & 1;
3833 shift = ((insn >> 5) & 3) * 8;
3837 shift = ((insn >> 6) & 1) * 16;
3838 stride = (insn & (1 << 5)) ? 2 : 1;
3842 stride = (insn & (1 << 6)) ? 2 : 1;
3847 nregs = ((insn >> 8) & 3) + 1;
3848 gen_movl_T1_reg(s, rn);
3849 for (reg = 0; reg < nregs; reg++) {
3853 tmp = gen_ld8u(cpu_T[1], IS_USER(s));
3856 tmp = gen_ld16u(cpu_T[1], IS_USER(s));
3859 tmp = gen_ld32(cpu_T[1], IS_USER(s));
3863 tmp2 = neon_load_reg(rd, pass);
3864 gen_bfi(tmp, tmp2, tmp, shift, size ? 0xffff : 0xff);
3867 neon_store_reg(rd, pass, tmp);
3868 } else { /* Store */
3869 tmp = neon_load_reg(rd, pass);
3871 tcg_gen_shri_i32(tmp, tmp, shift);
3874 gen_st8(tmp, cpu_T[1], IS_USER(s));
3877 gen_st16(tmp, cpu_T[1], IS_USER(s));
3880 gen_st32(tmp, cpu_T[1], IS_USER(s));
3885 gen_op_addl_T1_im(1 << size);
3887 stride = nregs * (1 << size);
3893 base = load_reg(s, rn);
3895 tcg_gen_addi_i32(base, base, stride);
3898 index = load_reg(s, rm);
3899 tcg_gen_add_i32(base, base, index);
3902 store_reg(s, rn, base);
3907 /* Bitwise select. dest = c ? t : f. Clobbers T and F. */
3908 static void gen_neon_bsl(TCGv dest, TCGv t, TCGv f, TCGv c)
3910 tcg_gen_and_i32(t, t, c);
3911 tcg_gen_bic_i32(f, f, c);
3912 tcg_gen_or_i32(dest, t, f);
3915 static inline void gen_neon_narrow(int size, TCGv dest, TCGv src)
3918 case 0: gen_helper_neon_narrow_u8(dest, src); break;
3919 case 1: gen_helper_neon_narrow_u16(dest, src); break;
3920 case 2: tcg_gen_trunc_i64_i32(dest, src); break;
3925 static inline void gen_neon_narrow_sats(int size, TCGv dest, TCGv src)
3928 case 0: gen_helper_neon_narrow_sat_s8(dest, cpu_env, src); break;
3929 case 1: gen_helper_neon_narrow_sat_s16(dest, cpu_env, src); break;
3930 case 2: gen_helper_neon_narrow_sat_s32(dest, cpu_env, src); break;
3935 static inline void gen_neon_narrow_satu(int size, TCGv dest, TCGv src)
3938 case 0: gen_helper_neon_narrow_sat_u8(dest, cpu_env, src); break;
3939 case 1: gen_helper_neon_narrow_sat_u16(dest, cpu_env, src); break;
3940 case 2: gen_helper_neon_narrow_sat_u32(dest, cpu_env, src); break;
3945 static inline void gen_neon_shift_narrow(int size, TCGv var, TCGv shift,
3951 case 1: gen_helper_neon_rshl_u16(var, var, shift); break;
3952 case 2: gen_helper_neon_rshl_u32(var, var, shift); break;
3957 case 1: gen_helper_neon_rshl_s16(var, var, shift); break;
3958 case 2: gen_helper_neon_rshl_s32(var, var, shift); break;
3965 case 1: gen_helper_neon_rshl_u16(var, var, shift); break;
3966 case 2: gen_helper_neon_rshl_u32(var, var, shift); break;
3971 case 1: gen_helper_neon_shl_s16(var, var, shift); break;
3972 case 2: gen_helper_neon_shl_s32(var, var, shift); break;
3979 static inline void gen_neon_widen(TCGv dest, TCGv src, int size, int u)
3983 case 0: gen_helper_neon_widen_u8(dest, src); break;
3984 case 1: gen_helper_neon_widen_u16(dest, src); break;
3985 case 2: tcg_gen_extu_i32_i64(dest, src); break;
3990 case 0: gen_helper_neon_widen_s8(dest, src); break;
3991 case 1: gen_helper_neon_widen_s16(dest, src); break;
3992 case 2: tcg_gen_ext_i32_i64(dest, src); break;
3999 static inline void gen_neon_addl(int size)
4002 case 0: gen_helper_neon_addl_u16(CPU_V001); break;
4003 case 1: gen_helper_neon_addl_u32(CPU_V001); break;
4004 case 2: tcg_gen_add_i64(CPU_V001); break;
4009 static inline void gen_neon_subl(int size)
4012 case 0: gen_helper_neon_subl_u16(CPU_V001); break;
4013 case 1: gen_helper_neon_subl_u32(CPU_V001); break;
4014 case 2: tcg_gen_sub_i64(CPU_V001); break;
4019 static inline void gen_neon_negl(TCGv var, int size)
4022 case 0: gen_helper_neon_negl_u16(var, var); break;
4023 case 1: gen_helper_neon_negl_u32(var, var); break;
4024 case 2: gen_helper_neon_negl_u64(var, var); break;
4029 static inline void gen_neon_addl_saturate(TCGv op0, TCGv op1, int size)
4032 case 1: gen_helper_neon_addl_saturate_s32(op0, cpu_env, op0, op1); break;
4033 case 2: gen_helper_neon_addl_saturate_s64(op0, cpu_env, op0, op1); break;
4038 static inline void gen_neon_mull(TCGv dest, TCGv a, TCGv b, int size, int u)
4042 switch ((size << 1) | u) {
4043 case 0: gen_helper_neon_mull_s8(dest, a, b); break;
4044 case 1: gen_helper_neon_mull_u8(dest, a, b); break;
4045 case 2: gen_helper_neon_mull_s16(dest, a, b); break;
4046 case 3: gen_helper_neon_mull_u16(dest, a, b); break;
4048 tmp = gen_muls_i64_i32(a, b);
4049 tcg_gen_mov_i64(dest, tmp);
4052 tmp = gen_mulu_i64_i32(a, b);
4053 tcg_gen_mov_i64(dest, tmp);
4063 /* Translate a NEON data processing instruction. Return nonzero if the
4064 instruction is invalid.
4065 We process data in a mixture of 32-bit and 64-bit chunks.
4066 Mostly we use 32-bit chunks so we can use normal scalar instructions. */
4068 static int disas_neon_data_insn(CPUState * env, DisasContext *s, uint32_t insn)
4085 if (!vfp_enabled(env))
4087 q = (insn & (1 << 6)) != 0;
4088 u = (insn >> 24) & 1;
4089 VFP_DREG_D(rd, insn);
4090 VFP_DREG_N(rn, insn);
4091 VFP_DREG_M(rm, insn);
4092 size = (insn >> 20) & 3;
4093 if ((insn & (1 << 23)) == 0) {
4094 /* Three register same length. */
4095 op = ((insn >> 7) & 0x1e) | ((insn >> 4) & 1);
4096 if (size == 3 && (op == 1 || op == 5 || op == 8 || op == 9
4097 || op == 10 || op == 11 || op == 16)) {
4098 /* 64-bit element instructions. */
4099 for (pass = 0; pass < (q ? 2 : 1); pass++) {
4100 neon_load_reg64(cpu_V0, rn + pass);
4101 neon_load_reg64(cpu_V1, rm + pass);
4105 gen_helper_neon_add_saturate_u64(CPU_V001);
4107 gen_helper_neon_add_saturate_s64(CPU_V001);
4112 gen_helper_neon_sub_saturate_u64(CPU_V001);
4114 gen_helper_neon_sub_saturate_s64(CPU_V001);
4119 gen_helper_neon_shl_u64(cpu_V0, cpu_V1, cpu_V0);
4121 gen_helper_neon_shl_s64(cpu_V0, cpu_V1, cpu_V0);
4126 gen_helper_neon_qshl_u64(cpu_V0, cpu_env,
4129 gen_helper_neon_qshl_s64(cpu_V1, cpu_env,
4133 case 10: /* VRSHL */
4135 gen_helper_neon_rshl_u64(cpu_V0, cpu_V1, cpu_V0);
4137 gen_helper_neon_rshl_s64(cpu_V0, cpu_V1, cpu_V0);
4140 case 11: /* VQRSHL */
4142 gen_helper_neon_qrshl_u64(cpu_V0, cpu_env,
4145 gen_helper_neon_qrshl_s64(cpu_V0, cpu_env,
4151 tcg_gen_sub_i64(CPU_V001);
4153 tcg_gen_add_i64(CPU_V001);
4159 neon_store_reg64(cpu_V0, rd + pass);
4166 case 10: /* VRSHL */
4167 case 11: /* VQRSHL */
4170 /* Shift instruction operands are reversed. */
4177 case 20: /* VPMAX */
4178 case 21: /* VPMIN */
4179 case 23: /* VPADD */
4182 case 26: /* VPADD (float) */
4183 pairwise = (u && size < 2);
4185 case 30: /* VPMIN/VPMAX (float) */
4192 for (pass = 0; pass < (q ? 4 : 2); pass++) {
4201 NEON_GET_REG(T0, rn, n);
4202 NEON_GET_REG(T1, rn, n + 1);
4204 NEON_GET_REG(T0, rm, n);
4205 NEON_GET_REG(T1, rm, n + 1);
4209 NEON_GET_REG(T0, rn, pass);
4210 NEON_GET_REG(T1, rm, pass);
4214 GEN_NEON_INTEGER_OP(hadd);
4217 GEN_NEON_INTEGER_OP_ENV(qadd);
4219 case 2: /* VRHADD */
4220 GEN_NEON_INTEGER_OP(rhadd);
4222 case 3: /* Logic ops. */
4223 switch ((u << 2) | size) {
4225 gen_op_andl_T0_T1();
4228 gen_op_bicl_T0_T1();
4238 gen_op_xorl_T0_T1();
4241 tmp = neon_load_reg(rd, pass);
4242 gen_neon_bsl(cpu_T[0], cpu_T[0], cpu_T[1], tmp);
4246 tmp = neon_load_reg(rd, pass);
4247 gen_neon_bsl(cpu_T[0], cpu_T[0], tmp, cpu_T[1]);
4251 tmp = neon_load_reg(rd, pass);
4252 gen_neon_bsl(cpu_T[0], tmp, cpu_T[0], cpu_T[1]);
4258 GEN_NEON_INTEGER_OP(hsub);
4261 GEN_NEON_INTEGER_OP_ENV(qsub);
4264 GEN_NEON_INTEGER_OP(cgt);
4267 GEN_NEON_INTEGER_OP(cge);
4270 GEN_NEON_INTEGER_OP(shl);
4273 GEN_NEON_INTEGER_OP_ENV(qshl);
4275 case 10: /* VRSHL */
4276 GEN_NEON_INTEGER_OP(rshl);
4278 case 11: /* VQRSHL */
4279 GEN_NEON_INTEGER_OP_ENV(qrshl);
4282 GEN_NEON_INTEGER_OP(max);
4285 GEN_NEON_INTEGER_OP(min);
4288 GEN_NEON_INTEGER_OP(abd);
4291 GEN_NEON_INTEGER_OP(abd);
4292 NEON_GET_REG(T1, rd, pass);
4296 if (!u) { /* VADD */
4297 if (gen_neon_add(size))
4301 case 0: gen_helper_neon_sub_u8(CPU_T001); break;
4302 case 1: gen_helper_neon_sub_u16(CPU_T001); break;
4303 case 2: gen_op_subl_T0_T1(); break;
4309 if (!u) { /* VTST */
4311 case 0: gen_helper_neon_tst_u8(CPU_T001); break;
4312 case 1: gen_helper_neon_tst_u16(CPU_T001); break;
4313 case 2: gen_helper_neon_tst_u32(CPU_T001); break;
4318 case 0: gen_helper_neon_ceq_u8(CPU_T001); break;
4319 case 1: gen_helper_neon_ceq_u16(CPU_T001); break;
4320 case 2: gen_helper_neon_ceq_u32(CPU_T001); break;
4325 case 18: /* Multiply. */
4327 case 0: gen_helper_neon_mul_u8(CPU_T001); break;
4328 case 1: gen_helper_neon_mul_u16(CPU_T001); break;
4329 case 2: gen_op_mul_T0_T1(); break;
4332 NEON_GET_REG(T1, rd, pass);
4340 if (u) { /* polynomial */
4341 gen_helper_neon_mul_p8(CPU_T001);
4342 } else { /* Integer */
4344 case 0: gen_helper_neon_mul_u8(CPU_T001); break;
4345 case 1: gen_helper_neon_mul_u16(CPU_T001); break;
4346 case 2: gen_op_mul_T0_T1(); break;
4351 case 20: /* VPMAX */
4352 GEN_NEON_INTEGER_OP(pmax);
4354 case 21: /* VPMIN */
4355 GEN_NEON_INTEGER_OP(pmin);
4357 case 22: /* Hultiply high. */
4358 if (!u) { /* VQDMULH */
4360 case 1: gen_helper_neon_qdmulh_s16(CPU_T0E01); break;
4361 case 2: gen_helper_neon_qdmulh_s32(CPU_T0E01); break;
4364 } else { /* VQRDHMUL */
4366 case 1: gen_helper_neon_qrdmulh_s16(CPU_T0E01); break;
4367 case 2: gen_helper_neon_qrdmulh_s32(CPU_T0E01); break;
4372 case 23: /* VPADD */
4376 case 0: gen_helper_neon_padd_u8(CPU_T001); break;
4377 case 1: gen_helper_neon_padd_u16(CPU_T001); break;
4378 case 2: gen_op_addl_T0_T1(); break;
4382 case 26: /* Floating point arithnetic. */
4383 switch ((u << 2) | size) {
4385 gen_helper_neon_add_f32(CPU_T001);
4388 gen_helper_neon_sub_f32(CPU_T001);
4391 gen_helper_neon_add_f32(CPU_T001);
4394 gen_helper_neon_abd_f32(CPU_T001);
4400 case 27: /* Float multiply. */
4401 gen_helper_neon_mul_f32(CPU_T001);
4403 NEON_GET_REG(T1, rd, pass);
4405 gen_helper_neon_add_f32(CPU_T001);
4407 gen_helper_neon_sub_f32(cpu_T[0], cpu_T[1], cpu_T[0]);
4411 case 28: /* Float compare. */
4413 gen_helper_neon_ceq_f32(CPU_T001);
4416 gen_helper_neon_cge_f32(CPU_T001);
4418 gen_helper_neon_cgt_f32(CPU_T001);
4421 case 29: /* Float compare absolute. */
4425 gen_helper_neon_acge_f32(CPU_T001);
4427 gen_helper_neon_acgt_f32(CPU_T001);
4429 case 30: /* Float min/max. */
4431 gen_helper_neon_max_f32(CPU_T001);
4433 gen_helper_neon_min_f32(CPU_T001);
4437 gen_helper_recps_f32(cpu_T[0], cpu_T[0], cpu_T[1], cpu_env);
4439 gen_helper_rsqrts_f32(cpu_T[0], cpu_T[0], cpu_T[1], cpu_env);
4444 /* Save the result. For elementwise operations we can put it
4445 straight into the destination register. For pairwise operations
4446 we have to be careful to avoid clobbering the source operands. */
4447 if (pairwise && rd == rm) {
4448 gen_neon_movl_scratch_T0(pass);
4450 NEON_SET_REG(T0, rd, pass);
4454 if (pairwise && rd == rm) {
4455 for (pass = 0; pass < (q ? 4 : 2); pass++) {
4456 gen_neon_movl_T0_scratch(pass);
4457 NEON_SET_REG(T0, rd, pass);
4460 /* End of 3 register same size operations. */
4461 } else if (insn & (1 << 4)) {
4462 if ((insn & 0x00380080) != 0) {
4463 /* Two registers and shift. */
4464 op = (insn >> 8) & 0xf;
4465 if (insn & (1 << 7)) {
4470 while ((insn & (1 << (size + 19))) == 0)
4473 shift = (insn >> 16) & ((1 << (3 + size)) - 1);
4474 /* To avoid excessive dumplication of ops we implement shift
4475 by immediate using the variable shift operations. */
4477 /* Shift by immediate:
4478 VSHR, VSRA, VRSHR, VRSRA, VSRI, VSHL, VQSHL, VQSHLU. */
4479 /* Right shifts are encoded as N - shift, where N is the
4480 element size in bits. */
4482 shift = shift - (1 << (size + 3));
4490 imm = (uint8_t) shift;
4495 imm = (uint16_t) shift;
4506 for (pass = 0; pass < count; pass++) {
4508 neon_load_reg64(cpu_V0, rm + pass);
4509 tcg_gen_movi_i64(cpu_V1, imm);
4514 gen_helper_neon_shl_u64(cpu_V0, cpu_V0, cpu_V1);
4516 gen_helper_neon_shl_s64(cpu_V0, cpu_V0, cpu_V1);
4521 gen_helper_neon_rshl_u64(cpu_V0, cpu_V0, cpu_V1);
4523 gen_helper_neon_rshl_s64(cpu_V0, cpu_V0, cpu_V1);
4528 gen_helper_neon_shl_u64(cpu_V0, cpu_V0, cpu_V1);
4530 case 5: /* VSHL, VSLI */
4531 gen_helper_neon_shl_u64(cpu_V0, cpu_V0, cpu_V1);
4535 gen_helper_neon_qshl_u64(cpu_V0, cpu_env, cpu_V0, cpu_V1);
4537 gen_helper_neon_qshl_s64(cpu_V0, cpu_env, cpu_V0, cpu_V1);
4539 case 7: /* VQSHLU */
4540 gen_helper_neon_qshl_u64(cpu_V0, cpu_env, cpu_V0, cpu_V1);
4543 if (op == 1 || op == 3) {
4545 neon_load_reg64(cpu_V0, rd + pass);
4546 tcg_gen_add_i64(cpu_V0, cpu_V0, cpu_V1);
4547 } else if (op == 4 || (op == 5 && u)) {
4549 cpu_abort(env, "VS[LR]I.64 not implemented");
4551 neon_store_reg64(cpu_V0, rd + pass);
4552 } else { /* size < 3 */
4553 /* Operands in T0 and T1. */
4554 gen_op_movl_T1_im(imm);
4555 NEON_GET_REG(T0, rm, pass);
4559 GEN_NEON_INTEGER_OP(shl);
4563 GEN_NEON_INTEGER_OP(rshl);
4568 GEN_NEON_INTEGER_OP(shl);
4570 case 5: /* VSHL, VSLI */
4572 case 0: gen_helper_neon_shl_u8(CPU_T001); break;
4573 case 1: gen_helper_neon_shl_u16(CPU_T001); break;
4574 case 2: gen_helper_neon_shl_u32(CPU_T001); break;
4579 GEN_NEON_INTEGER_OP_ENV(qshl);
4581 case 7: /* VQSHLU */
4583 case 0: gen_helper_neon_qshl_u8(CPU_T0E01); break;
4584 case 1: gen_helper_neon_qshl_u16(CPU_T0E01); break;
4585 case 2: gen_helper_neon_qshl_u32(CPU_T0E01); break;
4591 if (op == 1 || op == 3) {
4593 NEON_GET_REG(T1, rd, pass);
4595 } else if (op == 4 || (op == 5 && u)) {
4600 imm = 0xff >> -shift;
4602 imm = (uint8_t)(0xff << shift);
4608 imm = 0xffff >> -shift;
4610 imm = (uint16_t)(0xffff << shift);
4615 imm = 0xffffffffu >> -shift;
4617 imm = 0xffffffffu << shift;
4622 tmp = neon_load_reg(rd, pass);
4623 tcg_gen_andi_i32(cpu_T[0], cpu_T[0], imm);
4624 tcg_gen_andi_i32(tmp, tmp, ~imm);
4625 tcg_gen_or_i32(cpu_T[0], cpu_T[0], tmp);
4627 NEON_SET_REG(T0, rd, pass);
4630 } else if (op < 10) {
4631 /* Shift by immediate and narrow:
4632 VSHRN, VRSHRN, VQSHRN, VQRSHRN. */
4633 shift = shift - (1 << (size + 3));
4637 imm = (uint16_t)shift;
4639 tmp2 = tcg_const_i32(imm);
4642 imm = (uint32_t)shift;
4643 tmp2 = tcg_const_i32(imm);
4645 tmp2 = tcg_const_i64(shift);
4651 for (pass = 0; pass < 2; pass++) {
4653 neon_load_reg64(cpu_V0, rm + pass);
4656 gen_helper_neon_rshl_u64(cpu_V0, cpu_V0, tmp2);
4658 gen_helper_neon_rshl_s64(cpu_V0, cpu_V0, tmp2);
4661 gen_helper_neon_shl_u64(cpu_V0, cpu_V0, tmp2);
4663 gen_helper_neon_shl_s64(cpu_V0, cpu_V0, tmp2);
4666 tmp = neon_load_reg(rm + pass, 0);
4667 gen_neon_shift_narrow(size, tmp, tmp2, q, u);
4668 tcg_gen_extu_i32_i64(cpu_V0, tmp);
4670 tmp = neon_load_reg(rm + pass, 1);
4671 gen_neon_shift_narrow(size, tmp, tmp2, q, u);
4672 tcg_gen_extu_i32_i64(cpu_V1, tmp);
4674 tcg_gen_shli_i64(cpu_V1, cpu_V1, 32);
4675 tcg_gen_or_i64(cpu_V0, cpu_V0, cpu_V1);
4678 if (op == 8 && !u) {
4679 gen_neon_narrow(size - 1, tmp, cpu_V0);
4682 gen_neon_narrow_sats(size - 1, tmp, cpu_V0);
4684 gen_neon_narrow_satu(size - 1, tmp, cpu_V0);
4689 neon_store_reg(rd, 0, tmp2);
4690 neon_store_reg(rd, 1, tmp);
4693 } else if (op == 10) {
4697 tmp = neon_load_reg(rm, 0);
4698 tmp2 = neon_load_reg(rm, 1);
4699 for (pass = 0; pass < 2; pass++) {
4703 gen_neon_widen(cpu_V0, tmp, size, u);
4706 /* The shift is less than the width of the source
4707 type, so we can just shift the whole register. */
4708 tcg_gen_shli_i64(cpu_V0, cpu_V0, shift);
4709 if (size < 2 || !u) {
4712 imm = (0xffu >> (8 - shift));
4715 imm = 0xffff >> (16 - shift);
4717 imm64 = imm | (((uint64_t)imm) << 32);
4718 tcg_gen_andi_i64(cpu_V0, cpu_V0, imm64);
4721 neon_store_reg64(cpu_V0, rd + pass);
4723 } else if (op == 15 || op == 16) {
4724 /* VCVT fixed-point. */
4725 for (pass = 0; pass < (q ? 4 : 2); pass++) {
4726 tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, pass));
4729 gen_vfp_ulto(0, shift);
4731 gen_vfp_slto(0, shift);
4734 gen_vfp_toul(0, shift);
4736 gen_vfp_tosl(0, shift);
4738 tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, pass));
4743 } else { /* (insn & 0x00380080) == 0 */
4746 op = (insn >> 8) & 0xf;
4747 /* One register and immediate. */
4748 imm = (u << 7) | ((insn >> 12) & 0x70) | (insn & 0xf);
4749 invert = (insn & (1 << 5)) != 0;
4767 imm = (imm << 8) | (imm << 24);
4770 imm = (imm < 8) | 0xff;
4773 imm = (imm << 16) | 0xffff;
4776 imm |= (imm << 8) | (imm << 16) | (imm << 24);
4781 imm = ((imm & 0x80) << 24) | ((imm & 0x3f) << 19)
4782 | ((imm & 0x40) ? (0x1f << 25) : (1 << 30));
4788 if (op != 14 || !invert)
4789 gen_op_movl_T1_im(imm);
4791 for (pass = 0; pass < (q ? 4 : 2); pass++) {
4792 if (op & 1 && op < 12) {
4793 tmp = neon_load_reg(rd, pass);
4795 /* The immediate value has already been inverted, so
4797 tcg_gen_andi_i32(tmp, tmp, imm);
4799 tcg_gen_ori_i32(tmp, tmp, imm);
4804 if (op == 14 && invert) {
4807 for (n = 0; n < 4; n++) {
4808 if (imm & (1 << (n + (pass & 1) * 4)))
4809 val |= 0xff << (n * 8);
4811 tcg_gen_movi_i32(tmp, val);
4813 tcg_gen_movi_i32(tmp, imm);
4816 neon_store_reg(rd, pass, tmp);
4819 } else { /* (insn & 0x00800010 == 0x00800010) */
4821 op = (insn >> 8) & 0xf;
4822 if ((insn & (1 << 6)) == 0) {
4823 /* Three registers of different lengths. */
4827 /* prewiden, src1_wide, src2_wide */
4828 static const int neon_3reg_wide[16][3] = {
4829 {1, 0, 0}, /* VADDL */
4830 {1, 1, 0}, /* VADDW */
4831 {1, 0, 0}, /* VSUBL */
4832 {1, 1, 0}, /* VSUBW */
4833 {0, 1, 1}, /* VADDHN */
4834 {0, 0, 0}, /* VABAL */
4835 {0, 1, 1}, /* VSUBHN */
4836 {0, 0, 0}, /* VABDL */
4837 {0, 0, 0}, /* VMLAL */
4838 {0, 0, 0}, /* VQDMLAL */
4839 {0, 0, 0}, /* VMLSL */
4840 {0, 0, 0}, /* VQDMLSL */
4841 {0, 0, 0}, /* Integer VMULL */
4842 {0, 0, 0}, /* VQDMULL */
4843 {0, 0, 0} /* Polynomial VMULL */
4846 prewiden = neon_3reg_wide[op][0];
4847 src1_wide = neon_3reg_wide[op][1];
4848 src2_wide = neon_3reg_wide[op][2];
4850 if (size == 0 && (op == 9 || op == 11 || op == 13))
4853 /* Avoid overlapping operands. Wide source operands are
4854 always aligned so will never overlap with wide
4855 destinations in problematic ways. */
4856 if (rd == rm && !src2_wide) {
4857 NEON_GET_REG(T0, rm, 1);
4858 gen_neon_movl_scratch_T0(2);
4859 } else if (rd == rn && !src1_wide) {
4860 NEON_GET_REG(T0, rn, 1);
4861 gen_neon_movl_scratch_T0(2);
4863 for (pass = 0; pass < 2; pass++) {
4865 neon_load_reg64(cpu_V0, rn + pass);
4867 if (pass == 1 && rd == rn) {
4868 gen_neon_movl_T0_scratch(2);
4870 tcg_gen_mov_i32(tmp, cpu_T[0]);
4872 tmp = neon_load_reg(rn, pass);
4875 gen_neon_widen(cpu_V0, tmp, size, u);
4879 neon_load_reg64(cpu_V1, rm + pass);
4881 if (pass == 1 && rd == rm) {
4882 gen_neon_movl_T0_scratch(2);
4884 tcg_gen_mov_i32(tmp2, cpu_T[0]);
4886 tmp2 = neon_load_reg(rm, pass);
4889 gen_neon_widen(cpu_V1, tmp2, size, u);
4893 case 0: case 1: case 4: /* VADDL, VADDW, VADDHN, VRADDHN */
4894 gen_neon_addl(size);
4896 case 2: case 3: case 6: /* VSUBL, VSUBW, VSUBHL, VRSUBHL */
4897 gen_neon_subl(size);
4899 case 5: case 7: /* VABAL, VABDL */
4900 switch ((size << 1) | u) {
4902 gen_helper_neon_abdl_s16(cpu_V0, tmp, tmp2);
4905 gen_helper_neon_abdl_u16(cpu_V0, tmp, tmp2);
4908 gen_helper_neon_abdl_s32(cpu_V0, tmp, tmp2);
4911 gen_helper_neon_abdl_u32(cpu_V0, tmp, tmp2);
4914 gen_helper_neon_abdl_s64(cpu_V0, tmp, tmp2);
4917 gen_helper_neon_abdl_u64(cpu_V0, tmp, tmp2);
4924 case 8: case 9: case 10: case 11: case 12: case 13:
4925 /* VMLAL, VQDMLAL, VMLSL, VQDMLSL, VMULL, VQDMULL */
4926 gen_neon_mull(cpu_V0, tmp, tmp2, size, u);
4928 case 14: /* Polynomial VMULL */
4929 cpu_abort(env, "Polynomial VMULL not implemented");
4931 default: /* 15 is RESERVED. */
4934 if (op == 5 || op == 13 || (op >= 8 && op <= 11)) {
4936 if (op == 10 || op == 11) {
4937 gen_neon_negl(cpu_V0, size);
4941 neon_load_reg64(cpu_V1, rd + pass);
4945 case 5: case 8: case 10: /* VABAL, VMLAL, VMLSL */
4946 gen_neon_addl(size);
4948 case 9: case 11: /* VQDMLAL, VQDMLSL */
4949 gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
4950 gen_neon_addl_saturate(cpu_V0, cpu_V1, size);
4953 case 13: /* VQDMULL */
4954 gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
4959 neon_store_reg64(cpu_V0, rd + pass);
4960 } else if (op == 4 || op == 6) {
4961 /* Narrowing operation. */
4966 gen_helper_neon_narrow_high_u8(tmp, cpu_V0);
4969 gen_helper_neon_narrow_high_u16(tmp, cpu_V0);
4972 tcg_gen_shri_i64(cpu_V0, cpu_V0, 32);
4973 tcg_gen_trunc_i64_i32(tmp, cpu_V0);
4980 gen_helper_neon_narrow_round_high_u8(tmp, cpu_V0);
4983 gen_helper_neon_narrow_round_high_u16(tmp, cpu_V0);
4986 tcg_gen_addi_i64(cpu_V0, cpu_V0, 1u << 31);
4987 tcg_gen_shri_i64(cpu_V0, cpu_V0, 32);
4988 tcg_gen_trunc_i64_i32(tmp, cpu_V0);
4996 neon_store_reg(rd, 0, tmp3);
4997 neon_store_reg(rd, 1, tmp);
5000 /* Write back the result. */
5001 neon_store_reg64(cpu_V0, rd + pass);
5005 /* Two registers and a scalar. */
5007 case 0: /* Integer VMLA scalar */
5008 case 1: /* Float VMLA scalar */
5009 case 4: /* Integer VMLS scalar */
5010 case 5: /* Floating point VMLS scalar */
5011 case 8: /* Integer VMUL scalar */
5012 case 9: /* Floating point VMUL scalar */
5013 case 12: /* VQDMULH scalar */
5014 case 13: /* VQRDMULH scalar */
5015 gen_neon_get_scalar(size, rm);
5016 gen_neon_movl_scratch_T0(0);
5017 for (pass = 0; pass < (u ? 4 : 2); pass++) {
5019 gen_neon_movl_T0_scratch(0);
5020 NEON_GET_REG(T1, rn, pass);
5023 gen_helper_neon_qdmulh_s16(CPU_T0E01);
5025 gen_helper_neon_qdmulh_s32(CPU_T0E01);
5027 } else if (op == 13) {
5029 gen_helper_neon_qrdmulh_s16(CPU_T0E01);
5031 gen_helper_neon_qrdmulh_s32(CPU_T0E01);
5033 } else if (op & 1) {
5034 gen_helper_neon_mul_f32(CPU_T001);
5037 case 0: gen_helper_neon_mul_u8(CPU_T001); break;
5038 case 1: gen_helper_neon_mul_u16(CPU_T001); break;
5039 case 2: gen_op_mul_T0_T1(); break;
5045 NEON_GET_REG(T1, rd, pass);
5051 gen_helper_neon_add_f32(CPU_T001);
5057 gen_helper_neon_sub_f32(cpu_T[0], cpu_T[1], cpu_T[0]);
5063 NEON_SET_REG(T0, rd, pass);
5066 case 2: /* VMLAL sclar */
5067 case 3: /* VQDMLAL scalar */
5068 case 6: /* VMLSL scalar */
5069 case 7: /* VQDMLSL scalar */
5070 case 10: /* VMULL scalar */
5071 case 11: /* VQDMULL scalar */
5072 if (size == 0 && (op == 3 || op == 7 || op == 11))
5075 gen_neon_get_scalar(size, rm);
5076 NEON_GET_REG(T1, rn, 1);
5078 for (pass = 0; pass < 2; pass++) {
5080 tmp = neon_load_reg(rn, 0);
5083 tcg_gen_mov_i32(tmp, cpu_T[1]);
5086 tcg_gen_mov_i32(tmp2, cpu_T[0]);
5087 gen_neon_mull(cpu_V0, tmp, tmp2, size, u);
5088 if (op == 6 || op == 7) {
5089 gen_neon_negl(cpu_V0, size);
5092 neon_load_reg64(cpu_V1, rd + pass);
5096 gen_neon_addl(size);
5099 gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
5100 gen_neon_addl_saturate(cpu_V0, cpu_V1, size);
5106 gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
5111 neon_store_reg64(cpu_V0, rd + pass);
5114 default: /* 14 and 15 are RESERVED */
5118 } else { /* size == 3 */
5121 imm = (insn >> 8) & 0xf;
5128 neon_load_reg64(cpu_V0, rn);
5130 neon_load_reg64(cpu_V1, rn + 1);
5132 } else if (imm == 8) {
5133 neon_load_reg64(cpu_V0, rn + 1);
5135 neon_load_reg64(cpu_V1, rm);
5138 tmp = tcg_temp_new(TCG_TYPE_I64);
5140 neon_load_reg64(cpu_V0, rn);
5141 neon_load_reg64(tmp, rn + 1);
5143 neon_load_reg64(cpu_V0, rn + 1);
5144 neon_load_reg64(tmp, rm);
5146 tcg_gen_shri_i64(cpu_V0, cpu_V0, (imm & 7) * 8);
5147 tcg_gen_shli_i64(cpu_V1, tmp, 64 - ((imm & 7) * 8));
5148 tcg_gen_or_i64(cpu_V0, cpu_V0, cpu_V1);
5150 neon_load_reg64(cpu_V1, rm);
5152 neon_load_reg64(cpu_V1, rm + 1);
5155 tcg_gen_shli_i64(cpu_V1, cpu_V1, 64 - (imm * 8));
5156 tcg_gen_shri_i64(tmp, tmp, imm * 8);
5157 tcg_gen_or_i64(cpu_V1, cpu_V1, tmp);
5159 neon_load_reg64(cpu_V0, rn);
5160 tcg_gen_shri_i32(cpu_V0, cpu_V0, imm * 8);
5161 neon_load_reg64(cpu_V1, rm);
5162 tcg_gen_shli_i32(cpu_V1, cpu_V1, 64 - (imm * 8));
5163 tcg_gen_or_i64(cpu_V0, cpu_V0, cpu_V1);
5165 neon_store_reg64(cpu_V0, rd);
5167 neon_store_reg64(cpu_V1, rd + 1);
5169 } else if ((insn & (1 << 11)) == 0) {
5170 /* Two register misc. */
5171 op = ((insn >> 12) & 0x30) | ((insn >> 7) & 0xf);
5172 size = (insn >> 18) & 3;
5174 case 0: /* VREV64 */
5177 for (pass = 0; pass < (q ? 2 : 1); pass++) {
5178 NEON_GET_REG(T0, rm, pass * 2);
5179 NEON_GET_REG(T1, rm, pass * 2 + 1);
5181 case 0: tcg_gen_bswap_i32(cpu_T[0], cpu_T[0]); break;
5182 case 1: gen_swap_half(cpu_T[0]); break;
5183 case 2: /* no-op */ break;
5186 NEON_SET_REG(T0, rd, pass * 2 + 1);
5188 NEON_SET_REG(T1, rd, pass * 2);
5190 gen_op_movl_T0_T1();
5192 case 0: tcg_gen_bswap_i32(cpu_T[0], cpu_T[0]); break;
5193 case 1: gen_swap_half(cpu_T[0]); break;
5196 NEON_SET_REG(T0, rd, pass * 2);
5200 case 4: case 5: /* VPADDL */
5201 case 12: case 13: /* VPADAL */
5204 for (pass = 0; pass < q + 1; pass++) {
5205 tmp = neon_load_reg(rm, pass * 2);
5206 gen_neon_widen(cpu_V0, tmp, size, op & 1);
5207 tmp = neon_load_reg(rm, pass * 2 + 1);
5208 gen_neon_widen(cpu_V1, tmp, size, op & 1);
5210 case 0: gen_helper_neon_paddl_u16(CPU_V001); break;
5211 case 1: gen_helper_neon_paddl_u32(CPU_V001); break;
5212 case 2: tcg_gen_add_i64(CPU_V001); break;
5217 neon_load_reg64(cpu_V1, rd + pass);
5218 gen_neon_addl(size);
5220 neon_store_reg64(cpu_V0, rd + pass);
5225 for (n = 0; n < (q ? 4 : 2); n += 2) {
5226 NEON_GET_REG(T0, rm, n);
5227 NEON_GET_REG(T1, rd, n + 1);
5228 NEON_SET_REG(T1, rm, n);
5229 NEON_SET_REG(T0, rd, n + 1);
5237 Rd A3 A2 A1 A0 B2 B0 A2 A0
5238 Rm B3 B2 B1 B0 B3 B1 A3 A1
5242 gen_neon_unzip(rd, q, 0, size);
5243 gen_neon_unzip(rm, q, 4, size);
5245 static int unzip_order_q[8] =
5246 {0, 2, 4, 6, 1, 3, 5, 7};
5247 for (n = 0; n < 8; n++) {
5248 int reg = (n < 4) ? rd : rm;
5249 gen_neon_movl_T0_scratch(unzip_order_q[n]);
5250 NEON_SET_REG(T0, reg, n % 4);
5253 static int unzip_order[4] =
5255 for (n = 0; n < 4; n++) {
5256 int reg = (n < 2) ? rd : rm;
5257 gen_neon_movl_T0_scratch(unzip_order[n]);
5258 NEON_SET_REG(T0, reg, n % 2);
5264 Rd A3 A2 A1 A0 B1 A1 B0 A0
5265 Rm B3 B2 B1 B0 B3 A3 B2 A2
5269 count = (q ? 4 : 2);
5270 for (n = 0; n < count; n++) {
5271 NEON_GET_REG(T0, rd, n);
5272 NEON_GET_REG(T1, rd, n);
5274 case 0: gen_helper_neon_zip_u8(); break;
5275 case 1: gen_helper_neon_zip_u16(); break;
5276 case 2: /* no-op */; break;
5279 gen_neon_movl_scratch_T0(n * 2);
5280 gen_neon_movl_scratch_T1(n * 2 + 1);
5282 for (n = 0; n < count * 2; n++) {
5283 int reg = (n < count) ? rd : rm;
5284 gen_neon_movl_T0_scratch(n);
5285 NEON_SET_REG(T0, reg, n % count);
5288 case 36: case 37: /* VMOVN, VQMOVUN, VQMOVN */
5291 for (pass = 0; pass < 2; pass++) {
5292 neon_load_reg64(cpu_V0, rm + pass);
5294 if (op == 36 && q == 0) {
5295 gen_neon_narrow(size, tmp, cpu_V0);
5297 gen_neon_narrow_satu(size, tmp, cpu_V0);
5299 gen_neon_narrow_sats(size, tmp, cpu_V0);
5304 neon_store_reg(rd, 0, tmp2);
5305 neon_store_reg(rd, 1, tmp);
5309 case 38: /* VSHLL */
5312 tmp = neon_load_reg(rm, 0);
5313 tmp2 = neon_load_reg(rm, 1);
5314 for (pass = 0; pass < 2; pass++) {
5317 gen_neon_widen(cpu_V0, tmp, size, 1);
5318 neon_store_reg64(cpu_V0, rd + pass);
5323 for (pass = 0; pass < (q ? 4 : 2); pass++) {
5324 if (op == 30 || op == 31 || op >= 58) {
5325 tcg_gen_ld_f32(cpu_F0s, cpu_env,
5326 neon_reg_offset(rm, pass));
5328 NEON_GET_REG(T0, rm, pass);
5331 case 1: /* VREV32 */
5333 case 0: tcg_gen_bswap_i32(cpu_T[0], cpu_T[0]); break;
5334 case 1: gen_swap_half(cpu_T[0]); break;
5338 case 2: /* VREV16 */
5341 gen_rev16(cpu_T[0]);
5345 case 0: gen_helper_neon_cls_s8(cpu_T[0], cpu_T[0]); break;
5346 case 1: gen_helper_neon_cls_s16(cpu_T[0], cpu_T[0]); break;
5347 case 2: gen_helper_neon_cls_s32(cpu_T[0], cpu_T[0]); break;
5353 case 0: gen_helper_neon_clz_u8(cpu_T[0], cpu_T[0]); break;
5354 case 1: gen_helper_neon_clz_u16(cpu_T[0], cpu_T[0]); break;
5355 case 2: gen_helper_clz(cpu_T[0], cpu_T[0]); break;
5362 gen_helper_neon_cnt_u8(cpu_T[0], cpu_T[0]);
5369 case 14: /* VQABS */
5371 case 0: gen_helper_neon_qabs_s8(cpu_T[0], cpu_env, cpu_T[0]); break;
5372 case 1: gen_helper_neon_qabs_s16(cpu_T[0], cpu_env, cpu_T[0]); break;
5373 case 2: gen_helper_neon_qabs_s32(cpu_T[0], cpu_env, cpu_T[0]); break;
5377 case 15: /* VQNEG */
5379 case 0: gen_helper_neon_qneg_s8(cpu_T[0], cpu_env, cpu_T[0]); break;
5380 case 1: gen_helper_neon_qneg_s16(cpu_T[0], cpu_env, cpu_T[0]); break;
5381 case 2: gen_helper_neon_qneg_s32(cpu_T[0], cpu_env, cpu_T[0]); break;
5385 case 16: case 19: /* VCGT #0, VCLE #0 */
5386 gen_op_movl_T1_im(0);
5388 case 0: gen_helper_neon_cgt_s8(CPU_T001); break;
5389 case 1: gen_helper_neon_cgt_s16(CPU_T001); break;
5390 case 2: gen_helper_neon_cgt_s32(CPU_T001); break;
5396 case 17: case 20: /* VCGE #0, VCLT #0 */
5397 gen_op_movl_T1_im(0);
5399 case 0: gen_helper_neon_cge_s8(CPU_T001); break;
5400 case 1: gen_helper_neon_cge_s16(CPU_T001); break;
5401 case 2: gen_helper_neon_cge_s32(CPU_T001); break;
5407 case 18: /* VCEQ #0 */
5408 gen_op_movl_T1_im(0);
5410 case 0: gen_helper_neon_ceq_u8(CPU_T001); break;
5411 case 1: gen_helper_neon_ceq_u16(CPU_T001); break;
5412 case 2: gen_helper_neon_ceq_u32(CPU_T001); break;
5418 case 0: gen_helper_neon_abs_s8(cpu_T[0], cpu_T[0]); break;
5419 case 1: gen_helper_neon_abs_s16(cpu_T[0], cpu_T[0]); break;
5420 case 2: tcg_gen_abs_i32(cpu_T[0], cpu_T[0]); break;
5425 gen_op_movl_T1_im(0);
5430 case 24: case 27: /* Float VCGT #0, Float VCLE #0 */
5431 gen_op_movl_T1_im(0);
5432 gen_helper_neon_cgt_f32(CPU_T001);
5436 case 25: case 28: /* Float VCGE #0, Float VCLT #0 */
5437 gen_op_movl_T1_im(0);
5438 gen_helper_neon_cge_f32(CPU_T001);
5442 case 26: /* Float VCEQ #0 */
5443 gen_op_movl_T1_im(0);
5444 gen_helper_neon_ceq_f32(CPU_T001);
5446 case 30: /* Float VABS */
5449 case 31: /* Float VNEG */
5453 NEON_GET_REG(T1, rd, pass);
5454 NEON_SET_REG(T1, rm, pass);
5457 NEON_GET_REG(T1, rd, pass);
5459 case 0: gen_helper_neon_trn_u8(); break;
5460 case 1: gen_helper_neon_trn_u16(); break;
5464 NEON_SET_REG(T1, rm, pass);
5466 case 56: /* Integer VRECPE */
5467 gen_helper_recpe_u32(cpu_T[0], cpu_T[0], cpu_env);
5469 case 57: /* Integer VRSQRTE */
5470 gen_helper_rsqrte_u32(cpu_T[0], cpu_T[0], cpu_env);
5472 case 58: /* Float VRECPE */
5473 gen_helper_recpe_f32(cpu_F0s, cpu_F0s, cpu_env);
5475 case 59: /* Float VRSQRTE */
5476 gen_helper_rsqrte_f32(cpu_F0s, cpu_F0s, cpu_env);
5478 case 60: /* VCVT.F32.S32 */
5481 case 61: /* VCVT.F32.U32 */
5484 case 62: /* VCVT.S32.F32 */
5487 case 63: /* VCVT.U32.F32 */
5491 /* Reserved: 21, 29, 39-56 */
5494 if (op == 30 || op == 31 || op >= 58) {
5495 tcg_gen_st_f32(cpu_F0s, cpu_env,
5496 neon_reg_offset(rd, pass));
5498 NEON_SET_REG(T0, rd, pass);
5503 } else if ((insn & (1 << 10)) == 0) {
5505 n = (insn >> 5) & 0x18;
5506 if (insn & (1 << 6)) {
5507 tmp = neon_load_reg(rd, 0);
5510 tcg_gen_movi_i32(tmp, 0);
5512 tmp2 = neon_load_reg(rm, 0);
5513 gen_helper_neon_tbl(tmp2, tmp2, tmp, tcg_const_i32(rn),
5515 if (insn & (1 << 6)) {
5516 tmp = neon_load_reg(rd, 1);
5519 tcg_gen_movi_i32(tmp, 0);
5521 tmp3 = neon_load_reg(rm, 1);
5522 gen_helper_neon_tbl(tmp3, tmp3, tmp, tcg_const_i32(rn),
5524 neon_store_reg(rd, 0, tmp2);
5525 neon_store_reg(rd, 1, tmp2);
5526 } else if ((insn & 0x380) == 0) {
5528 if (insn & (1 << 19)) {
5529 NEON_SET_REG(T0, rm, 1);
5531 NEON_SET_REG(T0, rm, 0);
5533 if (insn & (1 << 16)) {
5534 gen_neon_dup_u8(cpu_T[0], ((insn >> 17) & 3) * 8);
5535 } else if (insn & (1 << 17)) {
5536 if ((insn >> 18) & 1)
5537 gen_neon_dup_high16(cpu_T[0]);
5539 gen_neon_dup_low16(cpu_T[0]);
5541 for (pass = 0; pass < (q ? 4 : 2); pass++) {
5542 NEON_SET_REG(T0, rd, pass);
5552 static int disas_coproc_insn(CPUState * env, DisasContext *s, uint32_t insn)
5556 cpnum = (insn >> 8) & 0xf;
5557 if (arm_feature(env, ARM_FEATURE_XSCALE)
5558 && ((env->cp15.c15_cpar ^ 0x3fff) & (1 << cpnum)))
5564 if (arm_feature(env, ARM_FEATURE_IWMMXT)) {
5565 return disas_iwmmxt_insn(env, s, insn);
5566 } else if (arm_feature(env, ARM_FEATURE_XSCALE)) {
5567 return disas_dsp_insn(env, s, insn);
5572 return disas_vfp_insn (env, s, insn);
5574 return disas_cp15_insn (env, s, insn);
5576 /* Unknown coprocessor. See if the board has hooked it. */
5577 return disas_cp_insn (env, s, insn);
5582 /* Store a 64-bit value to a register pair. Clobbers val. */
5583 static void gen_storeq_reg(DisasContext *s, int rlow, int rhigh, TCGv val)
5587 tcg_gen_trunc_i64_i32(tmp, val);
5588 store_reg(s, rlow, tmp);
5590 tcg_gen_shri_i64(val, val, 32);
5591 tcg_gen_trunc_i64_i32(tmp, val);
5592 store_reg(s, rhigh, tmp);
5595 /* load a 32-bit value from a register and perform a 64-bit accumulate. */
5596 static void gen_addq_lo(DisasContext *s, TCGv val, int rlow)
5601 /* Load 64-bit value rd:rn. */
5602 tmp = tcg_temp_new(TCG_TYPE_I64);
5603 tmp2 = load_reg(s, rlow);
5604 tcg_gen_extu_i32_i64(tmp, tmp2);
5606 tcg_gen_add_i64(val, val, tmp);
5609 /* load and add a 64-bit value from a register pair. */
5610 static void gen_addq(DisasContext *s, TCGv val, int rlow, int rhigh)
5615 /* Load 64-bit value rd:rn. */
5616 tmp = tcg_temp_new(TCG_TYPE_I64);
5617 tmp2 = load_reg(s, rhigh);
5618 tcg_gen_extu_i32_i64(tmp, tmp2);
5620 tcg_gen_shli_i64(tmp, tmp, 32);
5621 tcg_gen_add_i64(val, val, tmp);
5623 tmp2 = load_reg(s, rlow);
5624 tcg_gen_extu_i32_i64(tmp, tmp2);
5626 tcg_gen_add_i64(val, val, tmp);
5629 /* Set N and Z flags from a 64-bit value. */
5630 static void gen_logicq_cc(TCGv val)
5632 TCGv tmp = new_tmp();
5633 gen_helper_logicq_cc(tmp, val);
5638 static void disas_arm_insn(CPUState * env, DisasContext *s)
5640 unsigned int cond, insn, val, op1, i, shift, rm, rs, rn, rd, sh;
5646 insn = ldl_code(s->pc);
5649 /* M variants do not implement ARM mode. */
5654 /* Unconditional instructions. */
5655 if (((insn >> 25) & 7) == 1) {
5656 /* NEON Data processing. */
5657 if (!arm_feature(env, ARM_FEATURE_NEON))
5660 if (disas_neon_data_insn(env, s, insn))
5664 if ((insn & 0x0f100000) == 0x04000000) {
5665 /* NEON load/store. */
5666 if (!arm_feature(env, ARM_FEATURE_NEON))
5669 if (disas_neon_ls_insn(env, s, insn))
5673 if ((insn & 0x0d70f000) == 0x0550f000)
5675 else if ((insn & 0x0ffffdff) == 0x01010000) {
5678 if (insn & (1 << 9)) {
5679 /* BE8 mode not implemented. */
5683 } else if ((insn & 0x0fffff00) == 0x057ff000) {
5684 switch ((insn >> 4) & 0xf) {
5687 gen_helper_clrex(cpu_env);
5693 /* We don't emulate caches so these are a no-op. */
5698 } else if ((insn & 0x0e5fffe0) == 0x084d0500) {
5704 op1 = (insn & 0x1f);
5705 if (op1 == (env->uncached_cpsr & CPSR_M)) {
5706 addr = load_reg(s, 13);
5709 gen_helper_get_r13_banked(addr, cpu_env, tcg_const_i32(op1));
5711 i = (insn >> 23) & 3;
5713 case 0: offset = -4; break; /* DA */
5714 case 1: offset = -8; break; /* DB */
5715 case 2: offset = 0; break; /* IA */
5716 case 3: offset = 4; break; /* IB */
5720 tcg_gen_addi_i32(addr, addr, offset);
5721 tmp = load_reg(s, 14);
5722 gen_st32(tmp, addr, 0);
5724 gen_helper_cpsr_read(tmp);
5725 tcg_gen_addi_i32(addr, addr, 4);
5726 gen_st32(tmp, addr, 0);
5727 if (insn & (1 << 21)) {
5728 /* Base writeback. */
5730 case 0: offset = -8; break;
5731 case 1: offset = -4; break;
5732 case 2: offset = 4; break;
5733 case 3: offset = 0; break;
5737 tcg_gen_addi_i32(addr, tmp, offset);
5738 if (op1 == (env->uncached_cpsr & CPSR_M)) {
5739 gen_movl_reg_T1(s, 13);
5741 gen_helper_set_r13_banked(cpu_env, tcg_const_i32(op1), cpu_T[1]);
5746 } else if ((insn & 0x0e5fffe0) == 0x081d0a00) {
5752 rn = (insn >> 16) & 0xf;
5753 addr = load_reg(s, rn);
5754 i = (insn >> 23) & 3;
5756 case 0: offset = -4; break; /* DA */
5757 case 1: offset = -8; break; /* DB */
5758 case 2: offset = 0; break; /* IA */
5759 case 3: offset = 4; break; /* IB */
5763 tcg_gen_addi_i32(addr, addr, offset);
5764 /* Load PC into tmp and CPSR into tmp2. */
5765 tmp = gen_ld32(addr, 0);
5766 tcg_gen_addi_i32(addr, addr, 4);
5767 tmp2 = gen_ld32(addr, 0);
5768 if (insn & (1 << 21)) {
5769 /* Base writeback. */
5771 case 0: offset = -8; break;
5772 case 1: offset = -4; break;
5773 case 2: offset = 4; break;
5774 case 3: offset = 0; break;
5778 tcg_gen_addi_i32(addr, addr, offset);
5779 store_reg(s, rn, addr);
5783 gen_rfe(s, tmp, tmp2);
5784 } else if ((insn & 0x0e000000) == 0x0a000000) {
5785 /* branch link and change to thumb (blx <offset>) */
5788 val = (uint32_t)s->pc;
5790 tcg_gen_movi_i32(tmp, val);
5791 store_reg(s, 14, tmp);
5792 /* Sign-extend the 24-bit offset */
5793 offset = (((int32_t)insn) << 8) >> 8;
5794 /* offset * 4 + bit24 * 2 + (thumb bit) */
5795 val += (offset << 2) | ((insn >> 23) & 2) | 1;
5796 /* pipeline offset */
5800 } else if ((insn & 0x0e000f00) == 0x0c000100) {
5801 if (arm_feature(env, ARM_FEATURE_IWMMXT)) {
5802 /* iWMMXt register transfer. */
5803 if (env->cp15.c15_cpar & (1 << 1))
5804 if (!disas_iwmmxt_insn(env, s, insn))
5807 } else if ((insn & 0x0fe00000) == 0x0c400000) {
5808 /* Coprocessor double register transfer. */
5809 } else if ((insn & 0x0f000010) == 0x0e000010) {
5810 /* Additional coprocessor register transfer. */
5811 } else if ((insn & 0x0ff10010) == 0x01000000) {
5814 /* cps (privileged) */
5818 if (insn & (1 << 19)) {
5819 if (insn & (1 << 8))
5821 if (insn & (1 << 7))
5823 if (insn & (1 << 6))
5825 if (insn & (1 << 18))
5828 if (insn & (1 << 14)) {
5830 val |= (insn & 0x1f);
5833 gen_op_movl_T0_im(val);
5834 gen_set_psr_T0(s, mask, 0);
5841 /* if not always execute, we generate a conditional jump to
5843 s->condlabel = gen_new_label();
5844 gen_test_cc(cond ^ 1, s->condlabel);
5847 if ((insn & 0x0f900000) == 0x03000000) {
5848 if ((insn & (1 << 21)) == 0) {
5850 rd = (insn >> 12) & 0xf;
5851 val = ((insn >> 4) & 0xf000) | (insn & 0xfff);
5852 if ((insn & (1 << 22)) == 0) {
5855 tcg_gen_movi_i32(tmp, val);
5858 tmp = load_reg(s, rd);
5859 tcg_gen_ext16u_i32(tmp, tmp);
5860 tcg_gen_ori_i32(tmp, tmp, val << 16);
5862 store_reg(s, rd, tmp);
5864 if (((insn >> 12) & 0xf) != 0xf)
5866 if (((insn >> 16) & 0xf) == 0) {
5867 gen_nop_hint(s, insn & 0xff);
5869 /* CPSR = immediate */
5871 shift = ((insn >> 8) & 0xf) * 2;
5873 val = (val >> shift) | (val << (32 - shift));
5874 gen_op_movl_T0_im(val);
5875 i = ((insn & (1 << 22)) != 0);
5876 if (gen_set_psr_T0(s, msr_mask(env, s, (insn >> 16) & 0xf, i), i))
5880 } else if ((insn & 0x0f900000) == 0x01000000
5881 && (insn & 0x00000090) != 0x00000090) {
5882 /* miscellaneous instructions */
5883 op1 = (insn >> 21) & 3;
5884 sh = (insn >> 4) & 0xf;
5887 case 0x0: /* move program status register */
5890 gen_movl_T0_reg(s, rm);
5891 i = ((op1 & 2) != 0);
5892 if (gen_set_psr_T0(s, msr_mask(env, s, (insn >> 16) & 0xf, i), i))
5896 rd = (insn >> 12) & 0xf;
5900 tmp = load_cpu_field(spsr);
5903 gen_helper_cpsr_read(tmp);
5905 store_reg(s, rd, tmp);
5910 /* branch/exchange thumb (bx). */
5911 tmp = load_reg(s, rm);
5913 } else if (op1 == 3) {
5915 rd = (insn >> 12) & 0xf;
5916 tmp = load_reg(s, rm);
5917 gen_helper_clz(tmp, tmp);
5918 store_reg(s, rd, tmp);
5926 /* Trivial implementation equivalent to bx. */
5927 tmp = load_reg(s, rm);
5937 /* branch link/exchange thumb (blx) */
5938 tmp = load_reg(s, rm);
5940 tcg_gen_movi_i32(tmp2, s->pc);
5941 store_reg(s, 14, tmp2);
5944 case 0x5: /* saturating add/subtract */
5945 rd = (insn >> 12) & 0xf;
5946 rn = (insn >> 16) & 0xf;
5947 tmp = load_reg(s, rn);
5948 tmp2 = load_reg(s, rn);
5950 gen_helper_double_saturate(tmp2, tmp2);
5952 gen_helper_sub_saturate(tmp, tmp, tmp2);
5954 gen_helper_add_saturate(tmp, tmp, tmp2);
5956 store_reg(s, rd, tmp);
5959 gen_set_condexec(s);
5960 gen_set_pc_im(s->pc - 4);
5961 gen_exception(EXCP_BKPT);
5962 s->is_jmp = DISAS_JUMP;
5964 case 0x8: /* signed multiply */
5968 rs = (insn >> 8) & 0xf;
5969 rn = (insn >> 12) & 0xf;
5970 rd = (insn >> 16) & 0xf;
5972 /* (32 * 16) >> 16 */
5973 tmp = load_reg(s, rm);
5974 tmp2 = load_reg(s, rs);
5976 tcg_gen_sari_i32(tmp2, tmp2, 16);
5979 tmp2 = gen_muls_i64_i32(tmp, tmp2);
5980 tcg_gen_shri_i64(tmp2, tmp2, 16);
5982 tcg_gen_trunc_i64_i32(tmp, tmp2);
5983 if ((sh & 2) == 0) {
5984 tmp2 = load_reg(s, rn);
5985 gen_helper_add_setq(tmp, tmp, tmp2);
5988 store_reg(s, rd, tmp);
5991 tmp = load_reg(s, rm);
5992 tmp2 = load_reg(s, rs);
5993 gen_mulxy(tmp, tmp2, sh & 2, sh & 4);
5996 tmp = tcg_temp_new(TCG_TYPE_I64);
5997 tcg_gen_ext_i32_i64(tmp, cpu_T[0]);
5998 gen_addq(s, tmp, rn, rd);
5999 gen_storeq_reg(s, rn, rd, tmp);
6002 tmp2 = load_reg(s, rn);
6003 gen_helper_add_setq(tmp, tmp, tmp2);
6006 store_reg(s, rd, tmp);
6013 } else if (((insn & 0x0e000000) == 0 &&
6014 (insn & 0x00000090) != 0x90) ||
6015 ((insn & 0x0e000000) == (1 << 25))) {
6016 int set_cc, logic_cc, shiftop;
6018 op1 = (insn >> 21) & 0xf;
6019 set_cc = (insn >> 20) & 1;
6020 logic_cc = table_logic_cc[op1] & set_cc;
6022 /* data processing instruction */
6023 if (insn & (1 << 25)) {
6024 /* immediate operand */
6026 shift = ((insn >> 8) & 0xf) * 2;
6028 val = (val >> shift) | (val << (32 - shift));
6029 gen_op_movl_T1_im(val);
6030 if (logic_cc && shift)
6031 gen_set_CF_bit31(cpu_T[1]);
6035 gen_movl_T1_reg(s, rm);
6036 shiftop = (insn >> 5) & 3;
6037 if (!(insn & (1 << 4))) {
6038 shift = (insn >> 7) & 0x1f;
6039 gen_arm_shift_im(cpu_T[1], shiftop, shift, logic_cc);
6041 rs = (insn >> 8) & 0xf;
6042 tmp = load_reg(s, rs);
6043 gen_arm_shift_reg(cpu_T[1], shiftop, tmp, logic_cc);
6046 if (op1 != 0x0f && op1 != 0x0d) {
6047 rn = (insn >> 16) & 0xf;
6048 gen_movl_T0_reg(s, rn);
6050 rd = (insn >> 12) & 0xf;
6053 gen_op_andl_T0_T1();
6054 gen_movl_reg_T0(s, rd);
6056 gen_op_logic_T0_cc();
6059 gen_op_xorl_T0_T1();
6060 gen_movl_reg_T0(s, rd);
6062 gen_op_logic_T0_cc();
6065 if (set_cc && rd == 15) {
6066 /* SUBS r15, ... is used for exception return. */
6069 gen_op_subl_T0_T1_cc();
6070 gen_exception_return(s);
6073 gen_op_subl_T0_T1_cc();
6075 gen_op_subl_T0_T1();
6076 gen_movl_reg_T0(s, rd);
6081 gen_op_rsbl_T0_T1_cc();
6083 gen_op_rsbl_T0_T1();
6084 gen_movl_reg_T0(s, rd);
6088 gen_op_addl_T0_T1_cc();
6090 gen_op_addl_T0_T1();
6091 gen_movl_reg_T0(s, rd);
6095 gen_op_adcl_T0_T1_cc();
6098 gen_movl_reg_T0(s, rd);
6102 gen_op_sbcl_T0_T1_cc();
6105 gen_movl_reg_T0(s, rd);
6109 gen_op_rscl_T0_T1_cc();
6112 gen_movl_reg_T0(s, rd);
6116 gen_op_andl_T0_T1();
6117 gen_op_logic_T0_cc();
6122 gen_op_xorl_T0_T1();
6123 gen_op_logic_T0_cc();
6128 gen_op_subl_T0_T1_cc();
6133 gen_op_addl_T0_T1_cc();
6138 gen_movl_reg_T0(s, rd);
6140 gen_op_logic_T0_cc();
6143 if (logic_cc && rd == 15) {
6144 /* MOVS r15, ... is used for exception return. */
6147 gen_op_movl_T0_T1();
6148 gen_exception_return(s);
6150 gen_movl_reg_T1(s, rd);
6152 gen_op_logic_T1_cc();
6156 gen_op_bicl_T0_T1();
6157 gen_movl_reg_T0(s, rd);
6159 gen_op_logic_T0_cc();
6164 gen_movl_reg_T1(s, rd);
6166 gen_op_logic_T1_cc();
6170 /* other instructions */
6171 op1 = (insn >> 24) & 0xf;
6175 /* multiplies, extra load/stores */
6176 sh = (insn >> 5) & 3;
6179 rd = (insn >> 16) & 0xf;
6180 rn = (insn >> 12) & 0xf;
6181 rs = (insn >> 8) & 0xf;
6183 op1 = (insn >> 20) & 0xf;
6185 case 0: case 1: case 2: case 3: case 6:
6187 tmp = load_reg(s, rs);
6188 tmp2 = load_reg(s, rm);
6189 tcg_gen_mul_i32(tmp, tmp, tmp2);
6191 if (insn & (1 << 22)) {
6192 /* Subtract (mls) */
6194 tmp2 = load_reg(s, rn);
6195 tcg_gen_sub_i32(tmp, tmp2, tmp);
6197 } else if (insn & (1 << 21)) {
6199 tmp2 = load_reg(s, rn);
6200 tcg_gen_add_i32(tmp, tmp, tmp2);
6203 if (insn & (1 << 20))
6205 store_reg(s, rd, tmp);
6209 tmp = load_reg(s, rs);
6210 tmp2 = load_reg(s, rm);
6211 if (insn & (1 << 22))
6212 tmp = gen_muls_i64_i32(tmp, tmp2);
6214 tmp = gen_mulu_i64_i32(tmp, tmp2);
6215 if (insn & (1 << 21)) /* mult accumulate */
6216 gen_addq(s, tmp, rn, rd);
6217 if (!(insn & (1 << 23))) { /* double accumulate */
6219 gen_addq_lo(s, tmp, rn);
6220 gen_addq_lo(s, tmp, rd);
6222 if (insn & (1 << 20))
6224 gen_storeq_reg(s, rn, rd, tmp);
6228 rn = (insn >> 16) & 0xf;
6229 rd = (insn >> 12) & 0xf;
6230 if (insn & (1 << 23)) {
6231 /* load/store exclusive */
6232 gen_movl_T1_reg(s, rn);
6234 if (insn & (1 << 20)) {
6235 gen_helper_mark_exclusive(cpu_env, cpu_T[1]);
6236 tmp = gen_ld32(addr, IS_USER(s));
6237 store_reg(s, rd, tmp);
6239 int label = gen_new_label();
6241 gen_helper_test_exclusive(cpu_T[0], cpu_env, addr);
6242 tcg_gen_brcond_i32(TCG_COND_NE, cpu_T[0],
6243 tcg_const_i32(0), label);
6244 tmp = load_reg(s,rm);
6245 gen_st32(tmp, cpu_T[1], IS_USER(s));
6246 gen_set_label(label);
6247 gen_movl_reg_T0(s, rd);
6250 /* SWP instruction */
6253 /* ??? This is not really atomic. However we know
6254 we never have multiple CPUs running in parallel,
6255 so it is good enough. */
6256 addr = load_reg(s, rn);
6257 tmp = load_reg(s, rm);
6258 if (insn & (1 << 22)) {
6259 tmp2 = gen_ld8u(addr, IS_USER(s));
6260 gen_st8(tmp, addr, IS_USER(s));
6262 tmp2 = gen_ld32(addr, IS_USER(s));
6263 gen_st32(tmp, addr, IS_USER(s));
6266 store_reg(s, rd, tmp2);
6272 /* Misc load/store */
6273 rn = (insn >> 16) & 0xf;
6274 rd = (insn >> 12) & 0xf;
6275 addr = load_reg(s, rn);
6276 if (insn & (1 << 24))
6277 gen_add_datah_offset(s, insn, 0, addr);
6279 if (insn & (1 << 20)) {
6283 tmp = gen_ld16u(addr, IS_USER(s));
6286 tmp = gen_ld8s(addr, IS_USER(s));
6290 tmp = gen_ld16s(addr, IS_USER(s));
6294 } else if (sh & 2) {
6298 tmp = load_reg(s, rd);
6299 gen_st32(tmp, addr, IS_USER(s));
6300 tcg_gen_addi_i32(addr, addr, 4);
6301 tmp = load_reg(s, rd + 1);
6302 gen_st32(tmp, addr, IS_USER(s));
6306 tmp = gen_ld32(addr, IS_USER(s));
6307 store_reg(s, rd, tmp);
6308 tcg_gen_addi_i32(addr, addr, 4);
6309 tmp = gen_ld32(addr, IS_USER(s));
6313 address_offset = -4;
6316 tmp = load_reg(s, rd);
6317 gen_st16(tmp, addr, IS_USER(s));
6320 /* Perform base writeback before the loaded value to
6321 ensure correct behavior with overlapping index registers.
6322 ldrd with base writeback is is undefined if the
6323 destination and index registers overlap. */
6324 if (!(insn & (1 << 24))) {
6325 gen_add_datah_offset(s, insn, address_offset, addr);
6326 store_reg(s, rn, addr);
6327 } else if (insn & (1 << 21)) {
6329 tcg_gen_addi_i32(addr, addr, address_offset);
6330 store_reg(s, rn, addr);
6335 /* Complete the load. */
6336 store_reg(s, rd, tmp);
6345 if (insn & (1 << 4)) {
6347 /* Armv6 Media instructions. */
6349 rn = (insn >> 16) & 0xf;
6350 rd = (insn >> 12) & 0xf;
6351 rs = (insn >> 8) & 0xf;
6352 switch ((insn >> 23) & 3) {
6353 case 0: /* Parallel add/subtract. */
6354 op1 = (insn >> 20) & 7;
6355 tmp = load_reg(s, rn);
6356 tmp2 = load_reg(s, rm);
6357 sh = (insn >> 5) & 7;
6358 if ((op1 & 3) == 0 || sh == 5 || sh == 6)
6360 gen_arm_parallel_addsub(op1, sh, tmp, tmp2);
6362 store_reg(s, rd, tmp);
6365 if ((insn & 0x00700020) == 0) {
6366 /* Halfword pack. */
6367 tmp = load_reg(s, rn);
6368 tmp2 = load_reg(s, rm);
6369 shift = (insn >> 7) & 0x1f;
6371 tcg_gen_shli_i32(tmp2, tmp2, shift);
6372 if (insn & (1 << 6)) {
6374 tcg_gen_andi_i32(tmp, tmp, 0xffff0000);
6375 tcg_gen_ext16u_i32(tmp2, tmp2);
6378 tcg_gen_ext16u_i32(tmp, tmp);
6379 tcg_gen_andi_i32(tmp2, tmp2, 0xffff0000);
6381 tcg_gen_or_i32(tmp, tmp, tmp2);
6382 store_reg(s, rd, tmp);
6383 } else if ((insn & 0x00200020) == 0x00200000) {
6385 tmp = load_reg(s, rm);
6386 shift = (insn >> 7) & 0x1f;
6387 if (insn & (1 << 6)) {
6390 tcg_gen_sari_i32(tmp, tmp, shift);
6392 tcg_gen_shli_i32(tmp, tmp, shift);
6394 sh = (insn >> 16) & 0x1f;
6396 if (insn & (1 << 22))
6397 gen_helper_usat(tmp, tmp, tcg_const_i32(sh));
6399 gen_helper_ssat(tmp, tmp, tcg_const_i32(sh));
6401 store_reg(s, rd, tmp);
6402 } else if ((insn & 0x00300fe0) == 0x00200f20) {
6404 tmp = load_reg(s, rm);
6405 sh = (insn >> 16) & 0x1f;
6407 if (insn & (1 << 22))
6408 gen_helper_usat16(tmp, tmp, tcg_const_i32(sh));
6410 gen_helper_ssat16(tmp, tmp, tcg_const_i32(sh));
6412 store_reg(s, rd, tmp);
6413 } else if ((insn & 0x00700fe0) == 0x00000fa0) {
6415 tmp = load_reg(s, rn);
6416 tmp2 = load_reg(s, rm);
6418 tcg_gen_ld_i32(tmp3, cpu_env, offsetof(CPUState, GE));
6419 gen_helper_sel_flags(tmp, tmp3, tmp, tmp2);
6422 store_reg(s, rd, tmp);
6423 } else if ((insn & 0x000003e0) == 0x00000060) {
6424 tmp = load_reg(s, rm);
6425 shift = (insn >> 10) & 3;
6426 /* ??? In many cases it's not neccessary to do a
6427 rotate, a shift is sufficient. */
6429 tcg_gen_rori_i32(tmp, tmp, shift * 8);
6430 op1 = (insn >> 20) & 7;
6432 case 0: gen_sxtb16(tmp); break;
6433 case 2: gen_sxtb(tmp); break;
6434 case 3: gen_sxth(tmp); break;
6435 case 4: gen_uxtb16(tmp); break;
6436 case 6: gen_uxtb(tmp); break;
6437 case 7: gen_uxth(tmp); break;
6438 default: goto illegal_op;
6441 tmp2 = load_reg(s, rn);
6442 if ((op1 & 3) == 0) {
6443 gen_add16(tmp, tmp2);
6445 tcg_gen_add_i32(tmp, tmp, tmp2);
6449 store_reg(s, rd, tmp);
6450 } else if ((insn & 0x003f0f60) == 0x003f0f20) {
6452 tmp = load_reg(s, rm);
6453 if (insn & (1 << 22)) {
6454 if (insn & (1 << 7)) {
6458 gen_helper_rbit(tmp, tmp);
6461 if (insn & (1 << 7))
6464 tcg_gen_bswap_i32(tmp, tmp);
6466 store_reg(s, rd, tmp);
6471 case 2: /* Multiplies (Type 3). */
6472 tmp = load_reg(s, rm);
6473 tmp2 = load_reg(s, rs);
6474 if (insn & (1 << 20)) {
6475 /* Signed multiply most significant [accumulate]. */
6476 tmp2 = gen_muls_i64_i32(tmp, tmp2);
6477 if (insn & (1 << 5))
6478 tcg_gen_addi_i64(tmp2, tmp2, 0x80000000u);
6479 tcg_gen_shri_i64(tmp2, tmp2, 32);
6481 tcg_gen_trunc_i64_i32(tmp, tmp2);
6483 tmp2 = load_reg(s, rn);
6484 if (insn & (1 << 6)) {
6485 tcg_gen_sub_i32(tmp, tmp, tmp2);
6487 tcg_gen_add_i32(tmp, tmp, tmp2);
6491 store_reg(s, rd, tmp);
6493 if (insn & (1 << 5))
6494 gen_swap_half(tmp2);
6495 gen_smul_dual(tmp, tmp2);
6496 /* This addition cannot overflow. */
6497 if (insn & (1 << 6)) {
6498 tcg_gen_sub_i32(tmp, tmp, tmp2);
6500 tcg_gen_add_i32(tmp, tmp, tmp2);
6503 if (insn & (1 << 22)) {
6504 /* smlald, smlsld */
6505 tmp2 = tcg_temp_new(TCG_TYPE_I64);
6506 tcg_gen_ext_i32_i64(tmp2, tmp);
6508 gen_addq(s, tmp2, rn, rd);
6509 gen_storeq_reg(s, rn, rd, tmp2);
6511 /* smuad, smusd, smlad, smlsd */
6514 tmp2 = load_reg(s, rn);
6515 gen_helper_add_setq(tmp, tmp, tmp2);
6518 store_reg(s, rd, tmp);
6523 op1 = ((insn >> 17) & 0x38) | ((insn >> 5) & 7);
6525 case 0: /* Unsigned sum of absolute differences. */
6527 tmp = load_reg(s, rm);
6528 tmp2 = load_reg(s, rs);
6529 gen_helper_usad8(tmp, tmp, tmp2);
6532 tmp2 = load_reg(s, rn);
6533 tcg_gen_add_i32(tmp, tmp, tmp2);
6536 store_reg(s, rd, tmp);
6538 case 0x20: case 0x24: case 0x28: case 0x2c:
6539 /* Bitfield insert/clear. */
6541 shift = (insn >> 7) & 0x1f;
6542 i = (insn >> 16) & 0x1f;
6546 tcg_gen_movi_i32(tmp, 0);
6548 tmp = load_reg(s, rm);
6551 tmp2 = load_reg(s, rd);
6552 gen_bfi(tmp, tmp2, tmp, shift, (1u << i) - 1);
6555 store_reg(s, rd, tmp);
6557 case 0x12: case 0x16: case 0x1a: case 0x1e: /* sbfx */
6558 case 0x32: case 0x36: case 0x3a: case 0x3e: /* ubfx */
6559 tmp = load_reg(s, rm);
6560 shift = (insn >> 7) & 0x1f;
6561 i = ((insn >> 16) & 0x1f) + 1;
6566 gen_ubfx(tmp, shift, (1u << i) - 1);
6568 gen_sbfx(tmp, shift, i);
6571 store_reg(s, rd, tmp);
6581 /* Check for undefined extension instructions
6582 * per the ARM Bible IE:
6583 * xxxx 0111 1111 xxxx xxxx xxxx 1111 xxxx
6585 sh = (0xf << 20) | (0xf << 4);
6586 if (op1 == 0x7 && ((insn & sh) == sh))
6590 /* load/store byte/word */
6591 rn = (insn >> 16) & 0xf;
6592 rd = (insn >> 12) & 0xf;
6593 tmp2 = load_reg(s, rn);
6594 i = (IS_USER(s) || (insn & 0x01200000) == 0x00200000);
6595 if (insn & (1 << 24))
6596 gen_add_data_offset(s, insn, tmp2);
6597 if (insn & (1 << 20)) {
6600 if (insn & (1 << 22)) {
6601 tmp = gen_ld8u(tmp2, i);
6603 tmp = gen_ld32(tmp2, i);
6607 tmp = load_reg(s, rd);
6608 if (insn & (1 << 22))
6609 gen_st8(tmp, tmp2, i);
6611 gen_st32(tmp, tmp2, i);
6613 if (!(insn & (1 << 24))) {
6614 gen_add_data_offset(s, insn, tmp2);
6615 store_reg(s, rn, tmp2);
6616 } else if (insn & (1 << 21)) {
6617 store_reg(s, rn, tmp2);
6621 if (insn & (1 << 20)) {
6622 /* Complete the load. */
6626 store_reg(s, rd, tmp);
6632 int j, n, user, loaded_base;
6634 /* load/store multiple words */
6635 /* XXX: store correct base if write back */
6637 if (insn & (1 << 22)) {
6639 goto illegal_op; /* only usable in supervisor mode */
6641 if ((insn & (1 << 15)) == 0)
6644 rn = (insn >> 16) & 0xf;
6645 addr = load_reg(s, rn);
6647 /* compute total size */
6651 if (insn & (1 << i))
6654 /* XXX: test invalid n == 0 case ? */
6655 if (insn & (1 << 23)) {
6656 if (insn & (1 << 24)) {
6658 tcg_gen_addi_i32(addr, addr, 4);
6660 /* post increment */
6663 if (insn & (1 << 24)) {
6665 tcg_gen_addi_i32(addr, addr, -(n * 4));
6667 /* post decrement */
6669 tcg_gen_addi_i32(addr, addr, -((n - 1) * 4));
6674 if (insn & (1 << i)) {
6675 if (insn & (1 << 20)) {
6677 tmp = gen_ld32(addr, IS_USER(s));
6681 gen_helper_set_user_reg(tcg_const_i32(i), tmp);
6683 } else if (i == rn) {
6687 store_reg(s, i, tmp);
6692 /* special case: r15 = PC + 8 */
6693 val = (long)s->pc + 4;
6695 tcg_gen_movi_i32(tmp, val);
6698 gen_helper_get_user_reg(tmp, tcg_const_i32(i));
6700 tmp = load_reg(s, i);
6702 gen_st32(tmp, addr, IS_USER(s));
6705 /* no need to add after the last transfer */
6707 tcg_gen_addi_i32(addr, addr, 4);
6710 if (insn & (1 << 21)) {
6712 if (insn & (1 << 23)) {
6713 if (insn & (1 << 24)) {
6716 /* post increment */
6717 tcg_gen_addi_i32(addr, addr, 4);
6720 if (insn & (1 << 24)) {
6723 tcg_gen_addi_i32(addr, addr, -((n - 1) * 4));
6725 /* post decrement */
6726 tcg_gen_addi_i32(addr, addr, -(n * 4));
6729 store_reg(s, rn, addr);
6734 store_reg(s, rn, loaded_var);
6736 if ((insn & (1 << 22)) && !user) {
6737 /* Restore CPSR from SPSR. */
6738 tmp = load_cpu_field(spsr);
6739 gen_set_cpsr(tmp, 0xffffffff);
6741 s->is_jmp = DISAS_UPDATE;
6750 /* branch (and link) */
6751 val = (int32_t)s->pc;
6752 if (insn & (1 << 24)) {
6754 tcg_gen_movi_i32(tmp, val);
6755 store_reg(s, 14, tmp);
6757 offset = (((int32_t)insn << 8) >> 8);
6758 val += (offset << 2) + 4;
6766 if (disas_coproc_insn(env, s, insn))
6771 gen_set_pc_im(s->pc);
6772 s->is_jmp = DISAS_SWI;
6776 gen_set_condexec(s);
6777 gen_set_pc_im(s->pc - 4);
6778 gen_exception(EXCP_UDEF);
6779 s->is_jmp = DISAS_JUMP;
6785 /* Return true if this is a Thumb-2 logical op. */
6787 thumb2_logic_op(int op)
6792 /* Generate code for a Thumb-2 data processing operation. If CONDS is nonzero
6793 then set condition code flags based on the result of the operation.
6794 If SHIFTER_OUT is nonzero then set the carry flag for logical operations
6795 to the high bit of T1.
6796 Returns zero if the opcode is valid. */
6799 gen_thumb2_data_op(DisasContext *s, int op, int conds, uint32_t shifter_out)
6806 gen_op_andl_T0_T1();
6810 gen_op_bicl_T0_T1();
6823 gen_op_xorl_T0_T1();
6828 gen_op_addl_T0_T1_cc();
6830 gen_op_addl_T0_T1();
6834 gen_op_adcl_T0_T1_cc();
6840 gen_op_sbcl_T0_T1_cc();
6846 gen_op_subl_T0_T1_cc();
6848 gen_op_subl_T0_T1();
6852 gen_op_rsbl_T0_T1_cc();
6854 gen_op_rsbl_T0_T1();
6856 default: /* 5, 6, 7, 9, 12, 15. */
6860 gen_op_logic_T0_cc();
6862 gen_set_CF_bit31(cpu_T[1]);
6867 /* Translate a 32-bit thumb instruction. Returns nonzero if the instruction
6869 static int disas_thumb2_insn(CPUState *env, DisasContext *s, uint16_t insn_hw1)
6871 uint32_t insn, imm, shift, offset;
6872 uint32_t rd, rn, rm, rs;
6882 if (!(arm_feature(env, ARM_FEATURE_THUMB2)
6883 || arm_feature (env, ARM_FEATURE_M))) {
6884 /* Thumb-1 cores may need to treat bl and blx as a pair of
6885 16-bit instructions to get correct prefetch abort behavior. */
6887 if ((insn & (1 << 12)) == 0) {
6888 /* Second half of blx. */
6889 offset = ((insn & 0x7ff) << 1);
6890 tmp = load_reg(s, 14);
6891 tcg_gen_addi_i32(tmp, tmp, offset);
6892 tcg_gen_andi_i32(tmp, tmp, 0xfffffffc);
6895 tcg_gen_movi_i32(tmp2, s->pc | 1);
6896 store_reg(s, 14, tmp2);
6900 if (insn & (1 << 11)) {
6901 /* Second half of bl. */
6902 offset = ((insn & 0x7ff) << 1) | 1;
6903 tmp = load_reg(s, 14);
6904 tcg_gen_addi_i32(tmp, tmp, offset);
6907 tcg_gen_movi_i32(tmp2, s->pc | 1);
6908 store_reg(s, 14, tmp2);
6912 if ((s->pc & ~TARGET_PAGE_MASK) == 0) {
6913 /* Instruction spans a page boundary. Implement it as two
6914 16-bit instructions in case the second half causes an
6916 offset = ((int32_t)insn << 21) >> 9;
6917 gen_op_movl_T0_im(s->pc + 2 + offset);
6918 gen_movl_reg_T0(s, 14);
6921 /* Fall through to 32-bit decode. */
6924 insn = lduw_code(s->pc);
6926 insn |= (uint32_t)insn_hw1 << 16;
6928 if ((insn & 0xf800e800) != 0xf000e800) {
6932 rn = (insn >> 16) & 0xf;
6933 rs = (insn >> 12) & 0xf;
6934 rd = (insn >> 8) & 0xf;
6936 switch ((insn >> 25) & 0xf) {
6937 case 0: case 1: case 2: case 3:
6938 /* 16-bit instructions. Should never happen. */
6941 if (insn & (1 << 22)) {
6942 /* Other load/store, table branch. */
6943 if (insn & 0x01200000) {
6944 /* Load/store doubleword. */
6947 tcg_gen_movi_i32(addr, s->pc & ~3);
6949 addr = load_reg(s, rn);
6951 offset = (insn & 0xff) * 4;
6952 if ((insn & (1 << 23)) == 0)
6954 if (insn & (1 << 24)) {
6955 tcg_gen_addi_i32(addr, addr, offset);
6958 if (insn & (1 << 20)) {
6960 tmp = gen_ld32(addr, IS_USER(s));
6961 store_reg(s, rs, tmp);
6962 tcg_gen_addi_i32(addr, addr, 4);
6963 tmp = gen_ld32(addr, IS_USER(s));
6964 store_reg(s, rd, tmp);
6967 tmp = load_reg(s, rs);
6968 gen_st32(tmp, addr, IS_USER(s));
6969 tcg_gen_addi_i32(addr, addr, 4);
6970 tmp = load_reg(s, rd);
6971 gen_st32(tmp, addr, IS_USER(s));
6973 if (insn & (1 << 21)) {
6974 /* Base writeback. */
6977 tcg_gen_addi_i32(addr, addr, offset - 4);
6978 store_reg(s, rn, addr);
6982 } else if ((insn & (1 << 23)) == 0) {
6983 /* Load/store exclusive word. */
6984 gen_movl_T1_reg(s, rn);
6986 if (insn & (1 << 20)) {
6987 gen_helper_mark_exclusive(cpu_env, cpu_T[1]);
6988 tmp = gen_ld32(addr, IS_USER(s));
6989 store_reg(s, rd, tmp);
6991 int label = gen_new_label();
6992 gen_helper_test_exclusive(cpu_T[0], cpu_env, addr);
6993 tcg_gen_brcond_i32(TCG_COND_NE, cpu_T[0],
6994 tcg_const_i32(0), label);
6995 tmp = load_reg(s, rs);
6996 gen_st32(tmp, cpu_T[1], IS_USER(s));
6997 gen_set_label(label);
6998 gen_movl_reg_T0(s, rd);
7000 } else if ((insn & (1 << 6)) == 0) {
7004 tcg_gen_movi_i32(addr, s->pc);
7006 addr = load_reg(s, rn);
7008 tmp = load_reg(s, rm);
7009 tcg_gen_add_i32(addr, addr, tmp);
7010 if (insn & (1 << 4)) {
7012 tcg_gen_add_i32(addr, addr, tmp);
7014 tmp = gen_ld16u(addr, IS_USER(s));
7017 tmp = gen_ld8u(addr, IS_USER(s));
7020 tcg_gen_shli_i32(tmp, tmp, 1);
7021 tcg_gen_addi_i32(tmp, tmp, s->pc);
7022 store_reg(s, 15, tmp);
7024 /* Load/store exclusive byte/halfword/doubleword. */
7025 /* ??? These are not really atomic. However we know
7026 we never have multiple CPUs running in parallel,
7027 so it is good enough. */
7028 op = (insn >> 4) & 0x3;
7029 /* Must use a global reg for the address because we have
7030 a conditional branch in the store instruction. */
7031 gen_movl_T1_reg(s, rn);
7033 if (insn & (1 << 20)) {
7034 gen_helper_mark_exclusive(cpu_env, addr);
7037 tmp = gen_ld8u(addr, IS_USER(s));
7040 tmp = gen_ld16u(addr, IS_USER(s));
7043 tmp = gen_ld32(addr, IS_USER(s));
7044 tcg_gen_addi_i32(addr, addr, 4);
7045 tmp2 = gen_ld32(addr, IS_USER(s));
7046 store_reg(s, rd, tmp2);
7051 store_reg(s, rs, tmp);
7053 int label = gen_new_label();
7054 /* Must use a global that is not killed by the branch. */
7055 gen_helper_test_exclusive(cpu_T[0], cpu_env, addr);
7056 tcg_gen_brcond_i32(TCG_COND_NE, cpu_T[0], tcg_const_i32(0),
7058 tmp = load_reg(s, rs);
7061 gen_st8(tmp, addr, IS_USER(s));
7064 gen_st16(tmp, addr, IS_USER(s));
7067 gen_st32(tmp, addr, IS_USER(s));
7068 tcg_gen_addi_i32(addr, addr, 4);
7069 tmp = load_reg(s, rd);
7070 gen_st32(tmp, addr, IS_USER(s));
7075 gen_set_label(label);
7076 gen_movl_reg_T0(s, rm);
7080 /* Load/store multiple, RFE, SRS. */
7081 if (((insn >> 23) & 1) == ((insn >> 24) & 1)) {
7082 /* Not available in user mode. */
7085 if (insn & (1 << 20)) {
7087 addr = load_reg(s, rn);
7088 if ((insn & (1 << 24)) == 0)
7089 tcg_gen_addi_i32(addr, addr, -8);
7090 /* Load PC into tmp and CPSR into tmp2. */
7091 tmp = gen_ld32(addr, 0);
7092 tcg_gen_addi_i32(addr, addr, 4);
7093 tmp2 = gen_ld32(addr, 0);
7094 if (insn & (1 << 21)) {
7095 /* Base writeback. */
7096 if (insn & (1 << 24)) {
7097 tcg_gen_addi_i32(addr, addr, 4);
7099 tcg_gen_addi_i32(addr, addr, -4);
7101 store_reg(s, rn, addr);
7105 gen_rfe(s, tmp, tmp2);
7109 if (op == (env->uncached_cpsr & CPSR_M)) {
7110 addr = load_reg(s, 13);
7113 gen_helper_get_r13_banked(addr, cpu_env, tcg_const_i32(op));
7115 if ((insn & (1 << 24)) == 0) {
7116 tcg_gen_addi_i32(addr, addr, -8);
7118 tmp = load_reg(s, 14);
7119 gen_st32(tmp, addr, 0);
7120 tcg_gen_addi_i32(addr, addr, 4);
7122 gen_helper_cpsr_read(tmp);
7123 gen_st32(tmp, addr, 0);
7124 if (insn & (1 << 21)) {
7125 if ((insn & (1 << 24)) == 0) {
7126 tcg_gen_addi_i32(addr, addr, -4);
7128 tcg_gen_addi_i32(addr, addr, 4);
7130 if (op == (env->uncached_cpsr & CPSR_M)) {
7131 store_reg(s, 13, addr);
7133 gen_helper_set_r13_banked(cpu_env,
7134 tcg_const_i32(op), addr);
7142 /* Load/store multiple. */
7143 addr = load_reg(s, rn);
7145 for (i = 0; i < 16; i++) {
7146 if (insn & (1 << i))
7149 if (insn & (1 << 24)) {
7150 tcg_gen_addi_i32(addr, addr, -offset);
7153 for (i = 0; i < 16; i++) {
7154 if ((insn & (1 << i)) == 0)
7156 if (insn & (1 << 20)) {
7158 tmp = gen_ld32(addr, IS_USER(s));
7162 store_reg(s, i, tmp);
7166 tmp = load_reg(s, i);
7167 gen_st32(tmp, addr, IS_USER(s));
7169 tcg_gen_addi_i32(addr, addr, 4);
7171 if (insn & (1 << 21)) {
7172 /* Base register writeback. */
7173 if (insn & (1 << 24)) {
7174 tcg_gen_addi_i32(addr, addr, -offset);
7176 /* Fault if writeback register is in register list. */
7177 if (insn & (1 << rn))
7179 store_reg(s, rn, addr);
7186 case 5: /* Data processing register constant shift. */
7188 gen_op_movl_T0_im(0);
7190 gen_movl_T0_reg(s, rn);
7191 gen_movl_T1_reg(s, rm);
7192 op = (insn >> 21) & 0xf;
7193 shiftop = (insn >> 4) & 3;
7194 shift = ((insn >> 6) & 3) | ((insn >> 10) & 0x1c);
7195 conds = (insn & (1 << 20)) != 0;
7196 logic_cc = (conds && thumb2_logic_op(op));
7197 gen_arm_shift_im(cpu_T[1], shiftop, shift, logic_cc);
7198 if (gen_thumb2_data_op(s, op, conds, 0))
7201 gen_movl_reg_T0(s, rd);
7203 case 13: /* Misc data processing. */
7204 op = ((insn >> 22) & 6) | ((insn >> 7) & 1);
7205 if (op < 4 && (insn & 0xf000) != 0xf000)
7208 case 0: /* Register controlled shift. */
7209 tmp = load_reg(s, rn);
7210 tmp2 = load_reg(s, rm);
7211 if ((insn & 0x70) != 0)
7213 op = (insn >> 21) & 3;
7214 logic_cc = (insn & (1 << 20)) != 0;
7215 gen_arm_shift_reg(tmp, op, tmp2, logic_cc);
7218 store_reg(s, rd, tmp);
7220 case 1: /* Sign/zero extend. */
7221 tmp = load_reg(s, rm);
7222 shift = (insn >> 4) & 3;
7223 /* ??? In many cases it's not neccessary to do a
7224 rotate, a shift is sufficient. */
7226 tcg_gen_rori_i32(tmp, tmp, shift * 8);
7227 op = (insn >> 20) & 7;
7229 case 0: gen_sxth(tmp); break;
7230 case 1: gen_uxth(tmp); break;
7231 case 2: gen_sxtb16(tmp); break;
7232 case 3: gen_uxtb16(tmp); break;
7233 case 4: gen_sxtb(tmp); break;
7234 case 5: gen_uxtb(tmp); break;
7235 default: goto illegal_op;
7238 tmp2 = load_reg(s, rn);
7239 if ((op >> 1) == 1) {
7240 gen_add16(tmp, tmp2);
7242 tcg_gen_add_i32(tmp, tmp, tmp2);
7246 store_reg(s, rd, tmp);
7248 case 2: /* SIMD add/subtract. */
7249 op = (insn >> 20) & 7;
7250 shift = (insn >> 4) & 7;
7251 if ((op & 3) == 3 || (shift & 3) == 3)
7253 tmp = load_reg(s, rn);
7254 tmp2 = load_reg(s, rm);
7255 gen_thumb2_parallel_addsub(op, shift, tmp, tmp2);
7257 store_reg(s, rd, tmp);
7259 case 3: /* Other data processing. */
7260 op = ((insn >> 17) & 0x38) | ((insn >> 4) & 7);
7262 /* Saturating add/subtract. */
7263 tmp = load_reg(s, rn);
7264 tmp2 = load_reg(s, rm);
7266 gen_helper_double_saturate(tmp, tmp);
7268 gen_helper_sub_saturate(tmp, tmp2, tmp);
7270 gen_helper_add_saturate(tmp, tmp, tmp2);
7273 tmp = load_reg(s, rn);
7275 case 0x0a: /* rbit */
7276 gen_helper_rbit(tmp, tmp);
7278 case 0x08: /* rev */
7279 tcg_gen_bswap_i32(tmp, tmp);
7281 case 0x09: /* rev16 */
7284 case 0x0b: /* revsh */
7287 case 0x10: /* sel */
7288 tmp2 = load_reg(s, rm);
7290 tcg_gen_ld_i32(tmp3, cpu_env, offsetof(CPUState, GE));
7291 gen_helper_sel_flags(tmp, tmp3, tmp, tmp2);
7295 case 0x18: /* clz */
7296 gen_helper_clz(tmp, tmp);
7302 store_reg(s, rd, tmp);
7304 case 4: case 5: /* 32-bit multiply. Sum of absolute differences. */
7305 op = (insn >> 4) & 0xf;
7306 tmp = load_reg(s, rn);
7307 tmp2 = load_reg(s, rm);
7308 switch ((insn >> 20) & 7) {
7309 case 0: /* 32 x 32 -> 32 */
7310 tcg_gen_mul_i32(tmp, tmp, tmp2);
7313 tmp2 = load_reg(s, rs);
7315 tcg_gen_sub_i32(tmp, tmp2, tmp);
7317 tcg_gen_add_i32(tmp, tmp, tmp2);
7321 case 1: /* 16 x 16 -> 32 */
7322 gen_mulxy(tmp, tmp2, op & 2, op & 1);
7325 tmp2 = load_reg(s, rs);
7326 gen_helper_add_setq(tmp, tmp, tmp2);
7330 case 2: /* Dual multiply add. */
7331 case 4: /* Dual multiply subtract. */
7333 gen_swap_half(tmp2);
7334 gen_smul_dual(tmp, tmp2);
7335 /* This addition cannot overflow. */
7336 if (insn & (1 << 22)) {
7337 tcg_gen_sub_i32(tmp, tmp, tmp2);
7339 tcg_gen_add_i32(tmp, tmp, tmp2);
7344 tmp2 = load_reg(s, rs);
7345 gen_helper_add_setq(tmp, tmp, tmp2);
7349 case 3: /* 32 * 16 -> 32msb */
7351 tcg_gen_sari_i32(tmp2, tmp2, 16);
7354 tmp2 = gen_muls_i64_i32(tmp, tmp2);
7355 tcg_gen_shri_i64(tmp2, tmp2, 16);
7357 tcg_gen_trunc_i64_i32(tmp, tmp2);
7360 tmp2 = load_reg(s, rs);
7361 gen_helper_add_setq(tmp, tmp, tmp2);
7365 case 5: case 6: /* 32 * 32 -> 32msb */
7366 gen_imull(tmp, tmp2);
7367 if (insn & (1 << 5)) {
7368 gen_roundqd(tmp, tmp2);
7375 tmp2 = load_reg(s, rs);
7376 if (insn & (1 << 21)) {
7377 tcg_gen_add_i32(tmp, tmp, tmp2);
7379 tcg_gen_sub_i32(tmp, tmp2, tmp);
7384 case 7: /* Unsigned sum of absolute differences. */
7385 gen_helper_usad8(tmp, tmp, tmp2);
7388 tmp2 = load_reg(s, rs);
7389 tcg_gen_add_i32(tmp, tmp, tmp2);
7394 store_reg(s, rd, tmp);
7396 case 6: case 7: /* 64-bit multiply, Divide. */
7397 op = ((insn >> 4) & 0xf) | ((insn >> 16) & 0x70);
7398 tmp = load_reg(s, rn);
7399 tmp2 = load_reg(s, rm);
7400 if ((op & 0x50) == 0x10) {
7402 if (!arm_feature(env, ARM_FEATURE_DIV))
7405 gen_helper_udiv(tmp, tmp, tmp2);
7407 gen_helper_sdiv(tmp, tmp, tmp2);
7409 store_reg(s, rd, tmp);
7410 } else if ((op & 0xe) == 0xc) {
7411 /* Dual multiply accumulate long. */
7413 gen_swap_half(tmp2);
7414 gen_smul_dual(tmp, tmp2);
7416 tcg_gen_sub_i32(tmp, tmp, tmp2);
7418 tcg_gen_add_i32(tmp, tmp, tmp2);
7421 tmp2 = tcg_temp_new(TCG_TYPE_I64);
7422 gen_addq(s, tmp, rs, rd);
7423 gen_storeq_reg(s, rs, rd, tmp);
7426 /* Unsigned 64-bit multiply */
7427 tmp = gen_mulu_i64_i32(tmp, tmp2);
7431 gen_mulxy(tmp, tmp2, op & 2, op & 1);
7433 tmp2 = tcg_temp_new(TCG_TYPE_I64);
7434 tcg_gen_ext_i32_i64(tmp2, tmp);
7438 /* Signed 64-bit multiply */
7439 tmp = gen_muls_i64_i32(tmp, tmp2);
7444 gen_addq_lo(s, tmp, rs);
7445 gen_addq_lo(s, tmp, rd);
7446 } else if (op & 0x40) {
7447 /* 64-bit accumulate. */
7448 gen_addq(s, tmp, rs, rd);
7450 gen_storeq_reg(s, rs, rd, tmp);
7455 case 6: case 7: case 14: case 15:
7457 if (((insn >> 24) & 3) == 3) {
7458 /* Translate into the equivalent ARM encoding. */
7459 insn = (insn & 0xe2ffffff) | ((insn & (1 << 28)) >> 4);
7460 if (disas_neon_data_insn(env, s, insn))
7463 if (insn & (1 << 28))
7465 if (disas_coproc_insn (env, s, insn))
7469 case 8: case 9: case 10: case 11:
7470 if (insn & (1 << 15)) {
7471 /* Branches, misc control. */
7472 if (insn & 0x5000) {
7473 /* Unconditional branch. */
7474 /* signextend(hw1[10:0]) -> offset[:12]. */
7475 offset = ((int32_t)insn << 5) >> 9 & ~(int32_t)0xfff;
7476 /* hw1[10:0] -> offset[11:1]. */
7477 offset |= (insn & 0x7ff) << 1;
7478 /* (~hw2[13, 11] ^ offset[24]) -> offset[23,22]
7479 offset[24:22] already have the same value because of the
7480 sign extension above. */
7481 offset ^= ((~insn) & (1 << 13)) << 10;
7482 offset ^= ((~insn) & (1 << 11)) << 11;
7484 if (insn & (1 << 14)) {
7485 /* Branch and link. */
7486 gen_op_movl_T1_im(s->pc | 1);
7487 gen_movl_reg_T1(s, 14);
7491 if (insn & (1 << 12)) {
7496 offset &= ~(uint32_t)2;
7497 gen_bx_im(s, offset);
7499 } else if (((insn >> 23) & 7) == 7) {
7501 if (insn & (1 << 13))
7504 if (insn & (1 << 26)) {
7505 /* Secure monitor call (v6Z) */
7506 goto illegal_op; /* not implemented. */
7508 op = (insn >> 20) & 7;
7510 case 0: /* msr cpsr. */
7512 tmp = load_reg(s, rn);
7513 addr = tcg_const_i32(insn & 0xff);
7514 gen_helper_v7m_msr(cpu_env, addr, tmp);
7519 case 1: /* msr spsr. */
7522 gen_movl_T0_reg(s, rn);
7523 if (gen_set_psr_T0(s,
7524 msr_mask(env, s, (insn >> 8) & 0xf, op == 1),
7528 case 2: /* cps, nop-hint. */
7529 if (((insn >> 8) & 7) == 0) {
7530 gen_nop_hint(s, insn & 0xff);
7532 /* Implemented as NOP in user mode. */
7537 if (insn & (1 << 10)) {
7538 if (insn & (1 << 7))
7540 if (insn & (1 << 6))
7542 if (insn & (1 << 5))
7544 if (insn & (1 << 9))
7545 imm = CPSR_A | CPSR_I | CPSR_F;
7547 if (insn & (1 << 8)) {
7549 imm |= (insn & 0x1f);
7552 gen_op_movl_T0_im(imm);
7553 gen_set_psr_T0(s, offset, 0);
7556 case 3: /* Special control operations. */
7557 op = (insn >> 4) & 0xf;
7560 gen_helper_clrex(cpu_env);
7565 /* These execute as NOPs. */
7573 /* Trivial implementation equivalent to bx. */
7574 tmp = load_reg(s, rn);
7577 case 5: /* Exception return. */
7578 /* Unpredictable in user mode. */
7580 case 6: /* mrs cpsr. */
7583 addr = tcg_const_i32(insn & 0xff);
7584 gen_helper_v7m_mrs(tmp, cpu_env, addr);
7586 gen_helper_cpsr_read(tmp);
7588 store_reg(s, rd, tmp);
7590 case 7: /* mrs spsr. */
7591 /* Not accessible in user mode. */
7592 if (IS_USER(s) || IS_M(env))
7594 tmp = load_cpu_field(spsr);
7595 store_reg(s, rd, tmp);
7600 /* Conditional branch. */
7601 op = (insn >> 22) & 0xf;
7602 /* Generate a conditional jump to next instruction. */
7603 s->condlabel = gen_new_label();
7604 gen_test_cc(op ^ 1, s->condlabel);
7607 /* offset[11:1] = insn[10:0] */
7608 offset = (insn & 0x7ff) << 1;
7609 /* offset[17:12] = insn[21:16]. */
7610 offset |= (insn & 0x003f0000) >> 4;
7611 /* offset[31:20] = insn[26]. */
7612 offset |= ((int32_t)((insn << 5) & 0x80000000)) >> 11;
7613 /* offset[18] = insn[13]. */
7614 offset |= (insn & (1 << 13)) << 5;
7615 /* offset[19] = insn[11]. */
7616 offset |= (insn & (1 << 11)) << 8;
7618 /* jump to the offset */
7619 gen_jmp(s, s->pc + offset);
7622 /* Data processing immediate. */
7623 if (insn & (1 << 25)) {
7624 if (insn & (1 << 24)) {
7625 if (insn & (1 << 20))
7627 /* Bitfield/Saturate. */
7628 op = (insn >> 21) & 7;
7630 shift = ((insn >> 6) & 3) | ((insn >> 10) & 0x1c);
7633 tcg_gen_movi_i32(tmp, 0);
7635 tmp = load_reg(s, rn);
7638 case 2: /* Signed bitfield extract. */
7640 if (shift + imm > 32)
7643 gen_sbfx(tmp, shift, imm);
7645 case 6: /* Unsigned bitfield extract. */
7647 if (shift + imm > 32)
7650 gen_ubfx(tmp, shift, (1u << imm) - 1);
7652 case 3: /* Bitfield insert/clear. */
7655 imm = imm + 1 - shift;
7657 tmp2 = load_reg(s, rd);
7658 gen_bfi(tmp, tmp2, tmp, shift, (1u << imm) - 1);
7664 default: /* Saturate. */
7667 tcg_gen_sari_i32(tmp, tmp, shift);
7669 tcg_gen_shli_i32(tmp, tmp, shift);
7671 tmp2 = tcg_const_i32(imm);
7674 if ((op & 1) && shift == 0)
7675 gen_helper_usat16(tmp, tmp, tmp2);
7677 gen_helper_usat(tmp, tmp, tmp2);
7680 if ((op & 1) && shift == 0)
7681 gen_helper_ssat16(tmp, tmp, tmp2);
7683 gen_helper_ssat(tmp, tmp, tmp2);
7687 store_reg(s, rd, tmp);
7689 imm = ((insn & 0x04000000) >> 15)
7690 | ((insn & 0x7000) >> 4) | (insn & 0xff);
7691 if (insn & (1 << 22)) {
7692 /* 16-bit immediate. */
7693 imm |= (insn >> 4) & 0xf000;
7694 if (insn & (1 << 23)) {
7696 tmp = load_reg(s, rd);
7697 tcg_gen_ext16u_i32(tmp, tmp);
7698 tcg_gen_ori_i32(tmp, tmp, imm << 16);
7702 tcg_gen_movi_i32(tmp, imm);
7705 /* Add/sub 12-bit immediate. */
7707 offset = s->pc & ~(uint32_t)3;
7708 if (insn & (1 << 23))
7713 tcg_gen_movi_i32(tmp, offset);
7715 tmp = load_reg(s, rn);
7716 if (insn & (1 << 23))
7717 tcg_gen_subi_i32(tmp, tmp, imm);
7719 tcg_gen_addi_i32(tmp, tmp, imm);
7722 store_reg(s, rd, tmp);
7725 int shifter_out = 0;
7726 /* modified 12-bit immediate. */
7727 shift = ((insn & 0x04000000) >> 23) | ((insn & 0x7000) >> 12);
7728 imm = (insn & 0xff);
7731 /* Nothing to do. */
7733 case 1: /* 00XY00XY */
7736 case 2: /* XY00XY00 */
7740 case 3: /* XYXYXYXY */
7744 default: /* Rotated constant. */
7745 shift = (shift << 1) | (imm >> 7);
7747 imm = imm << (32 - shift);
7751 gen_op_movl_T1_im(imm);
7752 rn = (insn >> 16) & 0xf;
7754 gen_op_movl_T0_im(0);
7756 gen_movl_T0_reg(s, rn);
7757 op = (insn >> 21) & 0xf;
7758 if (gen_thumb2_data_op(s, op, (insn & (1 << 20)) != 0,
7761 rd = (insn >> 8) & 0xf;
7763 gen_movl_reg_T0(s, rd);
7768 case 12: /* Load/store single data item. */
7773 if ((insn & 0x01100000) == 0x01000000) {
7774 if (disas_neon_ls_insn(env, s, insn))
7782 /* s->pc has already been incremented by 4. */
7783 imm = s->pc & 0xfffffffc;
7784 if (insn & (1 << 23))
7785 imm += insn & 0xfff;
7787 imm -= insn & 0xfff;
7788 tcg_gen_movi_i32(addr, imm);
7790 addr = load_reg(s, rn);
7791 if (insn & (1 << 23)) {
7792 /* Positive offset. */
7794 tcg_gen_addi_i32(addr, addr, imm);
7796 op = (insn >> 8) & 7;
7799 case 0: case 8: /* Shifted Register. */
7800 shift = (insn >> 4) & 0xf;
7803 tmp = load_reg(s, rm);
7805 tcg_gen_shli_i32(tmp, tmp, shift);
7806 tcg_gen_add_i32(addr, addr, tmp);
7809 case 4: /* Negative offset. */
7810 tcg_gen_addi_i32(addr, addr, -imm);
7812 case 6: /* User privilege. */
7813 tcg_gen_addi_i32(addr, addr, imm);
7816 case 1: /* Post-decrement. */
7819 case 3: /* Post-increment. */
7823 case 5: /* Pre-decrement. */
7826 case 7: /* Pre-increment. */
7827 tcg_gen_addi_i32(addr, addr, imm);
7835 op = ((insn >> 21) & 3) | ((insn >> 22) & 4);
7836 if (insn & (1 << 20)) {
7838 if (rs == 15 && op != 2) {
7841 /* Memory hint. Implemented as NOP. */
7844 case 0: tmp = gen_ld8u(addr, user); break;
7845 case 4: tmp = gen_ld8s(addr, user); break;
7846 case 1: tmp = gen_ld16u(addr, user); break;
7847 case 5: tmp = gen_ld16s(addr, user); break;
7848 case 2: tmp = gen_ld32(addr, user); break;
7849 default: goto illegal_op;
7854 store_reg(s, rs, tmp);
7861 tmp = load_reg(s, rs);
7863 case 0: gen_st8(tmp, addr, user); break;
7864 case 1: gen_st16(tmp, addr, user); break;
7865 case 2: gen_st32(tmp, addr, user); break;
7866 default: goto illegal_op;
7870 tcg_gen_addi_i32(addr, addr, imm);
7872 store_reg(s, rn, addr);
7886 static void disas_thumb_insn(CPUState *env, DisasContext *s)
7888 uint32_t val, insn, op, rm, rn, rd, shift, cond;
7895 if (s->condexec_mask) {
7896 cond = s->condexec_cond;
7897 s->condlabel = gen_new_label();
7898 gen_test_cc(cond ^ 1, s->condlabel);
7902 insn = lduw_code(s->pc);
7905 switch (insn >> 12) {
7908 op = (insn >> 11) & 3;
7911 rn = (insn >> 3) & 7;
7912 gen_movl_T0_reg(s, rn);
7913 if (insn & (1 << 10)) {
7915 gen_op_movl_T1_im((insn >> 6) & 7);
7918 rm = (insn >> 6) & 7;
7919 gen_movl_T1_reg(s, rm);
7921 if (insn & (1 << 9)) {
7922 if (s->condexec_mask)
7923 gen_op_subl_T0_T1();
7925 gen_op_subl_T0_T1_cc();
7927 if (s->condexec_mask)
7928 gen_op_addl_T0_T1();
7930 gen_op_addl_T0_T1_cc();
7932 gen_movl_reg_T0(s, rd);
7934 /* shift immediate */
7935 rm = (insn >> 3) & 7;
7936 shift = (insn >> 6) & 0x1f;
7937 tmp = load_reg(s, rm);
7938 gen_arm_shift_im(tmp, op, shift, s->condexec_mask == 0);
7939 if (!s->condexec_mask)
7941 store_reg(s, rd, tmp);
7945 /* arithmetic large immediate */
7946 op = (insn >> 11) & 3;
7947 rd = (insn >> 8) & 0x7;
7949 gen_op_movl_T0_im(insn & 0xff);
7951 gen_movl_T0_reg(s, rd);
7952 gen_op_movl_T1_im(insn & 0xff);
7956 if (!s->condexec_mask)
7957 gen_op_logic_T0_cc();
7960 gen_op_subl_T0_T1_cc();
7963 if (s->condexec_mask)
7964 gen_op_addl_T0_T1();
7966 gen_op_addl_T0_T1_cc();
7969 if (s->condexec_mask)
7970 gen_op_subl_T0_T1();
7972 gen_op_subl_T0_T1_cc();
7976 gen_movl_reg_T0(s, rd);
7979 if (insn & (1 << 11)) {
7980 rd = (insn >> 8) & 7;
7981 /* load pc-relative. Bit 1 of PC is ignored. */
7982 val = s->pc + 2 + ((insn & 0xff) * 4);
7983 val &= ~(uint32_t)2;
7985 tcg_gen_movi_i32(addr, val);
7986 tmp = gen_ld32(addr, IS_USER(s));
7988 store_reg(s, rd, tmp);
7991 if (insn & (1 << 10)) {
7992 /* data processing extended or blx */
7993 rd = (insn & 7) | ((insn >> 4) & 8);
7994 rm = (insn >> 3) & 0xf;
7995 op = (insn >> 8) & 3;
7998 gen_movl_T0_reg(s, rd);
7999 gen_movl_T1_reg(s, rm);
8000 gen_op_addl_T0_T1();
8001 gen_movl_reg_T0(s, rd);
8004 gen_movl_T0_reg(s, rd);
8005 gen_movl_T1_reg(s, rm);
8006 gen_op_subl_T0_T1_cc();
8008 case 2: /* mov/cpy */
8009 gen_movl_T0_reg(s, rm);
8010 gen_movl_reg_T0(s, rd);
8012 case 3:/* branch [and link] exchange thumb register */
8013 tmp = load_reg(s, rm);
8014 if (insn & (1 << 7)) {
8015 val = (uint32_t)s->pc | 1;
8017 tcg_gen_movi_i32(tmp2, val);
8018 store_reg(s, 14, tmp2);
8026 /* data processing register */
8028 rm = (insn >> 3) & 7;
8029 op = (insn >> 6) & 0xf;
8030 if (op == 2 || op == 3 || op == 4 || op == 7) {
8031 /* the shift/rotate ops want the operands backwards */
8040 if (op == 9) /* neg */
8041 gen_op_movl_T0_im(0);
8042 else if (op != 0xf) /* mvn doesn't read its first operand */
8043 gen_movl_T0_reg(s, rd);
8045 gen_movl_T1_reg(s, rm);
8048 gen_op_andl_T0_T1();
8049 if (!s->condexec_mask)
8050 gen_op_logic_T0_cc();
8053 gen_op_xorl_T0_T1();
8054 if (!s->condexec_mask)
8055 gen_op_logic_T0_cc();
8058 if (s->condexec_mask) {
8059 gen_helper_shl(cpu_T[1], cpu_T[1], cpu_T[0]);
8061 gen_helper_shl_cc(cpu_T[1], cpu_T[1], cpu_T[0]);
8062 gen_op_logic_T1_cc();
8066 if (s->condexec_mask) {
8067 gen_helper_shr(cpu_T[1], cpu_T[1], cpu_T[0]);
8069 gen_helper_shr_cc(cpu_T[1], cpu_T[1], cpu_T[0]);
8070 gen_op_logic_T1_cc();
8074 if (s->condexec_mask) {
8075 gen_helper_sar(cpu_T[1], cpu_T[1], cpu_T[0]);
8077 gen_helper_sar_cc(cpu_T[1], cpu_T[1], cpu_T[0]);
8078 gen_op_logic_T1_cc();
8082 if (s->condexec_mask)
8085 gen_op_adcl_T0_T1_cc();
8088 if (s->condexec_mask)
8091 gen_op_sbcl_T0_T1_cc();
8094 if (s->condexec_mask) {
8095 gen_helper_ror(cpu_T[1], cpu_T[1], cpu_T[0]);
8097 gen_helper_ror_cc(cpu_T[1], cpu_T[1], cpu_T[0]);
8098 gen_op_logic_T1_cc();
8102 gen_op_andl_T0_T1();
8103 gen_op_logic_T0_cc();
8107 if (s->condexec_mask)
8108 tcg_gen_neg_i32(cpu_T[0], cpu_T[1]);
8110 gen_op_subl_T0_T1_cc();
8113 gen_op_subl_T0_T1_cc();
8117 gen_op_addl_T0_T1_cc();
8122 if (!s->condexec_mask)
8123 gen_op_logic_T0_cc();
8126 gen_op_mull_T0_T1();
8127 if (!s->condexec_mask)
8128 gen_op_logic_T0_cc();
8131 gen_op_bicl_T0_T1();
8132 if (!s->condexec_mask)
8133 gen_op_logic_T0_cc();
8137 if (!s->condexec_mask)
8138 gen_op_logic_T1_cc();
8145 gen_movl_reg_T1(s, rm);
8147 gen_movl_reg_T0(s, rd);
8152 /* load/store register offset. */
8154 rn = (insn >> 3) & 7;
8155 rm = (insn >> 6) & 7;
8156 op = (insn >> 9) & 7;
8157 addr = load_reg(s, rn);
8158 tmp = load_reg(s, rm);
8159 tcg_gen_add_i32(addr, addr, tmp);
8162 if (op < 3) /* store */
8163 tmp = load_reg(s, rd);
8167 gen_st32(tmp, addr, IS_USER(s));
8170 gen_st16(tmp, addr, IS_USER(s));
8173 gen_st8(tmp, addr, IS_USER(s));
8176 tmp = gen_ld8s(addr, IS_USER(s));
8179 tmp = gen_ld32(addr, IS_USER(s));
8182 tmp = gen_ld16u(addr, IS_USER(s));
8185 tmp = gen_ld8u(addr, IS_USER(s));
8188 tmp = gen_ld16s(addr, IS_USER(s));
8191 if (op >= 3) /* load */
8192 store_reg(s, rd, tmp);
8197 /* load/store word immediate offset */
8199 rn = (insn >> 3) & 7;
8200 addr = load_reg(s, rn);
8201 val = (insn >> 4) & 0x7c;
8202 tcg_gen_addi_i32(addr, addr, val);
8204 if (insn & (1 << 11)) {
8206 tmp = gen_ld32(addr, IS_USER(s));
8207 store_reg(s, rd, tmp);
8210 tmp = load_reg(s, rd);
8211 gen_st32(tmp, addr, IS_USER(s));
8217 /* load/store byte immediate offset */
8219 rn = (insn >> 3) & 7;
8220 addr = load_reg(s, rn);
8221 val = (insn >> 6) & 0x1f;
8222 tcg_gen_addi_i32(addr, addr, val);
8224 if (insn & (1 << 11)) {
8226 tmp = gen_ld8u(addr, IS_USER(s));
8227 store_reg(s, rd, tmp);
8230 tmp = load_reg(s, rd);
8231 gen_st8(tmp, addr, IS_USER(s));
8237 /* load/store halfword immediate offset */
8239 rn = (insn >> 3) & 7;
8240 addr = load_reg(s, rn);
8241 val = (insn >> 5) & 0x3e;
8242 tcg_gen_addi_i32(addr, addr, val);
8244 if (insn & (1 << 11)) {
8246 tmp = gen_ld16u(addr, IS_USER(s));
8247 store_reg(s, rd, tmp);
8250 tmp = load_reg(s, rd);
8251 gen_st16(tmp, addr, IS_USER(s));
8257 /* load/store from stack */
8258 rd = (insn >> 8) & 7;
8259 addr = load_reg(s, 13);
8260 val = (insn & 0xff) * 4;
8261 tcg_gen_addi_i32(addr, addr, val);
8263 if (insn & (1 << 11)) {
8265 tmp = gen_ld32(addr, IS_USER(s));
8266 store_reg(s, rd, tmp);
8269 tmp = load_reg(s, rd);
8270 gen_st32(tmp, addr, IS_USER(s));
8276 /* add to high reg */
8277 rd = (insn >> 8) & 7;
8278 if (insn & (1 << 11)) {
8280 tmp = load_reg(s, 13);
8282 /* PC. bit 1 is ignored. */
8284 tcg_gen_movi_i32(tmp, (s->pc + 2) & ~(uint32_t)2);
8286 val = (insn & 0xff) * 4;
8287 tcg_gen_addi_i32(tmp, tmp, val);
8288 store_reg(s, rd, tmp);
8293 op = (insn >> 8) & 0xf;
8296 /* adjust stack pointer */
8297 tmp = load_reg(s, 13);
8298 val = (insn & 0x7f) * 4;
8299 if (insn & (1 << 7))
8300 val = -(int32_t)val;
8301 tcg_gen_addi_i32(tmp, tmp, val);
8302 store_reg(s, 13, tmp);
8305 case 2: /* sign/zero extend. */
8308 rm = (insn >> 3) & 7;
8309 tmp = load_reg(s, rm);
8310 switch ((insn >> 6) & 3) {
8311 case 0: gen_sxth(tmp); break;
8312 case 1: gen_sxtb(tmp); break;
8313 case 2: gen_uxth(tmp); break;
8314 case 3: gen_uxtb(tmp); break;
8316 store_reg(s, rd, tmp);
8318 case 4: case 5: case 0xc: case 0xd:
8320 addr = load_reg(s, 13);
8321 if (insn & (1 << 8))
8325 for (i = 0; i < 8; i++) {
8326 if (insn & (1 << i))
8329 if ((insn & (1 << 11)) == 0) {
8330 tcg_gen_addi_i32(addr, addr, -offset);
8332 for (i = 0; i < 8; i++) {
8333 if (insn & (1 << i)) {
8334 if (insn & (1 << 11)) {
8336 tmp = gen_ld32(addr, IS_USER(s));
8337 store_reg(s, i, tmp);
8340 tmp = load_reg(s, i);
8341 gen_st32(tmp, addr, IS_USER(s));
8343 /* advance to the next address. */
8344 tcg_gen_addi_i32(addr, addr, 4);
8347 if (insn & (1 << 8)) {
8348 if (insn & (1 << 11)) {
8350 tmp = gen_ld32(addr, IS_USER(s));
8351 /* don't set the pc until the rest of the instruction
8355 tmp = load_reg(s, 14);
8356 gen_st32(tmp, addr, IS_USER(s));
8358 tcg_gen_addi_i32(addr, addr, 4);
8360 if ((insn & (1 << 11)) == 0) {
8361 tcg_gen_addi_i32(addr, addr, -offset);
8363 /* write back the new stack pointer */
8364 store_reg(s, 13, addr);
8365 /* set the new PC value */
8366 if ((insn & 0x0900) == 0x0900)
8370 case 1: case 3: case 9: case 11: /* czb */
8372 tmp = load_reg(s, rm);
8373 tmp2 = tcg_const_i32(0);
8374 s->condlabel = gen_new_label();
8376 if (insn & (1 << 11))
8377 tcg_gen_brcond_i32(TCG_COND_EQ, tmp, tmp2, s->condlabel);
8379 tcg_gen_brcond_i32(TCG_COND_NE, tmp, tmp2, s->condlabel);
8381 offset = ((insn & 0xf8) >> 2) | (insn & 0x200) >> 3;
8382 val = (uint32_t)s->pc + 2;
8387 case 15: /* IT, nop-hint. */
8388 if ((insn & 0xf) == 0) {
8389 gen_nop_hint(s, (insn >> 4) & 0xf);
8393 s->condexec_cond = (insn >> 4) & 0xe;
8394 s->condexec_mask = insn & 0x1f;
8395 /* No actual code generated for this insn, just setup state. */
8398 case 0xe: /* bkpt */
8399 gen_set_condexec(s);
8400 gen_set_pc_im(s->pc - 2);
8401 gen_exception(EXCP_BKPT);
8402 s->is_jmp = DISAS_JUMP;
8407 rn = (insn >> 3) & 0x7;
8409 tmp = load_reg(s, rn);
8410 switch ((insn >> 6) & 3) {
8411 case 0: tcg_gen_bswap_i32(tmp, tmp); break;
8412 case 1: gen_rev16(tmp); break;
8413 case 3: gen_revsh(tmp); break;
8414 default: goto illegal_op;
8416 store_reg(s, rd, tmp);
8424 tmp = tcg_const_i32((insn & (1 << 4)) != 0);
8427 addr = tcg_const_i32(16);
8428 gen_helper_v7m_msr(cpu_env, addr, tmp);
8432 addr = tcg_const_i32(17);
8433 gen_helper_v7m_msr(cpu_env, addr, tmp);
8437 if (insn & (1 << 4))
8438 shift = CPSR_A | CPSR_I | CPSR_F;
8442 val = ((insn & 7) << 6) & shift;
8443 gen_op_movl_T0_im(val);
8444 gen_set_psr_T0(s, shift, 0);
8454 /* load/store multiple */
8455 rn = (insn >> 8) & 0x7;
8456 addr = load_reg(s, rn);
8457 for (i = 0; i < 8; i++) {
8458 if (insn & (1 << i)) {
8459 if (insn & (1 << 11)) {
8461 tmp = gen_ld32(addr, IS_USER(s));
8462 store_reg(s, i, tmp);
8465 tmp = load_reg(s, i);
8466 gen_st32(tmp, addr, IS_USER(s));
8468 /* advance to the next address */
8469 tcg_gen_addi_i32(addr, addr, 4);
8472 /* Base register writeback. */
8473 if ((insn & (1 << rn)) == 0) {
8474 store_reg(s, rn, addr);
8481 /* conditional branch or swi */
8482 cond = (insn >> 8) & 0xf;
8488 gen_set_condexec(s);
8489 gen_set_pc_im(s->pc);
8490 s->is_jmp = DISAS_SWI;
8493 /* generate a conditional jump to next instruction */
8494 s->condlabel = gen_new_label();
8495 gen_test_cc(cond ^ 1, s->condlabel);
8497 gen_movl_T1_reg(s, 15);
8499 /* jump to the offset */
8500 val = (uint32_t)s->pc + 2;
8501 offset = ((int32_t)insn << 24) >> 24;
8507 if (insn & (1 << 11)) {
8508 if (disas_thumb2_insn(env, s, insn))
8512 /* unconditional branch */
8513 val = (uint32_t)s->pc;
8514 offset = ((int32_t)insn << 21) >> 21;
8515 val += (offset << 1) + 2;
8520 if (disas_thumb2_insn(env, s, insn))
8526 gen_set_condexec(s);
8527 gen_set_pc_im(s->pc - 4);
8528 gen_exception(EXCP_UDEF);
8529 s->is_jmp = DISAS_JUMP;
8533 gen_set_condexec(s);
8534 gen_set_pc_im(s->pc - 2);
8535 gen_exception(EXCP_UDEF);
8536 s->is_jmp = DISAS_JUMP;
8539 /* generate intermediate code in gen_opc_buf and gen_opparam_buf for
8540 basic block 'tb'. If search_pc is TRUE, also generate PC
8541 information for each intermediate instruction. */
8542 static inline int gen_intermediate_code_internal(CPUState *env,
8543 TranslationBlock *tb,
8546 DisasContext dc1, *dc = &dc1;
8547 uint16_t *gen_opc_end;
8549 target_ulong pc_start;
8550 uint32_t next_page_start;
8552 /* generate intermediate code */
8554 memset(temps, 0, sizeof(temps));
8560 gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
8562 dc->is_jmp = DISAS_NEXT;
8564 dc->singlestep_enabled = env->singlestep_enabled;
8566 dc->thumb = env->thumb;
8567 dc->condexec_mask = (env->condexec_bits & 0xf) << 1;
8568 dc->condexec_cond = env->condexec_bits >> 4;
8570 #if !defined(CONFIG_USER_ONLY)
8572 dc->user = ((env->v7m.exception == 0) && (env->v7m.control & 1));
8574 dc->user = (env->uncached_cpsr & 0x1f) == ARM_CPU_MODE_USR;
8577 cpu_F0s = tcg_temp_new(TCG_TYPE_I32);
8578 cpu_F1s = tcg_temp_new(TCG_TYPE_I32);
8579 cpu_F0d = tcg_temp_new(TCG_TYPE_I64);
8580 cpu_F1d = tcg_temp_new(TCG_TYPE_I64);
8583 /* FIXME: cpu_M0 can probably be the same as cpu_V0. */
8584 cpu_M0 = tcg_temp_new(TCG_TYPE_I64);
8585 next_page_start = (pc_start & TARGET_PAGE_MASK) + TARGET_PAGE_SIZE;
8587 /* Reset the conditional execution bits immediately. This avoids
8588 complications trying to do it at the end of the block. */
8589 if (env->condexec_bits)
8591 TCGv tmp = new_tmp();
8592 tcg_gen_movi_i32(tmp, 0);
8593 store_cpu_field(tmp, condexec_bits);
8596 #ifndef CONFIG_USER_ONLY
8597 if (dc->pc >= 0xfffffff0 && IS_M(env)) {
8598 /* We always get here via a jump, so know we are not in a
8599 conditional execution block. */
8600 gen_exception(EXCP_EXCEPTION_EXIT);
8604 if (env->nb_breakpoints > 0) {
8605 for(j = 0; j < env->nb_breakpoints; j++) {
8606 if (env->breakpoints[j] == dc->pc) {
8607 gen_set_condexec(dc);
8608 gen_set_pc_im(dc->pc);
8609 gen_exception(EXCP_DEBUG);
8610 dc->is_jmp = DISAS_JUMP;
8611 /* Advance PC so that clearing the breakpoint will
8612 invalidate this TB. */
8614 goto done_generating;
8620 j = gen_opc_ptr - gen_opc_buf;
8624 gen_opc_instr_start[lj++] = 0;
8626 gen_opc_pc[lj] = dc->pc;
8627 gen_opc_instr_start[lj] = 1;
8631 disas_thumb_insn(env, dc);
8632 if (dc->condexec_mask) {
8633 dc->condexec_cond = (dc->condexec_cond & 0xe)
8634 | ((dc->condexec_mask >> 4) & 1);
8635 dc->condexec_mask = (dc->condexec_mask << 1) & 0x1f;
8636 if (dc->condexec_mask == 0) {
8637 dc->condexec_cond = 0;
8641 disas_arm_insn(env, dc);
8644 fprintf(stderr, "Internal resource leak before %08x\n", dc->pc);
8648 if (dc->condjmp && !dc->is_jmp) {
8649 gen_set_label(dc->condlabel);
8652 /* Terminate the TB on memory ops if watchpoints are present. */
8653 /* FIXME: This should be replacd by the deterministic execution
8654 * IRQ raising bits. */
8655 if (dc->is_mem && env->nb_watchpoints)
8658 /* Translation stops when a conditional branch is enoutered.
8659 * Otherwise the subsequent code could get translated several times.
8660 * Also stop translation when a page boundary is reached. This
8661 * ensures prefech aborts occur at the right place. */
8662 } while (!dc->is_jmp && gen_opc_ptr < gen_opc_end &&
8663 !env->singlestep_enabled &&
8664 dc->pc < next_page_start);
8666 /* At this stage dc->condjmp will only be set when the skipped
8667 instruction was a conditional branch or trap, and the PC has
8668 already been written. */
8669 if (__builtin_expect(env->singlestep_enabled, 0)) {
8670 /* Make sure the pc is updated, and raise a debug exception. */
8672 gen_set_condexec(dc);
8673 if (dc->is_jmp == DISAS_SWI) {
8674 gen_exception(EXCP_SWI);
8676 gen_exception(EXCP_DEBUG);
8678 gen_set_label(dc->condlabel);
8680 if (dc->condjmp || !dc->is_jmp) {
8681 gen_set_pc_im(dc->pc);
8684 gen_set_condexec(dc);
8685 if (dc->is_jmp == DISAS_SWI && !dc->condjmp) {
8686 gen_exception(EXCP_SWI);
8688 /* FIXME: Single stepping a WFI insn will not halt
8690 gen_exception(EXCP_DEBUG);
8693 /* While branches must always occur at the end of an IT block,
8694 there are a few other things that can cause us to terminate
8695 the TB in the middel of an IT block:
8696 - Exception generating instructions (bkpt, swi, undefined).
8698 - Hardware watchpoints.
8699 Hardware breakpoints have already been handled and skip this code.
8701 gen_set_condexec(dc);
8702 switch(dc->is_jmp) {
8704 gen_goto_tb(dc, 1, dc->pc);
8709 /* indicate that the hash table must be used to find the next TB */
8713 /* nothing more to generate */
8719 gen_exception(EXCP_SWI);
8723 gen_set_label(dc->condlabel);
8724 gen_set_condexec(dc);
8725 gen_goto_tb(dc, 1, dc->pc);
8730 *gen_opc_ptr = INDEX_op_end;
8733 if (loglevel & CPU_LOG_TB_IN_ASM) {
8734 fprintf(logfile, "----------------\n");
8735 fprintf(logfile, "IN: %s\n", lookup_symbol(pc_start));
8736 target_disas(logfile, pc_start, dc->pc - pc_start, env->thumb);
8737 fprintf(logfile, "\n");
8741 j = gen_opc_ptr - gen_opc_buf;
8744 gen_opc_instr_start[lj++] = 0;
8746 tb->size = dc->pc - pc_start;
8751 int gen_intermediate_code(CPUState *env, TranslationBlock *tb)
8753 return gen_intermediate_code_internal(env, tb, 0);
8756 int gen_intermediate_code_pc(CPUState *env, TranslationBlock *tb)
8758 return gen_intermediate_code_internal(env, tb, 1);
8761 static const char *cpu_mode_names[16] = {
8762 "usr", "fiq", "irq", "svc", "???", "???", "???", "abt",
8763 "???", "???", "???", "und", "???", "???", "???", "sys"
8766 void cpu_dump_state(CPUState *env, FILE *f,
8767 int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
8776 /* ??? This assumes float64 and double have the same layout.
8777 Oh well, it's only debug dumps. */
8785 cpu_fprintf(f, "R%02d=%08x", i, env->regs[i]);
8787 cpu_fprintf(f, "\n");
8789 cpu_fprintf(f, " ");
8791 psr = cpsr_read(env);
8792 cpu_fprintf(f, "PSR=%08x %c%c%c%c %c %s%d\n",
8794 psr & (1 << 31) ? 'N' : '-',
8795 psr & (1 << 30) ? 'Z' : '-',
8796 psr & (1 << 29) ? 'C' : '-',
8797 psr & (1 << 28) ? 'V' : '-',
8798 psr & CPSR_T ? 'T' : 'A',
8799 cpu_mode_names[psr & 0xf], (psr & 0x10) ? 32 : 26);
8802 for (i = 0; i < 16; i++) {
8803 d.d = env->vfp.regs[i];
8807 cpu_fprintf(f, "s%02d=%08x(%8g) s%02d=%08x(%8g) d%02d=%08x%08x(%8g)\n",
8808 i * 2, (int)s0.i, s0.s,
8809 i * 2 + 1, (int)s1.i, s1.s,
8810 i, (int)(uint32_t)d.l.upper, (int)(uint32_t)d.l.lower,
8813 cpu_fprintf(f, "FPSCR: %08x\n", (int)env->vfp.xregs[ARM_VFP_FPSCR]);
8817 void gen_pc_load(CPUState *env, TranslationBlock *tb,
8818 unsigned long searched_pc, int pc_pos, void *puc)
8820 env->regs[15] = gen_opc_pc[pc_pos];