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, see <http://www.gnu.org/licenses/>.
37 #define ENABLE_ARCH_5J 0
38 #define ENABLE_ARCH_6 arm_feature(env, ARM_FEATURE_V6)
39 #define ENABLE_ARCH_6K arm_feature(env, ARM_FEATURE_V6K)
40 #define ENABLE_ARCH_6T2 arm_feature(env, ARM_FEATURE_THUMB2)
41 #define ENABLE_ARCH_7 arm_feature(env, ARM_FEATURE_V7)
43 #define ARCH(x) do { if (!ENABLE_ARCH_##x) goto illegal_op; } while(0)
45 /* internal defines */
46 typedef struct DisasContext {
49 /* Nonzero if this instruction has been conditionally skipped. */
51 /* The label that will be jumped to when the instruction is skipped. */
53 /* Thumb-2 condtional execution bits. */
56 struct TranslationBlock *tb;
57 int singlestep_enabled;
59 #if !defined(CONFIG_USER_ONLY)
67 static uint32_t gen_opc_condexec_bits[OPC_BUF_SIZE];
69 #if defined(CONFIG_USER_ONLY)
72 #define IS_USER(s) (s->user)
75 /* These instructions trap after executing, so defer them until after the
76 conditional executions state has been updated. */
80 static TCGv_ptr cpu_env;
81 /* We reuse the same 64-bit temporaries for efficiency. */
82 static TCGv_i64 cpu_V0, cpu_V1, cpu_M0;
83 static TCGv_i32 cpu_R[16];
84 static TCGv_i32 cpu_exclusive_addr;
85 static TCGv_i32 cpu_exclusive_val;
86 static TCGv_i32 cpu_exclusive_high;
87 #ifdef CONFIG_USER_ONLY
88 static TCGv_i32 cpu_exclusive_test;
89 static TCGv_i32 cpu_exclusive_info;
92 /* FIXME: These should be removed. */
93 static TCGv cpu_F0s, cpu_F1s;
94 static TCGv_i64 cpu_F0d, cpu_F1d;
96 #include "gen-icount.h"
98 static const char *regnames[] =
99 { "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
100 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "pc" };
102 /* initialize TCG globals. */
103 void arm_translate_init(void)
107 cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");
109 for (i = 0; i < 16; i++) {
110 cpu_R[i] = tcg_global_mem_new_i32(TCG_AREG0,
111 offsetof(CPUState, regs[i]),
114 cpu_exclusive_addr = tcg_global_mem_new_i32(TCG_AREG0,
115 offsetof(CPUState, exclusive_addr), "exclusive_addr");
116 cpu_exclusive_val = tcg_global_mem_new_i32(TCG_AREG0,
117 offsetof(CPUState, exclusive_val), "exclusive_val");
118 cpu_exclusive_high = tcg_global_mem_new_i32(TCG_AREG0,
119 offsetof(CPUState, exclusive_high), "exclusive_high");
120 #ifdef CONFIG_USER_ONLY
121 cpu_exclusive_test = tcg_global_mem_new_i32(TCG_AREG0,
122 offsetof(CPUState, exclusive_test), "exclusive_test");
123 cpu_exclusive_info = tcg_global_mem_new_i32(TCG_AREG0,
124 offsetof(CPUState, exclusive_info), "exclusive_info");
131 static int num_temps;
133 /* Allocate a temporary variable. */
134 static TCGv_i32 new_tmp(void)
137 return tcg_temp_new_i32();
140 /* Release a temporary variable. */
141 static void dead_tmp(TCGv tmp)
147 static inline TCGv load_cpu_offset(int offset)
149 TCGv tmp = new_tmp();
150 tcg_gen_ld_i32(tmp, cpu_env, offset);
154 #define load_cpu_field(name) load_cpu_offset(offsetof(CPUState, name))
156 static inline void store_cpu_offset(TCGv var, int offset)
158 tcg_gen_st_i32(var, cpu_env, offset);
162 #define store_cpu_field(var, name) \
163 store_cpu_offset(var, offsetof(CPUState, name))
165 /* Set a variable to the value of a CPU register. */
166 static void load_reg_var(DisasContext *s, TCGv var, int reg)
170 /* normaly, since we updated PC, we need only to add one insn */
172 addr = (long)s->pc + 2;
174 addr = (long)s->pc + 4;
175 tcg_gen_movi_i32(var, addr);
177 tcg_gen_mov_i32(var, cpu_R[reg]);
181 /* Create a new temporary and set it to the value of a CPU register. */
182 static inline TCGv load_reg(DisasContext *s, int reg)
184 TCGv tmp = new_tmp();
185 load_reg_var(s, tmp, reg);
189 /* Set a CPU register. The source must be a temporary and will be
191 static void store_reg(DisasContext *s, int reg, TCGv var)
194 tcg_gen_andi_i32(var, var, ~1);
195 s->is_jmp = DISAS_JUMP;
197 tcg_gen_mov_i32(cpu_R[reg], var);
201 /* Value extensions. */
202 #define gen_uxtb(var) tcg_gen_ext8u_i32(var, var)
203 #define gen_uxth(var) tcg_gen_ext16u_i32(var, var)
204 #define gen_sxtb(var) tcg_gen_ext8s_i32(var, var)
205 #define gen_sxth(var) tcg_gen_ext16s_i32(var, var)
207 #define gen_sxtb16(var) gen_helper_sxtb16(var, var)
208 #define gen_uxtb16(var) gen_helper_uxtb16(var, var)
211 static inline void gen_set_cpsr(TCGv var, uint32_t mask)
213 TCGv tmp_mask = tcg_const_i32(mask);
214 gen_helper_cpsr_write(var, tmp_mask);
215 tcg_temp_free_i32(tmp_mask);
217 /* Set NZCV flags from the high 4 bits of var. */
218 #define gen_set_nzcv(var) gen_set_cpsr(var, CPSR_NZCV)
220 static void gen_exception(int excp)
222 TCGv tmp = new_tmp();
223 tcg_gen_movi_i32(tmp, excp);
224 gen_helper_exception(tmp);
228 static void gen_smul_dual(TCGv a, TCGv b)
230 TCGv tmp1 = new_tmp();
231 TCGv tmp2 = new_tmp();
232 tcg_gen_ext16s_i32(tmp1, a);
233 tcg_gen_ext16s_i32(tmp2, b);
234 tcg_gen_mul_i32(tmp1, tmp1, tmp2);
236 tcg_gen_sari_i32(a, a, 16);
237 tcg_gen_sari_i32(b, b, 16);
238 tcg_gen_mul_i32(b, b, a);
239 tcg_gen_mov_i32(a, tmp1);
243 /* Byteswap each halfword. */
244 static void gen_rev16(TCGv var)
246 TCGv tmp = new_tmp();
247 tcg_gen_shri_i32(tmp, var, 8);
248 tcg_gen_andi_i32(tmp, tmp, 0x00ff00ff);
249 tcg_gen_shli_i32(var, var, 8);
250 tcg_gen_andi_i32(var, var, 0xff00ff00);
251 tcg_gen_or_i32(var, var, tmp);
255 /* Byteswap low halfword and sign extend. */
256 static void gen_revsh(TCGv var)
258 tcg_gen_ext16u_i32(var, var);
259 tcg_gen_bswap16_i32(var, var);
260 tcg_gen_ext16s_i32(var, var);
263 /* Unsigned bitfield extract. */
264 static void gen_ubfx(TCGv var, int shift, uint32_t mask)
267 tcg_gen_shri_i32(var, var, shift);
268 tcg_gen_andi_i32(var, var, mask);
271 /* Signed bitfield extract. */
272 static void gen_sbfx(TCGv var, int shift, int width)
277 tcg_gen_sari_i32(var, var, shift);
278 if (shift + width < 32) {
279 signbit = 1u << (width - 1);
280 tcg_gen_andi_i32(var, var, (1u << width) - 1);
281 tcg_gen_xori_i32(var, var, signbit);
282 tcg_gen_subi_i32(var, var, signbit);
286 /* Bitfield insertion. Insert val into base. Clobbers base and val. */
287 static void gen_bfi(TCGv dest, TCGv base, TCGv val, int shift, uint32_t mask)
289 tcg_gen_andi_i32(val, val, mask);
290 tcg_gen_shli_i32(val, val, shift);
291 tcg_gen_andi_i32(base, base, ~(mask << shift));
292 tcg_gen_or_i32(dest, base, val);
295 /* Return (b << 32) + a. Mark inputs as dead */
296 static TCGv_i64 gen_addq_msw(TCGv_i64 a, TCGv b)
298 TCGv_i64 tmp64 = tcg_temp_new_i64();
300 tcg_gen_extu_i32_i64(tmp64, b);
302 tcg_gen_shli_i64(tmp64, tmp64, 32);
303 tcg_gen_add_i64(a, tmp64, a);
305 tcg_temp_free_i64(tmp64);
309 /* Return (b << 32) - a. Mark inputs as dead. */
310 static TCGv_i64 gen_subq_msw(TCGv_i64 a, TCGv b)
312 TCGv_i64 tmp64 = tcg_temp_new_i64();
314 tcg_gen_extu_i32_i64(tmp64, b);
316 tcg_gen_shli_i64(tmp64, tmp64, 32);
317 tcg_gen_sub_i64(a, tmp64, a);
319 tcg_temp_free_i64(tmp64);
323 /* FIXME: Most targets have native widening multiplication.
324 It would be good to use that instead of a full wide multiply. */
325 /* 32x32->64 multiply. Marks inputs as dead. */
326 static TCGv_i64 gen_mulu_i64_i32(TCGv a, TCGv b)
328 TCGv_i64 tmp1 = tcg_temp_new_i64();
329 TCGv_i64 tmp2 = tcg_temp_new_i64();
331 tcg_gen_extu_i32_i64(tmp1, a);
333 tcg_gen_extu_i32_i64(tmp2, b);
335 tcg_gen_mul_i64(tmp1, tmp1, tmp2);
336 tcg_temp_free_i64(tmp2);
340 static TCGv_i64 gen_muls_i64_i32(TCGv a, TCGv b)
342 TCGv_i64 tmp1 = tcg_temp_new_i64();
343 TCGv_i64 tmp2 = tcg_temp_new_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);
350 tcg_temp_free_i64(tmp2);
354 /* Swap low and high halfwords. */
355 static void gen_swap_half(TCGv var)
357 TCGv tmp = new_tmp();
358 tcg_gen_shri_i32(tmp, var, 16);
359 tcg_gen_shli_i32(var, var, 16);
360 tcg_gen_or_i32(var, var, tmp);
364 /* Dual 16-bit add. Result placed in t0 and t1 is marked as dead.
365 tmp = (t0 ^ t1) & 0x8000;
368 t0 = (t0 + t1) ^ tmp;
371 static void gen_add16(TCGv t0, TCGv t1)
373 TCGv tmp = new_tmp();
374 tcg_gen_xor_i32(tmp, t0, t1);
375 tcg_gen_andi_i32(tmp, tmp, 0x8000);
376 tcg_gen_andi_i32(t0, t0, ~0x8000);
377 tcg_gen_andi_i32(t1, t1, ~0x8000);
378 tcg_gen_add_i32(t0, t0, t1);
379 tcg_gen_xor_i32(t0, t0, tmp);
384 #define gen_set_CF(var) tcg_gen_st_i32(var, cpu_env, offsetof(CPUState, CF))
386 /* Set CF to the top bit of var. */
387 static void gen_set_CF_bit31(TCGv var)
389 TCGv tmp = new_tmp();
390 tcg_gen_shri_i32(tmp, var, 31);
395 /* Set N and Z flags from var. */
396 static inline void gen_logic_CC(TCGv var)
398 tcg_gen_st_i32(var, cpu_env, offsetof(CPUState, NF));
399 tcg_gen_st_i32(var, cpu_env, offsetof(CPUState, ZF));
403 static void gen_adc(TCGv t0, TCGv t1)
406 tcg_gen_add_i32(t0, t0, t1);
407 tmp = load_cpu_field(CF);
408 tcg_gen_add_i32(t0, t0, tmp);
412 /* dest = T0 + T1 + CF. */
413 static void gen_add_carry(TCGv dest, TCGv t0, TCGv t1)
416 tcg_gen_add_i32(dest, t0, t1);
417 tmp = load_cpu_field(CF);
418 tcg_gen_add_i32(dest, dest, tmp);
422 /* dest = T0 - T1 + CF - 1. */
423 static void gen_sub_carry(TCGv dest, TCGv t0, TCGv t1)
426 tcg_gen_sub_i32(dest, t0, t1);
427 tmp = load_cpu_field(CF);
428 tcg_gen_add_i32(dest, dest, tmp);
429 tcg_gen_subi_i32(dest, dest, 1);
433 /* FIXME: Implement this natively. */
434 #define tcg_gen_abs_i32(t0, t1) gen_helper_abs(t0, t1)
436 static void shifter_out_im(TCGv var, int shift)
438 TCGv tmp = new_tmp();
440 tcg_gen_andi_i32(tmp, var, 1);
442 tcg_gen_shri_i32(tmp, var, shift);
444 tcg_gen_andi_i32(tmp, tmp, 1);
450 /* Shift by immediate. Includes special handling for shift == 0. */
451 static inline void gen_arm_shift_im(TCGv var, int shiftop, int shift, int flags)
457 shifter_out_im(var, 32 - shift);
458 tcg_gen_shli_i32(var, var, shift);
464 tcg_gen_shri_i32(var, var, 31);
467 tcg_gen_movi_i32(var, 0);
470 shifter_out_im(var, shift - 1);
471 tcg_gen_shri_i32(var, var, shift);
478 shifter_out_im(var, shift - 1);
481 tcg_gen_sari_i32(var, var, shift);
483 case 3: /* ROR/RRX */
486 shifter_out_im(var, shift - 1);
487 tcg_gen_rotri_i32(var, var, shift); break;
489 TCGv tmp = load_cpu_field(CF);
491 shifter_out_im(var, 0);
492 tcg_gen_shri_i32(var, var, 1);
493 tcg_gen_shli_i32(tmp, tmp, 31);
494 tcg_gen_or_i32(var, var, tmp);
500 static inline void gen_arm_shift_reg(TCGv var, int shiftop,
501 TCGv shift, int flags)
505 case 0: gen_helper_shl_cc(var, var, shift); break;
506 case 1: gen_helper_shr_cc(var, var, shift); break;
507 case 2: gen_helper_sar_cc(var, var, shift); break;
508 case 3: gen_helper_ror_cc(var, var, shift); break;
512 case 0: gen_helper_shl(var, var, shift); break;
513 case 1: gen_helper_shr(var, var, shift); break;
514 case 2: gen_helper_sar(var, var, shift); break;
515 case 3: tcg_gen_andi_i32(shift, shift, 0x1f);
516 tcg_gen_rotr_i32(var, var, shift); break;
522 #define PAS_OP(pfx) \
524 case 0: gen_pas_helper(glue(pfx,add16)); break; \
525 case 1: gen_pas_helper(glue(pfx,addsubx)); break; \
526 case 2: gen_pas_helper(glue(pfx,subaddx)); break; \
527 case 3: gen_pas_helper(glue(pfx,sub16)); break; \
528 case 4: gen_pas_helper(glue(pfx,add8)); break; \
529 case 7: gen_pas_helper(glue(pfx,sub8)); break; \
531 static void gen_arm_parallel_addsub(int op1, int op2, TCGv a, TCGv b)
536 #define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b, tmp)
538 tmp = tcg_temp_new_ptr();
539 tcg_gen_addi_ptr(tmp, cpu_env, offsetof(CPUState, GE));
541 tcg_temp_free_ptr(tmp);
544 tmp = tcg_temp_new_ptr();
545 tcg_gen_addi_ptr(tmp, cpu_env, offsetof(CPUState, GE));
547 tcg_temp_free_ptr(tmp);
549 #undef gen_pas_helper
550 #define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b)
563 #undef gen_pas_helper
568 /* For unknown reasons Arm and Thumb-2 use arbitrarily different encodings. */
569 #define PAS_OP(pfx) \
571 case 0: gen_pas_helper(glue(pfx,add8)); break; \
572 case 1: gen_pas_helper(glue(pfx,add16)); break; \
573 case 2: gen_pas_helper(glue(pfx,addsubx)); break; \
574 case 4: gen_pas_helper(glue(pfx,sub8)); break; \
575 case 5: gen_pas_helper(glue(pfx,sub16)); break; \
576 case 6: gen_pas_helper(glue(pfx,subaddx)); break; \
578 static void gen_thumb2_parallel_addsub(int op1, int op2, TCGv a, TCGv b)
583 #define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b, tmp)
585 tmp = tcg_temp_new_ptr();
586 tcg_gen_addi_ptr(tmp, cpu_env, offsetof(CPUState, GE));
588 tcg_temp_free_ptr(tmp);
591 tmp = tcg_temp_new_ptr();
592 tcg_gen_addi_ptr(tmp, cpu_env, offsetof(CPUState, GE));
594 tcg_temp_free_ptr(tmp);
596 #undef gen_pas_helper
597 #define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b)
610 #undef gen_pas_helper
615 static void gen_test_cc(int cc, int label)
623 tmp = load_cpu_field(ZF);
624 tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 0, label);
627 tmp = load_cpu_field(ZF);
628 tcg_gen_brcondi_i32(TCG_COND_NE, tmp, 0, label);
631 tmp = load_cpu_field(CF);
632 tcg_gen_brcondi_i32(TCG_COND_NE, tmp, 0, label);
635 tmp = load_cpu_field(CF);
636 tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 0, label);
639 tmp = load_cpu_field(NF);
640 tcg_gen_brcondi_i32(TCG_COND_LT, tmp, 0, label);
643 tmp = load_cpu_field(NF);
644 tcg_gen_brcondi_i32(TCG_COND_GE, tmp, 0, label);
647 tmp = load_cpu_field(VF);
648 tcg_gen_brcondi_i32(TCG_COND_LT, tmp, 0, label);
651 tmp = load_cpu_field(VF);
652 tcg_gen_brcondi_i32(TCG_COND_GE, tmp, 0, label);
654 case 8: /* hi: C && !Z */
655 inv = gen_new_label();
656 tmp = load_cpu_field(CF);
657 tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 0, inv);
659 tmp = load_cpu_field(ZF);
660 tcg_gen_brcondi_i32(TCG_COND_NE, tmp, 0, label);
663 case 9: /* ls: !C || Z */
664 tmp = load_cpu_field(CF);
665 tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 0, label);
667 tmp = load_cpu_field(ZF);
668 tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 0, label);
670 case 10: /* ge: N == V -> N ^ V == 0 */
671 tmp = load_cpu_field(VF);
672 tmp2 = load_cpu_field(NF);
673 tcg_gen_xor_i32(tmp, tmp, tmp2);
675 tcg_gen_brcondi_i32(TCG_COND_GE, tmp, 0, label);
677 case 11: /* lt: N != V -> N ^ V != 0 */
678 tmp = load_cpu_field(VF);
679 tmp2 = load_cpu_field(NF);
680 tcg_gen_xor_i32(tmp, tmp, tmp2);
682 tcg_gen_brcondi_i32(TCG_COND_LT, tmp, 0, label);
684 case 12: /* gt: !Z && N == V */
685 inv = gen_new_label();
686 tmp = load_cpu_field(ZF);
687 tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 0, inv);
689 tmp = load_cpu_field(VF);
690 tmp2 = load_cpu_field(NF);
691 tcg_gen_xor_i32(tmp, tmp, tmp2);
693 tcg_gen_brcondi_i32(TCG_COND_GE, tmp, 0, label);
696 case 13: /* le: Z || N != V */
697 tmp = load_cpu_field(ZF);
698 tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 0, label);
700 tmp = load_cpu_field(VF);
701 tmp2 = load_cpu_field(NF);
702 tcg_gen_xor_i32(tmp, tmp, tmp2);
704 tcg_gen_brcondi_i32(TCG_COND_LT, tmp, 0, label);
707 fprintf(stderr, "Bad condition code 0x%x\n", cc);
713 static const uint8_t table_logic_cc[16] = {
732 /* Set PC and Thumb state from an immediate address. */
733 static inline void gen_bx_im(DisasContext *s, uint32_t addr)
737 s->is_jmp = DISAS_UPDATE;
738 if (s->thumb != (addr & 1)) {
740 tcg_gen_movi_i32(tmp, addr & 1);
741 tcg_gen_st_i32(tmp, cpu_env, offsetof(CPUState, thumb));
744 tcg_gen_movi_i32(cpu_R[15], addr & ~1);
747 /* Set PC and Thumb state from var. var is marked as dead. */
748 static inline void gen_bx(DisasContext *s, TCGv var)
750 s->is_jmp = DISAS_UPDATE;
751 tcg_gen_andi_i32(cpu_R[15], var, ~1);
752 tcg_gen_andi_i32(var, var, 1);
753 store_cpu_field(var, thumb);
756 /* Variant of store_reg which uses branch&exchange logic when storing
757 to r15 in ARM architecture v7 and above. The source must be a temporary
758 and will be marked as dead. */
759 static inline void store_reg_bx(CPUState *env, DisasContext *s,
762 if (reg == 15 && ENABLE_ARCH_7) {
765 store_reg(s, reg, var);
769 static inline TCGv gen_ld8s(TCGv addr, int index)
771 TCGv tmp = new_tmp();
772 tcg_gen_qemu_ld8s(tmp, addr, index);
775 static inline TCGv gen_ld8u(TCGv addr, int index)
777 TCGv tmp = new_tmp();
778 tcg_gen_qemu_ld8u(tmp, addr, index);
781 static inline TCGv gen_ld16s(TCGv addr, int index)
783 TCGv tmp = new_tmp();
784 tcg_gen_qemu_ld16s(tmp, addr, index);
787 static inline TCGv gen_ld16u(TCGv addr, int index)
789 TCGv tmp = new_tmp();
790 tcg_gen_qemu_ld16u(tmp, addr, index);
793 static inline TCGv gen_ld32(TCGv addr, int index)
795 TCGv tmp = new_tmp();
796 tcg_gen_qemu_ld32u(tmp, addr, index);
799 static inline TCGv_i64 gen_ld64(TCGv addr, int index)
801 TCGv_i64 tmp = tcg_temp_new_i64();
802 tcg_gen_qemu_ld64(tmp, addr, index);
805 static inline void gen_st8(TCGv val, TCGv addr, int index)
807 tcg_gen_qemu_st8(val, addr, index);
810 static inline void gen_st16(TCGv val, TCGv addr, int index)
812 tcg_gen_qemu_st16(val, addr, index);
815 static inline void gen_st32(TCGv val, TCGv addr, int index)
817 tcg_gen_qemu_st32(val, addr, index);
820 static inline void gen_st64(TCGv_i64 val, TCGv addr, int index)
822 tcg_gen_qemu_st64(val, addr, index);
823 tcg_temp_free_i64(val);
826 static inline void gen_set_pc_im(uint32_t val)
828 tcg_gen_movi_i32(cpu_R[15], val);
831 /* Force a TB lookup after an instruction that changes the CPU state. */
832 static inline void gen_lookup_tb(DisasContext *s)
834 tcg_gen_movi_i32(cpu_R[15], s->pc & ~1);
835 s->is_jmp = DISAS_UPDATE;
838 static inline void gen_add_data_offset(DisasContext *s, unsigned int insn,
841 int val, rm, shift, shiftop;
844 if (!(insn & (1 << 25))) {
847 if (!(insn & (1 << 23)))
850 tcg_gen_addi_i32(var, var, val);
854 shift = (insn >> 7) & 0x1f;
855 shiftop = (insn >> 5) & 3;
856 offset = load_reg(s, rm);
857 gen_arm_shift_im(offset, shiftop, shift, 0);
858 if (!(insn & (1 << 23)))
859 tcg_gen_sub_i32(var, var, offset);
861 tcg_gen_add_i32(var, var, offset);
866 static inline void gen_add_datah_offset(DisasContext *s, unsigned int insn,
872 if (insn & (1 << 22)) {
874 val = (insn & 0xf) | ((insn >> 4) & 0xf0);
875 if (!(insn & (1 << 23)))
879 tcg_gen_addi_i32(var, var, val);
883 tcg_gen_addi_i32(var, var, extra);
885 offset = load_reg(s, rm);
886 if (!(insn & (1 << 23)))
887 tcg_gen_sub_i32(var, var, offset);
889 tcg_gen_add_i32(var, var, offset);
894 #define VFP_OP2(name) \
895 static inline void gen_vfp_##name(int dp) \
898 gen_helper_vfp_##name##d(cpu_F0d, cpu_F0d, cpu_F1d, cpu_env); \
900 gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, cpu_F1s, cpu_env); \
910 static inline void gen_vfp_abs(int dp)
913 gen_helper_vfp_absd(cpu_F0d, cpu_F0d);
915 gen_helper_vfp_abss(cpu_F0s, cpu_F0s);
918 static inline void gen_vfp_neg(int dp)
921 gen_helper_vfp_negd(cpu_F0d, cpu_F0d);
923 gen_helper_vfp_negs(cpu_F0s, cpu_F0s);
926 static inline void gen_vfp_sqrt(int dp)
929 gen_helper_vfp_sqrtd(cpu_F0d, cpu_F0d, cpu_env);
931 gen_helper_vfp_sqrts(cpu_F0s, cpu_F0s, cpu_env);
934 static inline void gen_vfp_cmp(int dp)
937 gen_helper_vfp_cmpd(cpu_F0d, cpu_F1d, cpu_env);
939 gen_helper_vfp_cmps(cpu_F0s, cpu_F1s, cpu_env);
942 static inline void gen_vfp_cmpe(int dp)
945 gen_helper_vfp_cmped(cpu_F0d, cpu_F1d, cpu_env);
947 gen_helper_vfp_cmpes(cpu_F0s, cpu_F1s, cpu_env);
950 static inline void gen_vfp_F1_ld0(int dp)
953 tcg_gen_movi_i64(cpu_F1d, 0);
955 tcg_gen_movi_i32(cpu_F1s, 0);
958 static inline void gen_vfp_uito(int dp)
961 gen_helper_vfp_uitod(cpu_F0d, cpu_F0s, cpu_env);
963 gen_helper_vfp_uitos(cpu_F0s, cpu_F0s, cpu_env);
966 static inline void gen_vfp_sito(int dp)
969 gen_helper_vfp_sitod(cpu_F0d, cpu_F0s, cpu_env);
971 gen_helper_vfp_sitos(cpu_F0s, cpu_F0s, cpu_env);
974 static inline void gen_vfp_toui(int dp)
977 gen_helper_vfp_touid(cpu_F0s, cpu_F0d, cpu_env);
979 gen_helper_vfp_touis(cpu_F0s, cpu_F0s, cpu_env);
982 static inline void gen_vfp_touiz(int dp)
985 gen_helper_vfp_touizd(cpu_F0s, cpu_F0d, cpu_env);
987 gen_helper_vfp_touizs(cpu_F0s, cpu_F0s, cpu_env);
990 static inline void gen_vfp_tosi(int dp)
993 gen_helper_vfp_tosid(cpu_F0s, cpu_F0d, cpu_env);
995 gen_helper_vfp_tosis(cpu_F0s, cpu_F0s, cpu_env);
998 static inline void gen_vfp_tosiz(int dp)
1001 gen_helper_vfp_tosizd(cpu_F0s, cpu_F0d, cpu_env);
1003 gen_helper_vfp_tosizs(cpu_F0s, cpu_F0s, cpu_env);
1006 #define VFP_GEN_FIX(name) \
1007 static inline void gen_vfp_##name(int dp, int shift) \
1009 TCGv tmp_shift = tcg_const_i32(shift); \
1011 gen_helper_vfp_##name##d(cpu_F0d, cpu_F0d, tmp_shift, cpu_env);\
1013 gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, tmp_shift, cpu_env);\
1014 tcg_temp_free_i32(tmp_shift); \
1026 static inline void gen_vfp_ld(DisasContext *s, int dp, TCGv addr)
1029 tcg_gen_qemu_ld64(cpu_F0d, addr, IS_USER(s));
1031 tcg_gen_qemu_ld32u(cpu_F0s, addr, IS_USER(s));
1034 static inline void gen_vfp_st(DisasContext *s, int dp, TCGv addr)
1037 tcg_gen_qemu_st64(cpu_F0d, addr, IS_USER(s));
1039 tcg_gen_qemu_st32(cpu_F0s, addr, IS_USER(s));
1043 vfp_reg_offset (int dp, int reg)
1046 return offsetof(CPUARMState, vfp.regs[reg]);
1048 return offsetof(CPUARMState, vfp.regs[reg >> 1])
1049 + offsetof(CPU_DoubleU, l.upper);
1051 return offsetof(CPUARMState, vfp.regs[reg >> 1])
1052 + offsetof(CPU_DoubleU, l.lower);
1056 /* Return the offset of a 32-bit piece of a NEON register.
1057 zero is the least significant end of the register. */
1059 neon_reg_offset (int reg, int n)
1063 return vfp_reg_offset(0, sreg);
1066 static TCGv neon_load_reg(int reg, int pass)
1068 TCGv tmp = new_tmp();
1069 tcg_gen_ld_i32(tmp, cpu_env, neon_reg_offset(reg, pass));
1073 static void neon_store_reg(int reg, int pass, TCGv var)
1075 tcg_gen_st_i32(var, cpu_env, neon_reg_offset(reg, pass));
1079 static inline void neon_load_reg64(TCGv_i64 var, int reg)
1081 tcg_gen_ld_i64(var, cpu_env, vfp_reg_offset(1, reg));
1084 static inline void neon_store_reg64(TCGv_i64 var, int reg)
1086 tcg_gen_st_i64(var, cpu_env, vfp_reg_offset(1, reg));
1089 #define tcg_gen_ld_f32 tcg_gen_ld_i32
1090 #define tcg_gen_ld_f64 tcg_gen_ld_i64
1091 #define tcg_gen_st_f32 tcg_gen_st_i32
1092 #define tcg_gen_st_f64 tcg_gen_st_i64
1094 static inline void gen_mov_F0_vreg(int dp, int reg)
1097 tcg_gen_ld_f64(cpu_F0d, cpu_env, vfp_reg_offset(dp, reg));
1099 tcg_gen_ld_f32(cpu_F0s, cpu_env, vfp_reg_offset(dp, reg));
1102 static inline void gen_mov_F1_vreg(int dp, int reg)
1105 tcg_gen_ld_f64(cpu_F1d, cpu_env, vfp_reg_offset(dp, reg));
1107 tcg_gen_ld_f32(cpu_F1s, cpu_env, vfp_reg_offset(dp, reg));
1110 static inline void gen_mov_vreg_F0(int dp, int reg)
1113 tcg_gen_st_f64(cpu_F0d, cpu_env, vfp_reg_offset(dp, reg));
1115 tcg_gen_st_f32(cpu_F0s, cpu_env, vfp_reg_offset(dp, reg));
1118 #define ARM_CP_RW_BIT (1 << 20)
1120 static inline void iwmmxt_load_reg(TCGv_i64 var, int reg)
1122 tcg_gen_ld_i64(var, cpu_env, offsetof(CPUState, iwmmxt.regs[reg]));
1125 static inline void iwmmxt_store_reg(TCGv_i64 var, int reg)
1127 tcg_gen_st_i64(var, cpu_env, offsetof(CPUState, iwmmxt.regs[reg]));
1130 static inline TCGv iwmmxt_load_creg(int reg)
1132 TCGv var = new_tmp();
1133 tcg_gen_ld_i32(var, cpu_env, offsetof(CPUState, iwmmxt.cregs[reg]));
1137 static inline void iwmmxt_store_creg(int reg, TCGv var)
1139 tcg_gen_st_i32(var, cpu_env, offsetof(CPUState, iwmmxt.cregs[reg]));
1143 static inline void gen_op_iwmmxt_movq_wRn_M0(int rn)
1145 iwmmxt_store_reg(cpu_M0, rn);
1148 static inline void gen_op_iwmmxt_movq_M0_wRn(int rn)
1150 iwmmxt_load_reg(cpu_M0, rn);
1153 static inline void gen_op_iwmmxt_orq_M0_wRn(int rn)
1155 iwmmxt_load_reg(cpu_V1, rn);
1156 tcg_gen_or_i64(cpu_M0, cpu_M0, cpu_V1);
1159 static inline void gen_op_iwmmxt_andq_M0_wRn(int rn)
1161 iwmmxt_load_reg(cpu_V1, rn);
1162 tcg_gen_and_i64(cpu_M0, cpu_M0, cpu_V1);
1165 static inline void gen_op_iwmmxt_xorq_M0_wRn(int rn)
1167 iwmmxt_load_reg(cpu_V1, rn);
1168 tcg_gen_xor_i64(cpu_M0, cpu_M0, cpu_V1);
1171 #define IWMMXT_OP(name) \
1172 static inline void gen_op_iwmmxt_##name##_M0_wRn(int rn) \
1174 iwmmxt_load_reg(cpu_V1, rn); \
1175 gen_helper_iwmmxt_##name(cpu_M0, cpu_M0, cpu_V1); \
1178 #define IWMMXT_OP_ENV(name) \
1179 static inline void gen_op_iwmmxt_##name##_M0_wRn(int rn) \
1181 iwmmxt_load_reg(cpu_V1, rn); \
1182 gen_helper_iwmmxt_##name(cpu_M0, cpu_env, cpu_M0, cpu_V1); \
1185 #define IWMMXT_OP_ENV_SIZE(name) \
1186 IWMMXT_OP_ENV(name##b) \
1187 IWMMXT_OP_ENV(name##w) \
1188 IWMMXT_OP_ENV(name##l)
1190 #define IWMMXT_OP_ENV1(name) \
1191 static inline void gen_op_iwmmxt_##name##_M0(void) \
1193 gen_helper_iwmmxt_##name(cpu_M0, cpu_env, cpu_M0); \
1207 IWMMXT_OP_ENV_SIZE(unpackl)
1208 IWMMXT_OP_ENV_SIZE(unpackh)
1210 IWMMXT_OP_ENV1(unpacklub)
1211 IWMMXT_OP_ENV1(unpackluw)
1212 IWMMXT_OP_ENV1(unpacklul)
1213 IWMMXT_OP_ENV1(unpackhub)
1214 IWMMXT_OP_ENV1(unpackhuw)
1215 IWMMXT_OP_ENV1(unpackhul)
1216 IWMMXT_OP_ENV1(unpacklsb)
1217 IWMMXT_OP_ENV1(unpacklsw)
1218 IWMMXT_OP_ENV1(unpacklsl)
1219 IWMMXT_OP_ENV1(unpackhsb)
1220 IWMMXT_OP_ENV1(unpackhsw)
1221 IWMMXT_OP_ENV1(unpackhsl)
1223 IWMMXT_OP_ENV_SIZE(cmpeq)
1224 IWMMXT_OP_ENV_SIZE(cmpgtu)
1225 IWMMXT_OP_ENV_SIZE(cmpgts)
1227 IWMMXT_OP_ENV_SIZE(mins)
1228 IWMMXT_OP_ENV_SIZE(minu)
1229 IWMMXT_OP_ENV_SIZE(maxs)
1230 IWMMXT_OP_ENV_SIZE(maxu)
1232 IWMMXT_OP_ENV_SIZE(subn)
1233 IWMMXT_OP_ENV_SIZE(addn)
1234 IWMMXT_OP_ENV_SIZE(subu)
1235 IWMMXT_OP_ENV_SIZE(addu)
1236 IWMMXT_OP_ENV_SIZE(subs)
1237 IWMMXT_OP_ENV_SIZE(adds)
1239 IWMMXT_OP_ENV(avgb0)
1240 IWMMXT_OP_ENV(avgb1)
1241 IWMMXT_OP_ENV(avgw0)
1242 IWMMXT_OP_ENV(avgw1)
1246 IWMMXT_OP_ENV(packuw)
1247 IWMMXT_OP_ENV(packul)
1248 IWMMXT_OP_ENV(packuq)
1249 IWMMXT_OP_ENV(packsw)
1250 IWMMXT_OP_ENV(packsl)
1251 IWMMXT_OP_ENV(packsq)
1253 static void gen_op_iwmmxt_set_mup(void)
1256 tmp = load_cpu_field(iwmmxt.cregs[ARM_IWMMXT_wCon]);
1257 tcg_gen_ori_i32(tmp, tmp, 2);
1258 store_cpu_field(tmp, iwmmxt.cregs[ARM_IWMMXT_wCon]);
1261 static void gen_op_iwmmxt_set_cup(void)
1264 tmp = load_cpu_field(iwmmxt.cregs[ARM_IWMMXT_wCon]);
1265 tcg_gen_ori_i32(tmp, tmp, 1);
1266 store_cpu_field(tmp, iwmmxt.cregs[ARM_IWMMXT_wCon]);
1269 static void gen_op_iwmmxt_setpsr_nz(void)
1271 TCGv tmp = new_tmp();
1272 gen_helper_iwmmxt_setpsr_nz(tmp, cpu_M0);
1273 store_cpu_field(tmp, iwmmxt.cregs[ARM_IWMMXT_wCASF]);
1276 static inline void gen_op_iwmmxt_addl_M0_wRn(int rn)
1278 iwmmxt_load_reg(cpu_V1, rn);
1279 tcg_gen_ext32u_i64(cpu_V1, cpu_V1);
1280 tcg_gen_add_i64(cpu_M0, cpu_M0, cpu_V1);
1283 static inline int gen_iwmmxt_address(DisasContext *s, uint32_t insn, TCGv dest)
1289 rd = (insn >> 16) & 0xf;
1290 tmp = load_reg(s, rd);
1292 offset = (insn & 0xff) << ((insn >> 7) & 2);
1293 if (insn & (1 << 24)) {
1295 if (insn & (1 << 23))
1296 tcg_gen_addi_i32(tmp, tmp, offset);
1298 tcg_gen_addi_i32(tmp, tmp, -offset);
1299 tcg_gen_mov_i32(dest, tmp);
1300 if (insn & (1 << 21))
1301 store_reg(s, rd, tmp);
1304 } else if (insn & (1 << 21)) {
1306 tcg_gen_mov_i32(dest, tmp);
1307 if (insn & (1 << 23))
1308 tcg_gen_addi_i32(tmp, tmp, offset);
1310 tcg_gen_addi_i32(tmp, tmp, -offset);
1311 store_reg(s, rd, tmp);
1312 } else if (!(insn & (1 << 23)))
1317 static inline int gen_iwmmxt_shift(uint32_t insn, uint32_t mask, TCGv dest)
1319 int rd = (insn >> 0) & 0xf;
1322 if (insn & (1 << 8)) {
1323 if (rd < ARM_IWMMXT_wCGR0 || rd > ARM_IWMMXT_wCGR3) {
1326 tmp = iwmmxt_load_creg(rd);
1330 iwmmxt_load_reg(cpu_V0, rd);
1331 tcg_gen_trunc_i64_i32(tmp, cpu_V0);
1333 tcg_gen_andi_i32(tmp, tmp, mask);
1334 tcg_gen_mov_i32(dest, tmp);
1339 /* Disassemble an iwMMXt instruction. Returns nonzero if an error occured
1340 (ie. an undefined instruction). */
1341 static int disas_iwmmxt_insn(CPUState *env, DisasContext *s, uint32_t insn)
1344 int rdhi, rdlo, rd0, rd1, i;
1346 TCGv tmp, tmp2, tmp3;
1348 if ((insn & 0x0e000e00) == 0x0c000000) {
1349 if ((insn & 0x0fe00ff0) == 0x0c400000) {
1351 rdlo = (insn >> 12) & 0xf;
1352 rdhi = (insn >> 16) & 0xf;
1353 if (insn & ARM_CP_RW_BIT) { /* TMRRC */
1354 iwmmxt_load_reg(cpu_V0, wrd);
1355 tcg_gen_trunc_i64_i32(cpu_R[rdlo], cpu_V0);
1356 tcg_gen_shri_i64(cpu_V0, cpu_V0, 32);
1357 tcg_gen_trunc_i64_i32(cpu_R[rdhi], cpu_V0);
1358 } else { /* TMCRR */
1359 tcg_gen_concat_i32_i64(cpu_V0, cpu_R[rdlo], cpu_R[rdhi]);
1360 iwmmxt_store_reg(cpu_V0, wrd);
1361 gen_op_iwmmxt_set_mup();
1366 wrd = (insn >> 12) & 0xf;
1368 if (gen_iwmmxt_address(s, insn, addr)) {
1372 if (insn & ARM_CP_RW_BIT) {
1373 if ((insn >> 28) == 0xf) { /* WLDRW wCx */
1375 tcg_gen_qemu_ld32u(tmp, addr, IS_USER(s));
1376 iwmmxt_store_creg(wrd, tmp);
1379 if (insn & (1 << 8)) {
1380 if (insn & (1 << 22)) { /* WLDRD */
1381 tcg_gen_qemu_ld64(cpu_M0, addr, IS_USER(s));
1383 } else { /* WLDRW wRd */
1384 tmp = gen_ld32(addr, IS_USER(s));
1387 if (insn & (1 << 22)) { /* WLDRH */
1388 tmp = gen_ld16u(addr, IS_USER(s));
1389 } else { /* WLDRB */
1390 tmp = gen_ld8u(addr, IS_USER(s));
1394 tcg_gen_extu_i32_i64(cpu_M0, tmp);
1397 gen_op_iwmmxt_movq_wRn_M0(wrd);
1400 if ((insn >> 28) == 0xf) { /* WSTRW wCx */
1401 tmp = iwmmxt_load_creg(wrd);
1402 gen_st32(tmp, addr, IS_USER(s));
1404 gen_op_iwmmxt_movq_M0_wRn(wrd);
1406 if (insn & (1 << 8)) {
1407 if (insn & (1 << 22)) { /* WSTRD */
1409 tcg_gen_qemu_st64(cpu_M0, addr, IS_USER(s));
1410 } else { /* WSTRW wRd */
1411 tcg_gen_trunc_i64_i32(tmp, cpu_M0);
1412 gen_st32(tmp, addr, IS_USER(s));
1415 if (insn & (1 << 22)) { /* WSTRH */
1416 tcg_gen_trunc_i64_i32(tmp, cpu_M0);
1417 gen_st16(tmp, addr, IS_USER(s));
1418 } else { /* WSTRB */
1419 tcg_gen_trunc_i64_i32(tmp, cpu_M0);
1420 gen_st8(tmp, addr, IS_USER(s));
1429 if ((insn & 0x0f000000) != 0x0e000000)
1432 switch (((insn >> 12) & 0xf00) | ((insn >> 4) & 0xff)) {
1433 case 0x000: /* WOR */
1434 wrd = (insn >> 12) & 0xf;
1435 rd0 = (insn >> 0) & 0xf;
1436 rd1 = (insn >> 16) & 0xf;
1437 gen_op_iwmmxt_movq_M0_wRn(rd0);
1438 gen_op_iwmmxt_orq_M0_wRn(rd1);
1439 gen_op_iwmmxt_setpsr_nz();
1440 gen_op_iwmmxt_movq_wRn_M0(wrd);
1441 gen_op_iwmmxt_set_mup();
1442 gen_op_iwmmxt_set_cup();
1444 case 0x011: /* TMCR */
1447 rd = (insn >> 12) & 0xf;
1448 wrd = (insn >> 16) & 0xf;
1450 case ARM_IWMMXT_wCID:
1451 case ARM_IWMMXT_wCASF:
1453 case ARM_IWMMXT_wCon:
1454 gen_op_iwmmxt_set_cup();
1456 case ARM_IWMMXT_wCSSF:
1457 tmp = iwmmxt_load_creg(wrd);
1458 tmp2 = load_reg(s, rd);
1459 tcg_gen_andc_i32(tmp, tmp, tmp2);
1461 iwmmxt_store_creg(wrd, tmp);
1463 case ARM_IWMMXT_wCGR0:
1464 case ARM_IWMMXT_wCGR1:
1465 case ARM_IWMMXT_wCGR2:
1466 case ARM_IWMMXT_wCGR3:
1467 gen_op_iwmmxt_set_cup();
1468 tmp = load_reg(s, rd);
1469 iwmmxt_store_creg(wrd, tmp);
1475 case 0x100: /* WXOR */
1476 wrd = (insn >> 12) & 0xf;
1477 rd0 = (insn >> 0) & 0xf;
1478 rd1 = (insn >> 16) & 0xf;
1479 gen_op_iwmmxt_movq_M0_wRn(rd0);
1480 gen_op_iwmmxt_xorq_M0_wRn(rd1);
1481 gen_op_iwmmxt_setpsr_nz();
1482 gen_op_iwmmxt_movq_wRn_M0(wrd);
1483 gen_op_iwmmxt_set_mup();
1484 gen_op_iwmmxt_set_cup();
1486 case 0x111: /* TMRC */
1489 rd = (insn >> 12) & 0xf;
1490 wrd = (insn >> 16) & 0xf;
1491 tmp = iwmmxt_load_creg(wrd);
1492 store_reg(s, rd, tmp);
1494 case 0x300: /* WANDN */
1495 wrd = (insn >> 12) & 0xf;
1496 rd0 = (insn >> 0) & 0xf;
1497 rd1 = (insn >> 16) & 0xf;
1498 gen_op_iwmmxt_movq_M0_wRn(rd0);
1499 tcg_gen_neg_i64(cpu_M0, cpu_M0);
1500 gen_op_iwmmxt_andq_M0_wRn(rd1);
1501 gen_op_iwmmxt_setpsr_nz();
1502 gen_op_iwmmxt_movq_wRn_M0(wrd);
1503 gen_op_iwmmxt_set_mup();
1504 gen_op_iwmmxt_set_cup();
1506 case 0x200: /* WAND */
1507 wrd = (insn >> 12) & 0xf;
1508 rd0 = (insn >> 0) & 0xf;
1509 rd1 = (insn >> 16) & 0xf;
1510 gen_op_iwmmxt_movq_M0_wRn(rd0);
1511 gen_op_iwmmxt_andq_M0_wRn(rd1);
1512 gen_op_iwmmxt_setpsr_nz();
1513 gen_op_iwmmxt_movq_wRn_M0(wrd);
1514 gen_op_iwmmxt_set_mup();
1515 gen_op_iwmmxt_set_cup();
1517 case 0x810: case 0xa10: /* WMADD */
1518 wrd = (insn >> 12) & 0xf;
1519 rd0 = (insn >> 0) & 0xf;
1520 rd1 = (insn >> 16) & 0xf;
1521 gen_op_iwmmxt_movq_M0_wRn(rd0);
1522 if (insn & (1 << 21))
1523 gen_op_iwmmxt_maddsq_M0_wRn(rd1);
1525 gen_op_iwmmxt_madduq_M0_wRn(rd1);
1526 gen_op_iwmmxt_movq_wRn_M0(wrd);
1527 gen_op_iwmmxt_set_mup();
1529 case 0x10e: case 0x50e: case 0x90e: case 0xd0e: /* WUNPCKIL */
1530 wrd = (insn >> 12) & 0xf;
1531 rd0 = (insn >> 16) & 0xf;
1532 rd1 = (insn >> 0) & 0xf;
1533 gen_op_iwmmxt_movq_M0_wRn(rd0);
1534 switch ((insn >> 22) & 3) {
1536 gen_op_iwmmxt_unpacklb_M0_wRn(rd1);
1539 gen_op_iwmmxt_unpacklw_M0_wRn(rd1);
1542 gen_op_iwmmxt_unpackll_M0_wRn(rd1);
1547 gen_op_iwmmxt_movq_wRn_M0(wrd);
1548 gen_op_iwmmxt_set_mup();
1549 gen_op_iwmmxt_set_cup();
1551 case 0x10c: case 0x50c: case 0x90c: case 0xd0c: /* WUNPCKIH */
1552 wrd = (insn >> 12) & 0xf;
1553 rd0 = (insn >> 16) & 0xf;
1554 rd1 = (insn >> 0) & 0xf;
1555 gen_op_iwmmxt_movq_M0_wRn(rd0);
1556 switch ((insn >> 22) & 3) {
1558 gen_op_iwmmxt_unpackhb_M0_wRn(rd1);
1561 gen_op_iwmmxt_unpackhw_M0_wRn(rd1);
1564 gen_op_iwmmxt_unpackhl_M0_wRn(rd1);
1569 gen_op_iwmmxt_movq_wRn_M0(wrd);
1570 gen_op_iwmmxt_set_mup();
1571 gen_op_iwmmxt_set_cup();
1573 case 0x012: case 0x112: case 0x412: case 0x512: /* WSAD */
1574 wrd = (insn >> 12) & 0xf;
1575 rd0 = (insn >> 16) & 0xf;
1576 rd1 = (insn >> 0) & 0xf;
1577 gen_op_iwmmxt_movq_M0_wRn(rd0);
1578 if (insn & (1 << 22))
1579 gen_op_iwmmxt_sadw_M0_wRn(rd1);
1581 gen_op_iwmmxt_sadb_M0_wRn(rd1);
1582 if (!(insn & (1 << 20)))
1583 gen_op_iwmmxt_addl_M0_wRn(wrd);
1584 gen_op_iwmmxt_movq_wRn_M0(wrd);
1585 gen_op_iwmmxt_set_mup();
1587 case 0x010: case 0x110: case 0x210: case 0x310: /* WMUL */
1588 wrd = (insn >> 12) & 0xf;
1589 rd0 = (insn >> 16) & 0xf;
1590 rd1 = (insn >> 0) & 0xf;
1591 gen_op_iwmmxt_movq_M0_wRn(rd0);
1592 if (insn & (1 << 21)) {
1593 if (insn & (1 << 20))
1594 gen_op_iwmmxt_mulshw_M0_wRn(rd1);
1596 gen_op_iwmmxt_mulslw_M0_wRn(rd1);
1598 if (insn & (1 << 20))
1599 gen_op_iwmmxt_muluhw_M0_wRn(rd1);
1601 gen_op_iwmmxt_mululw_M0_wRn(rd1);
1603 gen_op_iwmmxt_movq_wRn_M0(wrd);
1604 gen_op_iwmmxt_set_mup();
1606 case 0x410: case 0x510: case 0x610: case 0x710: /* WMAC */
1607 wrd = (insn >> 12) & 0xf;
1608 rd0 = (insn >> 16) & 0xf;
1609 rd1 = (insn >> 0) & 0xf;
1610 gen_op_iwmmxt_movq_M0_wRn(rd0);
1611 if (insn & (1 << 21))
1612 gen_op_iwmmxt_macsw_M0_wRn(rd1);
1614 gen_op_iwmmxt_macuw_M0_wRn(rd1);
1615 if (!(insn & (1 << 20))) {
1616 iwmmxt_load_reg(cpu_V1, wrd);
1617 tcg_gen_add_i64(cpu_M0, cpu_M0, cpu_V1);
1619 gen_op_iwmmxt_movq_wRn_M0(wrd);
1620 gen_op_iwmmxt_set_mup();
1622 case 0x006: case 0x406: case 0x806: case 0xc06: /* WCMPEQ */
1623 wrd = (insn >> 12) & 0xf;
1624 rd0 = (insn >> 16) & 0xf;
1625 rd1 = (insn >> 0) & 0xf;
1626 gen_op_iwmmxt_movq_M0_wRn(rd0);
1627 switch ((insn >> 22) & 3) {
1629 gen_op_iwmmxt_cmpeqb_M0_wRn(rd1);
1632 gen_op_iwmmxt_cmpeqw_M0_wRn(rd1);
1635 gen_op_iwmmxt_cmpeql_M0_wRn(rd1);
1640 gen_op_iwmmxt_movq_wRn_M0(wrd);
1641 gen_op_iwmmxt_set_mup();
1642 gen_op_iwmmxt_set_cup();
1644 case 0x800: case 0x900: case 0xc00: case 0xd00: /* WAVG2 */
1645 wrd = (insn >> 12) & 0xf;
1646 rd0 = (insn >> 16) & 0xf;
1647 rd1 = (insn >> 0) & 0xf;
1648 gen_op_iwmmxt_movq_M0_wRn(rd0);
1649 if (insn & (1 << 22)) {
1650 if (insn & (1 << 20))
1651 gen_op_iwmmxt_avgw1_M0_wRn(rd1);
1653 gen_op_iwmmxt_avgw0_M0_wRn(rd1);
1655 if (insn & (1 << 20))
1656 gen_op_iwmmxt_avgb1_M0_wRn(rd1);
1658 gen_op_iwmmxt_avgb0_M0_wRn(rd1);
1660 gen_op_iwmmxt_movq_wRn_M0(wrd);
1661 gen_op_iwmmxt_set_mup();
1662 gen_op_iwmmxt_set_cup();
1664 case 0x802: case 0x902: case 0xa02: case 0xb02: /* WALIGNR */
1665 wrd = (insn >> 12) & 0xf;
1666 rd0 = (insn >> 16) & 0xf;
1667 rd1 = (insn >> 0) & 0xf;
1668 gen_op_iwmmxt_movq_M0_wRn(rd0);
1669 tmp = iwmmxt_load_creg(ARM_IWMMXT_wCGR0 + ((insn >> 20) & 3));
1670 tcg_gen_andi_i32(tmp, tmp, 7);
1671 iwmmxt_load_reg(cpu_V1, rd1);
1672 gen_helper_iwmmxt_align(cpu_M0, cpu_M0, cpu_V1, tmp);
1674 gen_op_iwmmxt_movq_wRn_M0(wrd);
1675 gen_op_iwmmxt_set_mup();
1677 case 0x601: case 0x605: case 0x609: case 0x60d: /* TINSR */
1678 if (((insn >> 6) & 3) == 3)
1680 rd = (insn >> 12) & 0xf;
1681 wrd = (insn >> 16) & 0xf;
1682 tmp = load_reg(s, rd);
1683 gen_op_iwmmxt_movq_M0_wRn(wrd);
1684 switch ((insn >> 6) & 3) {
1686 tmp2 = tcg_const_i32(0xff);
1687 tmp3 = tcg_const_i32((insn & 7) << 3);
1690 tmp2 = tcg_const_i32(0xffff);
1691 tmp3 = tcg_const_i32((insn & 3) << 4);
1694 tmp2 = tcg_const_i32(0xffffffff);
1695 tmp3 = tcg_const_i32((insn & 1) << 5);
1701 gen_helper_iwmmxt_insr(cpu_M0, cpu_M0, tmp, tmp2, tmp3);
1702 tcg_temp_free(tmp3);
1703 tcg_temp_free(tmp2);
1705 gen_op_iwmmxt_movq_wRn_M0(wrd);
1706 gen_op_iwmmxt_set_mup();
1708 case 0x107: case 0x507: case 0x907: case 0xd07: /* TEXTRM */
1709 rd = (insn >> 12) & 0xf;
1710 wrd = (insn >> 16) & 0xf;
1711 if (rd == 15 || ((insn >> 22) & 3) == 3)
1713 gen_op_iwmmxt_movq_M0_wRn(wrd);
1715 switch ((insn >> 22) & 3) {
1717 tcg_gen_shri_i64(cpu_M0, cpu_M0, (insn & 7) << 3);
1718 tcg_gen_trunc_i64_i32(tmp, cpu_M0);
1720 tcg_gen_ext8s_i32(tmp, tmp);
1722 tcg_gen_andi_i32(tmp, tmp, 0xff);
1726 tcg_gen_shri_i64(cpu_M0, cpu_M0, (insn & 3) << 4);
1727 tcg_gen_trunc_i64_i32(tmp, cpu_M0);
1729 tcg_gen_ext16s_i32(tmp, tmp);
1731 tcg_gen_andi_i32(tmp, tmp, 0xffff);
1735 tcg_gen_shri_i64(cpu_M0, cpu_M0, (insn & 1) << 5);
1736 tcg_gen_trunc_i64_i32(tmp, cpu_M0);
1739 store_reg(s, rd, tmp);
1741 case 0x117: case 0x517: case 0x917: case 0xd17: /* TEXTRC */
1742 if ((insn & 0x000ff008) != 0x0003f000 || ((insn >> 22) & 3) == 3)
1744 tmp = iwmmxt_load_creg(ARM_IWMMXT_wCASF);
1745 switch ((insn >> 22) & 3) {
1747 tcg_gen_shri_i32(tmp, tmp, ((insn & 7) << 2) + 0);
1750 tcg_gen_shri_i32(tmp, tmp, ((insn & 3) << 3) + 4);
1753 tcg_gen_shri_i32(tmp, tmp, ((insn & 1) << 4) + 12);
1756 tcg_gen_shli_i32(tmp, tmp, 28);
1760 case 0x401: case 0x405: case 0x409: case 0x40d: /* TBCST */
1761 if (((insn >> 6) & 3) == 3)
1763 rd = (insn >> 12) & 0xf;
1764 wrd = (insn >> 16) & 0xf;
1765 tmp = load_reg(s, rd);
1766 switch ((insn >> 6) & 3) {
1768 gen_helper_iwmmxt_bcstb(cpu_M0, tmp);
1771 gen_helper_iwmmxt_bcstw(cpu_M0, tmp);
1774 gen_helper_iwmmxt_bcstl(cpu_M0, tmp);
1778 gen_op_iwmmxt_movq_wRn_M0(wrd);
1779 gen_op_iwmmxt_set_mup();
1781 case 0x113: case 0x513: case 0x913: case 0xd13: /* TANDC */
1782 if ((insn & 0x000ff00f) != 0x0003f000 || ((insn >> 22) & 3) == 3)
1784 tmp = iwmmxt_load_creg(ARM_IWMMXT_wCASF);
1786 tcg_gen_mov_i32(tmp2, tmp);
1787 switch ((insn >> 22) & 3) {
1789 for (i = 0; i < 7; i ++) {
1790 tcg_gen_shli_i32(tmp2, tmp2, 4);
1791 tcg_gen_and_i32(tmp, tmp, tmp2);
1795 for (i = 0; i < 3; i ++) {
1796 tcg_gen_shli_i32(tmp2, tmp2, 8);
1797 tcg_gen_and_i32(tmp, tmp, tmp2);
1801 tcg_gen_shli_i32(tmp2, tmp2, 16);
1802 tcg_gen_and_i32(tmp, tmp, tmp2);
1809 case 0x01c: case 0x41c: case 0x81c: case 0xc1c: /* WACC */
1810 wrd = (insn >> 12) & 0xf;
1811 rd0 = (insn >> 16) & 0xf;
1812 gen_op_iwmmxt_movq_M0_wRn(rd0);
1813 switch ((insn >> 22) & 3) {
1815 gen_helper_iwmmxt_addcb(cpu_M0, cpu_M0);
1818 gen_helper_iwmmxt_addcw(cpu_M0, cpu_M0);
1821 gen_helper_iwmmxt_addcl(cpu_M0, cpu_M0);
1826 gen_op_iwmmxt_movq_wRn_M0(wrd);
1827 gen_op_iwmmxt_set_mup();
1829 case 0x115: case 0x515: case 0x915: case 0xd15: /* TORC */
1830 if ((insn & 0x000ff00f) != 0x0003f000 || ((insn >> 22) & 3) == 3)
1832 tmp = iwmmxt_load_creg(ARM_IWMMXT_wCASF);
1834 tcg_gen_mov_i32(tmp2, tmp);
1835 switch ((insn >> 22) & 3) {
1837 for (i = 0; i < 7; i ++) {
1838 tcg_gen_shli_i32(tmp2, tmp2, 4);
1839 tcg_gen_or_i32(tmp, tmp, tmp2);
1843 for (i = 0; i < 3; i ++) {
1844 tcg_gen_shli_i32(tmp2, tmp2, 8);
1845 tcg_gen_or_i32(tmp, tmp, tmp2);
1849 tcg_gen_shli_i32(tmp2, tmp2, 16);
1850 tcg_gen_or_i32(tmp, tmp, tmp2);
1857 case 0x103: case 0x503: case 0x903: case 0xd03: /* TMOVMSK */
1858 rd = (insn >> 12) & 0xf;
1859 rd0 = (insn >> 16) & 0xf;
1860 if ((insn & 0xf) != 0 || ((insn >> 22) & 3) == 3)
1862 gen_op_iwmmxt_movq_M0_wRn(rd0);
1864 switch ((insn >> 22) & 3) {
1866 gen_helper_iwmmxt_msbb(tmp, cpu_M0);
1869 gen_helper_iwmmxt_msbw(tmp, cpu_M0);
1872 gen_helper_iwmmxt_msbl(tmp, cpu_M0);
1875 store_reg(s, rd, tmp);
1877 case 0x106: case 0x306: case 0x506: case 0x706: /* WCMPGT */
1878 case 0x906: case 0xb06: case 0xd06: case 0xf06:
1879 wrd = (insn >> 12) & 0xf;
1880 rd0 = (insn >> 16) & 0xf;
1881 rd1 = (insn >> 0) & 0xf;
1882 gen_op_iwmmxt_movq_M0_wRn(rd0);
1883 switch ((insn >> 22) & 3) {
1885 if (insn & (1 << 21))
1886 gen_op_iwmmxt_cmpgtsb_M0_wRn(rd1);
1888 gen_op_iwmmxt_cmpgtub_M0_wRn(rd1);
1891 if (insn & (1 << 21))
1892 gen_op_iwmmxt_cmpgtsw_M0_wRn(rd1);
1894 gen_op_iwmmxt_cmpgtuw_M0_wRn(rd1);
1897 if (insn & (1 << 21))
1898 gen_op_iwmmxt_cmpgtsl_M0_wRn(rd1);
1900 gen_op_iwmmxt_cmpgtul_M0_wRn(rd1);
1905 gen_op_iwmmxt_movq_wRn_M0(wrd);
1906 gen_op_iwmmxt_set_mup();
1907 gen_op_iwmmxt_set_cup();
1909 case 0x00e: case 0x20e: case 0x40e: case 0x60e: /* WUNPCKEL */
1910 case 0x80e: case 0xa0e: case 0xc0e: case 0xe0e:
1911 wrd = (insn >> 12) & 0xf;
1912 rd0 = (insn >> 16) & 0xf;
1913 gen_op_iwmmxt_movq_M0_wRn(rd0);
1914 switch ((insn >> 22) & 3) {
1916 if (insn & (1 << 21))
1917 gen_op_iwmmxt_unpacklsb_M0();
1919 gen_op_iwmmxt_unpacklub_M0();
1922 if (insn & (1 << 21))
1923 gen_op_iwmmxt_unpacklsw_M0();
1925 gen_op_iwmmxt_unpackluw_M0();
1928 if (insn & (1 << 21))
1929 gen_op_iwmmxt_unpacklsl_M0();
1931 gen_op_iwmmxt_unpacklul_M0();
1936 gen_op_iwmmxt_movq_wRn_M0(wrd);
1937 gen_op_iwmmxt_set_mup();
1938 gen_op_iwmmxt_set_cup();
1940 case 0x00c: case 0x20c: case 0x40c: case 0x60c: /* WUNPCKEH */
1941 case 0x80c: case 0xa0c: case 0xc0c: case 0xe0c:
1942 wrd = (insn >> 12) & 0xf;
1943 rd0 = (insn >> 16) & 0xf;
1944 gen_op_iwmmxt_movq_M0_wRn(rd0);
1945 switch ((insn >> 22) & 3) {
1947 if (insn & (1 << 21))
1948 gen_op_iwmmxt_unpackhsb_M0();
1950 gen_op_iwmmxt_unpackhub_M0();
1953 if (insn & (1 << 21))
1954 gen_op_iwmmxt_unpackhsw_M0();
1956 gen_op_iwmmxt_unpackhuw_M0();
1959 if (insn & (1 << 21))
1960 gen_op_iwmmxt_unpackhsl_M0();
1962 gen_op_iwmmxt_unpackhul_M0();
1967 gen_op_iwmmxt_movq_wRn_M0(wrd);
1968 gen_op_iwmmxt_set_mup();
1969 gen_op_iwmmxt_set_cup();
1971 case 0x204: case 0x604: case 0xa04: case 0xe04: /* WSRL */
1972 case 0x214: case 0x614: case 0xa14: case 0xe14:
1973 if (((insn >> 22) & 3) == 0)
1975 wrd = (insn >> 12) & 0xf;
1976 rd0 = (insn >> 16) & 0xf;
1977 gen_op_iwmmxt_movq_M0_wRn(rd0);
1979 if (gen_iwmmxt_shift(insn, 0xff, tmp)) {
1983 switch ((insn >> 22) & 3) {
1985 gen_helper_iwmmxt_srlw(cpu_M0, cpu_env, cpu_M0, tmp);
1988 gen_helper_iwmmxt_srll(cpu_M0, cpu_env, cpu_M0, tmp);
1991 gen_helper_iwmmxt_srlq(cpu_M0, cpu_env, cpu_M0, tmp);
1995 gen_op_iwmmxt_movq_wRn_M0(wrd);
1996 gen_op_iwmmxt_set_mup();
1997 gen_op_iwmmxt_set_cup();
1999 case 0x004: case 0x404: case 0x804: case 0xc04: /* WSRA */
2000 case 0x014: case 0x414: case 0x814: case 0xc14:
2001 if (((insn >> 22) & 3) == 0)
2003 wrd = (insn >> 12) & 0xf;
2004 rd0 = (insn >> 16) & 0xf;
2005 gen_op_iwmmxt_movq_M0_wRn(rd0);
2007 if (gen_iwmmxt_shift(insn, 0xff, tmp)) {
2011 switch ((insn >> 22) & 3) {
2013 gen_helper_iwmmxt_sraw(cpu_M0, cpu_env, cpu_M0, tmp);
2016 gen_helper_iwmmxt_sral(cpu_M0, cpu_env, cpu_M0, tmp);
2019 gen_helper_iwmmxt_sraq(cpu_M0, cpu_env, cpu_M0, tmp);
2023 gen_op_iwmmxt_movq_wRn_M0(wrd);
2024 gen_op_iwmmxt_set_mup();
2025 gen_op_iwmmxt_set_cup();
2027 case 0x104: case 0x504: case 0x904: case 0xd04: /* WSLL */
2028 case 0x114: case 0x514: case 0x914: case 0xd14:
2029 if (((insn >> 22) & 3) == 0)
2031 wrd = (insn >> 12) & 0xf;
2032 rd0 = (insn >> 16) & 0xf;
2033 gen_op_iwmmxt_movq_M0_wRn(rd0);
2035 if (gen_iwmmxt_shift(insn, 0xff, tmp)) {
2039 switch ((insn >> 22) & 3) {
2041 gen_helper_iwmmxt_sllw(cpu_M0, cpu_env, cpu_M0, tmp);
2044 gen_helper_iwmmxt_slll(cpu_M0, cpu_env, cpu_M0, tmp);
2047 gen_helper_iwmmxt_sllq(cpu_M0, cpu_env, cpu_M0, tmp);
2051 gen_op_iwmmxt_movq_wRn_M0(wrd);
2052 gen_op_iwmmxt_set_mup();
2053 gen_op_iwmmxt_set_cup();
2055 case 0x304: case 0x704: case 0xb04: case 0xf04: /* WROR */
2056 case 0x314: case 0x714: case 0xb14: case 0xf14:
2057 if (((insn >> 22) & 3) == 0)
2059 wrd = (insn >> 12) & 0xf;
2060 rd0 = (insn >> 16) & 0xf;
2061 gen_op_iwmmxt_movq_M0_wRn(rd0);
2063 switch ((insn >> 22) & 3) {
2065 if (gen_iwmmxt_shift(insn, 0xf, tmp)) {
2069 gen_helper_iwmmxt_rorw(cpu_M0, cpu_env, cpu_M0, tmp);
2072 if (gen_iwmmxt_shift(insn, 0x1f, tmp)) {
2076 gen_helper_iwmmxt_rorl(cpu_M0, cpu_env, cpu_M0, tmp);
2079 if (gen_iwmmxt_shift(insn, 0x3f, tmp)) {
2083 gen_helper_iwmmxt_rorq(cpu_M0, cpu_env, cpu_M0, tmp);
2087 gen_op_iwmmxt_movq_wRn_M0(wrd);
2088 gen_op_iwmmxt_set_mup();
2089 gen_op_iwmmxt_set_cup();
2091 case 0x116: case 0x316: case 0x516: case 0x716: /* WMIN */
2092 case 0x916: case 0xb16: case 0xd16: case 0xf16:
2093 wrd = (insn >> 12) & 0xf;
2094 rd0 = (insn >> 16) & 0xf;
2095 rd1 = (insn >> 0) & 0xf;
2096 gen_op_iwmmxt_movq_M0_wRn(rd0);
2097 switch ((insn >> 22) & 3) {
2099 if (insn & (1 << 21))
2100 gen_op_iwmmxt_minsb_M0_wRn(rd1);
2102 gen_op_iwmmxt_minub_M0_wRn(rd1);
2105 if (insn & (1 << 21))
2106 gen_op_iwmmxt_minsw_M0_wRn(rd1);
2108 gen_op_iwmmxt_minuw_M0_wRn(rd1);
2111 if (insn & (1 << 21))
2112 gen_op_iwmmxt_minsl_M0_wRn(rd1);
2114 gen_op_iwmmxt_minul_M0_wRn(rd1);
2119 gen_op_iwmmxt_movq_wRn_M0(wrd);
2120 gen_op_iwmmxt_set_mup();
2122 case 0x016: case 0x216: case 0x416: case 0x616: /* WMAX */
2123 case 0x816: case 0xa16: case 0xc16: case 0xe16:
2124 wrd = (insn >> 12) & 0xf;
2125 rd0 = (insn >> 16) & 0xf;
2126 rd1 = (insn >> 0) & 0xf;
2127 gen_op_iwmmxt_movq_M0_wRn(rd0);
2128 switch ((insn >> 22) & 3) {
2130 if (insn & (1 << 21))
2131 gen_op_iwmmxt_maxsb_M0_wRn(rd1);
2133 gen_op_iwmmxt_maxub_M0_wRn(rd1);
2136 if (insn & (1 << 21))
2137 gen_op_iwmmxt_maxsw_M0_wRn(rd1);
2139 gen_op_iwmmxt_maxuw_M0_wRn(rd1);
2142 if (insn & (1 << 21))
2143 gen_op_iwmmxt_maxsl_M0_wRn(rd1);
2145 gen_op_iwmmxt_maxul_M0_wRn(rd1);
2150 gen_op_iwmmxt_movq_wRn_M0(wrd);
2151 gen_op_iwmmxt_set_mup();
2153 case 0x002: case 0x102: case 0x202: case 0x302: /* WALIGNI */
2154 case 0x402: case 0x502: case 0x602: case 0x702:
2155 wrd = (insn >> 12) & 0xf;
2156 rd0 = (insn >> 16) & 0xf;
2157 rd1 = (insn >> 0) & 0xf;
2158 gen_op_iwmmxt_movq_M0_wRn(rd0);
2159 tmp = tcg_const_i32((insn >> 20) & 3);
2160 iwmmxt_load_reg(cpu_V1, rd1);
2161 gen_helper_iwmmxt_align(cpu_M0, cpu_M0, cpu_V1, tmp);
2163 gen_op_iwmmxt_movq_wRn_M0(wrd);
2164 gen_op_iwmmxt_set_mup();
2166 case 0x01a: case 0x11a: case 0x21a: case 0x31a: /* WSUB */
2167 case 0x41a: case 0x51a: case 0x61a: case 0x71a:
2168 case 0x81a: case 0x91a: case 0xa1a: case 0xb1a:
2169 case 0xc1a: case 0xd1a: case 0xe1a: case 0xf1a:
2170 wrd = (insn >> 12) & 0xf;
2171 rd0 = (insn >> 16) & 0xf;
2172 rd1 = (insn >> 0) & 0xf;
2173 gen_op_iwmmxt_movq_M0_wRn(rd0);
2174 switch ((insn >> 20) & 0xf) {
2176 gen_op_iwmmxt_subnb_M0_wRn(rd1);
2179 gen_op_iwmmxt_subub_M0_wRn(rd1);
2182 gen_op_iwmmxt_subsb_M0_wRn(rd1);
2185 gen_op_iwmmxt_subnw_M0_wRn(rd1);
2188 gen_op_iwmmxt_subuw_M0_wRn(rd1);
2191 gen_op_iwmmxt_subsw_M0_wRn(rd1);
2194 gen_op_iwmmxt_subnl_M0_wRn(rd1);
2197 gen_op_iwmmxt_subul_M0_wRn(rd1);
2200 gen_op_iwmmxt_subsl_M0_wRn(rd1);
2205 gen_op_iwmmxt_movq_wRn_M0(wrd);
2206 gen_op_iwmmxt_set_mup();
2207 gen_op_iwmmxt_set_cup();
2209 case 0x01e: case 0x11e: case 0x21e: case 0x31e: /* WSHUFH */
2210 case 0x41e: case 0x51e: case 0x61e: case 0x71e:
2211 case 0x81e: case 0x91e: case 0xa1e: case 0xb1e:
2212 case 0xc1e: case 0xd1e: case 0xe1e: case 0xf1e:
2213 wrd = (insn >> 12) & 0xf;
2214 rd0 = (insn >> 16) & 0xf;
2215 gen_op_iwmmxt_movq_M0_wRn(rd0);
2216 tmp = tcg_const_i32(((insn >> 16) & 0xf0) | (insn & 0x0f));
2217 gen_helper_iwmmxt_shufh(cpu_M0, cpu_env, cpu_M0, tmp);
2219 gen_op_iwmmxt_movq_wRn_M0(wrd);
2220 gen_op_iwmmxt_set_mup();
2221 gen_op_iwmmxt_set_cup();
2223 case 0x018: case 0x118: case 0x218: case 0x318: /* WADD */
2224 case 0x418: case 0x518: case 0x618: case 0x718:
2225 case 0x818: case 0x918: case 0xa18: case 0xb18:
2226 case 0xc18: case 0xd18: case 0xe18: case 0xf18:
2227 wrd = (insn >> 12) & 0xf;
2228 rd0 = (insn >> 16) & 0xf;
2229 rd1 = (insn >> 0) & 0xf;
2230 gen_op_iwmmxt_movq_M0_wRn(rd0);
2231 switch ((insn >> 20) & 0xf) {
2233 gen_op_iwmmxt_addnb_M0_wRn(rd1);
2236 gen_op_iwmmxt_addub_M0_wRn(rd1);
2239 gen_op_iwmmxt_addsb_M0_wRn(rd1);
2242 gen_op_iwmmxt_addnw_M0_wRn(rd1);
2245 gen_op_iwmmxt_adduw_M0_wRn(rd1);
2248 gen_op_iwmmxt_addsw_M0_wRn(rd1);
2251 gen_op_iwmmxt_addnl_M0_wRn(rd1);
2254 gen_op_iwmmxt_addul_M0_wRn(rd1);
2257 gen_op_iwmmxt_addsl_M0_wRn(rd1);
2262 gen_op_iwmmxt_movq_wRn_M0(wrd);
2263 gen_op_iwmmxt_set_mup();
2264 gen_op_iwmmxt_set_cup();
2266 case 0x008: case 0x108: case 0x208: case 0x308: /* WPACK */
2267 case 0x408: case 0x508: case 0x608: case 0x708:
2268 case 0x808: case 0x908: case 0xa08: case 0xb08:
2269 case 0xc08: case 0xd08: case 0xe08: case 0xf08:
2270 if (!(insn & (1 << 20)) || ((insn >> 22) & 3) == 0)
2272 wrd = (insn >> 12) & 0xf;
2273 rd0 = (insn >> 16) & 0xf;
2274 rd1 = (insn >> 0) & 0xf;
2275 gen_op_iwmmxt_movq_M0_wRn(rd0);
2276 switch ((insn >> 22) & 3) {
2278 if (insn & (1 << 21))
2279 gen_op_iwmmxt_packsw_M0_wRn(rd1);
2281 gen_op_iwmmxt_packuw_M0_wRn(rd1);
2284 if (insn & (1 << 21))
2285 gen_op_iwmmxt_packsl_M0_wRn(rd1);
2287 gen_op_iwmmxt_packul_M0_wRn(rd1);
2290 if (insn & (1 << 21))
2291 gen_op_iwmmxt_packsq_M0_wRn(rd1);
2293 gen_op_iwmmxt_packuq_M0_wRn(rd1);
2296 gen_op_iwmmxt_movq_wRn_M0(wrd);
2297 gen_op_iwmmxt_set_mup();
2298 gen_op_iwmmxt_set_cup();
2300 case 0x201: case 0x203: case 0x205: case 0x207:
2301 case 0x209: case 0x20b: case 0x20d: case 0x20f:
2302 case 0x211: case 0x213: case 0x215: case 0x217:
2303 case 0x219: case 0x21b: case 0x21d: case 0x21f:
2304 wrd = (insn >> 5) & 0xf;
2305 rd0 = (insn >> 12) & 0xf;
2306 rd1 = (insn >> 0) & 0xf;
2307 if (rd0 == 0xf || rd1 == 0xf)
2309 gen_op_iwmmxt_movq_M0_wRn(wrd);
2310 tmp = load_reg(s, rd0);
2311 tmp2 = load_reg(s, rd1);
2312 switch ((insn >> 16) & 0xf) {
2313 case 0x0: /* TMIA */
2314 gen_helper_iwmmxt_muladdsl(cpu_M0, cpu_M0, tmp, tmp2);
2316 case 0x8: /* TMIAPH */
2317 gen_helper_iwmmxt_muladdsw(cpu_M0, cpu_M0, tmp, tmp2);
2319 case 0xc: case 0xd: case 0xe: case 0xf: /* TMIAxy */
2320 if (insn & (1 << 16))
2321 tcg_gen_shri_i32(tmp, tmp, 16);
2322 if (insn & (1 << 17))
2323 tcg_gen_shri_i32(tmp2, tmp2, 16);
2324 gen_helper_iwmmxt_muladdswl(cpu_M0, cpu_M0, tmp, tmp2);
2333 gen_op_iwmmxt_movq_wRn_M0(wrd);
2334 gen_op_iwmmxt_set_mup();
2343 /* Disassemble an XScale DSP instruction. Returns nonzero if an error occured
2344 (ie. an undefined instruction). */
2345 static int disas_dsp_insn(CPUState *env, DisasContext *s, uint32_t insn)
2347 int acc, rd0, rd1, rdhi, rdlo;
2350 if ((insn & 0x0ff00f10) == 0x0e200010) {
2351 /* Multiply with Internal Accumulate Format */
2352 rd0 = (insn >> 12) & 0xf;
2354 acc = (insn >> 5) & 7;
2359 tmp = load_reg(s, rd0);
2360 tmp2 = load_reg(s, rd1);
2361 switch ((insn >> 16) & 0xf) {
2363 gen_helper_iwmmxt_muladdsl(cpu_M0, cpu_M0, tmp, tmp2);
2365 case 0x8: /* MIAPH */
2366 gen_helper_iwmmxt_muladdsw(cpu_M0, cpu_M0, tmp, tmp2);
2368 case 0xc: /* MIABB */
2369 case 0xd: /* MIABT */
2370 case 0xe: /* MIATB */
2371 case 0xf: /* MIATT */
2372 if (insn & (1 << 16))
2373 tcg_gen_shri_i32(tmp, tmp, 16);
2374 if (insn & (1 << 17))
2375 tcg_gen_shri_i32(tmp2, tmp2, 16);
2376 gen_helper_iwmmxt_muladdswl(cpu_M0, cpu_M0, tmp, tmp2);
2384 gen_op_iwmmxt_movq_wRn_M0(acc);
2388 if ((insn & 0x0fe00ff8) == 0x0c400000) {
2389 /* Internal Accumulator Access Format */
2390 rdhi = (insn >> 16) & 0xf;
2391 rdlo = (insn >> 12) & 0xf;
2397 if (insn & ARM_CP_RW_BIT) { /* MRA */
2398 iwmmxt_load_reg(cpu_V0, acc);
2399 tcg_gen_trunc_i64_i32(cpu_R[rdlo], cpu_V0);
2400 tcg_gen_shri_i64(cpu_V0, cpu_V0, 32);
2401 tcg_gen_trunc_i64_i32(cpu_R[rdhi], cpu_V0);
2402 tcg_gen_andi_i32(cpu_R[rdhi], cpu_R[rdhi], (1 << (40 - 32)) - 1);
2404 tcg_gen_concat_i32_i64(cpu_V0, cpu_R[rdlo], cpu_R[rdhi]);
2405 iwmmxt_store_reg(cpu_V0, acc);
2413 /* Disassemble system coprocessor instruction. Return nonzero if
2414 instruction is not defined. */
2415 static int disas_cp_insn(CPUState *env, DisasContext *s, uint32_t insn)
2418 uint32_t rd = (insn >> 12) & 0xf;
2419 uint32_t cp = (insn >> 8) & 0xf;
2424 if (insn & ARM_CP_RW_BIT) {
2425 if (!env->cp[cp].cp_read)
2427 gen_set_pc_im(s->pc);
2429 tmp2 = tcg_const_i32(insn);
2430 gen_helper_get_cp(tmp, cpu_env, tmp2);
2431 tcg_temp_free(tmp2);
2432 store_reg(s, rd, tmp);
2434 if (!env->cp[cp].cp_write)
2436 gen_set_pc_im(s->pc);
2437 tmp = load_reg(s, rd);
2438 tmp2 = tcg_const_i32(insn);
2439 gen_helper_set_cp(cpu_env, tmp2, tmp);
2440 tcg_temp_free(tmp2);
2446 static int cp15_user_ok(uint32_t insn)
2448 int cpn = (insn >> 16) & 0xf;
2449 int cpm = insn & 0xf;
2450 int op = ((insn >> 5) & 7) | ((insn >> 18) & 0x38);
2452 if (cpn == 13 && cpm == 0) {
2454 if (op == 2 || (op == 3 && (insn & ARM_CP_RW_BIT)))
2458 /* ISB, DSB, DMB. */
2459 if ((cpm == 5 && op == 4)
2460 || (cpm == 10 && (op == 4 || op == 5)))
2466 static int cp15_tls_load_store(CPUState *env, DisasContext *s, uint32_t insn, uint32_t rd)
2469 int cpn = (insn >> 16) & 0xf;
2470 int cpm = insn & 0xf;
2471 int op = ((insn >> 5) & 7) | ((insn >> 18) & 0x38);
2473 if (!arm_feature(env, ARM_FEATURE_V6K))
2476 if (!(cpn == 13 && cpm == 0))
2479 if (insn & ARM_CP_RW_BIT) {
2482 tmp = load_cpu_field(cp15.c13_tls1);
2485 tmp = load_cpu_field(cp15.c13_tls2);
2488 tmp = load_cpu_field(cp15.c13_tls3);
2493 store_reg(s, rd, tmp);
2496 tmp = load_reg(s, rd);
2499 store_cpu_field(tmp, cp15.c13_tls1);
2502 store_cpu_field(tmp, cp15.c13_tls2);
2505 store_cpu_field(tmp, cp15.c13_tls3);
2515 /* Disassemble system coprocessor (cp15) instruction. Return nonzero if
2516 instruction is not defined. */
2517 static int disas_cp15_insn(CPUState *env, DisasContext *s, uint32_t insn)
2522 /* M profile cores use memory mapped registers instead of cp15. */
2523 if (arm_feature(env, ARM_FEATURE_M))
2526 if ((insn & (1 << 25)) == 0) {
2527 if (insn & (1 << 20)) {
2531 /* mcrr. Used for block cache operations, so implement as no-op. */
2534 if ((insn & (1 << 4)) == 0) {
2538 if (IS_USER(s) && !cp15_user_ok(insn)) {
2542 /* Pre-v7 versions of the architecture implemented WFI via coprocessor
2543 * instructions rather than a separate instruction.
2545 if ((insn & 0x0fff0fff) == 0x0e070f90) {
2546 /* 0,c7,c0,4: Standard v6 WFI (also used in some pre-v6 cores).
2547 * In v7, this must NOP.
2549 if (!arm_feature(env, ARM_FEATURE_V7)) {
2550 /* Wait for interrupt. */
2551 gen_set_pc_im(s->pc);
2552 s->is_jmp = DISAS_WFI;
2557 if ((insn & 0x0fff0fff) == 0x0e070f58) {
2558 /* 0,c7,c8,2: Not all pre-v6 cores implemented this WFI,
2559 * so this is slightly over-broad.
2561 if (!arm_feature(env, ARM_FEATURE_V6)) {
2562 /* Wait for interrupt. */
2563 gen_set_pc_im(s->pc);
2564 s->is_jmp = DISAS_WFI;
2567 /* Otherwise fall through to handle via helper function.
2568 * In particular, on v7 and some v6 cores this is one of
2569 * the VA-PA registers.
2573 rd = (insn >> 12) & 0xf;
2575 if (cp15_tls_load_store(env, s, insn, rd))
2578 tmp2 = tcg_const_i32(insn);
2579 if (insn & ARM_CP_RW_BIT) {
2581 gen_helper_get_cp15(tmp, cpu_env, tmp2);
2582 /* If the destination register is r15 then sets condition codes. */
2584 store_reg(s, rd, tmp);
2588 tmp = load_reg(s, rd);
2589 gen_helper_set_cp15(cpu_env, tmp2, tmp);
2591 /* Normally we would always end the TB here, but Linux
2592 * arch/arm/mach-pxa/sleep.S expects two instructions following
2593 * an MMU enable to execute from cache. Imitate this behaviour. */
2594 if (!arm_feature(env, ARM_FEATURE_XSCALE) ||
2595 (insn & 0x0fff0fff) != 0x0e010f10)
2598 tcg_temp_free_i32(tmp2);
2602 #define VFP_REG_SHR(x, n) (((n) > 0) ? (x) >> (n) : (x) << -(n))
2603 #define VFP_SREG(insn, bigbit, smallbit) \
2604 ((VFP_REG_SHR(insn, bigbit - 1) & 0x1e) | (((insn) >> (smallbit)) & 1))
2605 #define VFP_DREG(reg, insn, bigbit, smallbit) do { \
2606 if (arm_feature(env, ARM_FEATURE_VFP3)) { \
2607 reg = (((insn) >> (bigbit)) & 0x0f) \
2608 | (((insn) >> ((smallbit) - 4)) & 0x10); \
2610 if (insn & (1 << (smallbit))) \
2612 reg = ((insn) >> (bigbit)) & 0x0f; \
2615 #define VFP_SREG_D(insn) VFP_SREG(insn, 12, 22)
2616 #define VFP_DREG_D(reg, insn) VFP_DREG(reg, insn, 12, 22)
2617 #define VFP_SREG_N(insn) VFP_SREG(insn, 16, 7)
2618 #define VFP_DREG_N(reg, insn) VFP_DREG(reg, insn, 16, 7)
2619 #define VFP_SREG_M(insn) VFP_SREG(insn, 0, 5)
2620 #define VFP_DREG_M(reg, insn) VFP_DREG(reg, insn, 0, 5)
2622 /* Move between integer and VFP cores. */
2623 static TCGv gen_vfp_mrs(void)
2625 TCGv tmp = new_tmp();
2626 tcg_gen_mov_i32(tmp, cpu_F0s);
2630 static void gen_vfp_msr(TCGv tmp)
2632 tcg_gen_mov_i32(cpu_F0s, tmp);
2636 static void gen_neon_dup_u8(TCGv var, int shift)
2638 TCGv tmp = new_tmp();
2640 tcg_gen_shri_i32(var, var, shift);
2641 tcg_gen_ext8u_i32(var, var);
2642 tcg_gen_shli_i32(tmp, var, 8);
2643 tcg_gen_or_i32(var, var, tmp);
2644 tcg_gen_shli_i32(tmp, var, 16);
2645 tcg_gen_or_i32(var, var, tmp);
2649 static void gen_neon_dup_low16(TCGv var)
2651 TCGv tmp = new_tmp();
2652 tcg_gen_ext16u_i32(var, var);
2653 tcg_gen_shli_i32(tmp, var, 16);
2654 tcg_gen_or_i32(var, var, tmp);
2658 static void gen_neon_dup_high16(TCGv var)
2660 TCGv tmp = new_tmp();
2661 tcg_gen_andi_i32(var, var, 0xffff0000);
2662 tcg_gen_shri_i32(tmp, var, 16);
2663 tcg_gen_or_i32(var, var, tmp);
2667 /* Disassemble a VFP instruction. Returns nonzero if an error occured
2668 (ie. an undefined instruction). */
2669 static int disas_vfp_insn(CPUState * env, DisasContext *s, uint32_t insn)
2671 uint32_t rd, rn, rm, op, i, n, offset, delta_d, delta_m, bank_mask;
2677 if (!arm_feature(env, ARM_FEATURE_VFP))
2680 if (!s->vfp_enabled) {
2681 /* VFP disabled. Only allow fmxr/fmrx to/from some control regs. */
2682 if ((insn & 0x0fe00fff) != 0x0ee00a10)
2684 rn = (insn >> 16) & 0xf;
2685 if (rn != ARM_VFP_FPSID && rn != ARM_VFP_FPEXC
2686 && rn != ARM_VFP_MVFR1 && rn != ARM_VFP_MVFR0)
2689 dp = ((insn & 0xf00) == 0xb00);
2690 switch ((insn >> 24) & 0xf) {
2692 if (insn & (1 << 4)) {
2693 /* single register transfer */
2694 rd = (insn >> 12) & 0xf;
2699 VFP_DREG_N(rn, insn);
2702 if (insn & 0x00c00060
2703 && !arm_feature(env, ARM_FEATURE_NEON))
2706 pass = (insn >> 21) & 1;
2707 if (insn & (1 << 22)) {
2709 offset = ((insn >> 5) & 3) * 8;
2710 } else if (insn & (1 << 5)) {
2712 offset = (insn & (1 << 6)) ? 16 : 0;
2717 if (insn & ARM_CP_RW_BIT) {
2719 tmp = neon_load_reg(rn, pass);
2723 tcg_gen_shri_i32(tmp, tmp, offset);
2724 if (insn & (1 << 23))
2730 if (insn & (1 << 23)) {
2732 tcg_gen_shri_i32(tmp, tmp, 16);
2738 tcg_gen_sari_i32(tmp, tmp, 16);
2747 store_reg(s, rd, tmp);
2750 tmp = load_reg(s, rd);
2751 if (insn & (1 << 23)) {
2754 gen_neon_dup_u8(tmp, 0);
2755 } else if (size == 1) {
2756 gen_neon_dup_low16(tmp);
2758 for (n = 0; n <= pass * 2; n++) {
2760 tcg_gen_mov_i32(tmp2, tmp);
2761 neon_store_reg(rn, n, tmp2);
2763 neon_store_reg(rn, n, tmp);
2768 tmp2 = neon_load_reg(rn, pass);
2769 gen_bfi(tmp, tmp2, tmp, offset, 0xff);
2773 tmp2 = neon_load_reg(rn, pass);
2774 gen_bfi(tmp, tmp2, tmp, offset, 0xffff);
2780 neon_store_reg(rn, pass, tmp);
2784 if ((insn & 0x6f) != 0x00)
2786 rn = VFP_SREG_N(insn);
2787 if (insn & ARM_CP_RW_BIT) {
2789 if (insn & (1 << 21)) {
2790 /* system register */
2795 /* VFP2 allows access to FSID from userspace.
2796 VFP3 restricts all id registers to privileged
2799 && arm_feature(env, ARM_FEATURE_VFP3))
2801 tmp = load_cpu_field(vfp.xregs[rn]);
2806 tmp = load_cpu_field(vfp.xregs[rn]);
2808 case ARM_VFP_FPINST:
2809 case ARM_VFP_FPINST2:
2810 /* Not present in VFP3. */
2812 || arm_feature(env, ARM_FEATURE_VFP3))
2814 tmp = load_cpu_field(vfp.xregs[rn]);
2818 tmp = load_cpu_field(vfp.xregs[ARM_VFP_FPSCR]);
2819 tcg_gen_andi_i32(tmp, tmp, 0xf0000000);
2822 gen_helper_vfp_get_fpscr(tmp, cpu_env);
2828 || !arm_feature(env, ARM_FEATURE_VFP3))
2830 tmp = load_cpu_field(vfp.xregs[rn]);
2836 gen_mov_F0_vreg(0, rn);
2837 tmp = gen_vfp_mrs();
2840 /* Set the 4 flag bits in the CPSR. */
2844 store_reg(s, rd, tmp);
2848 tmp = load_reg(s, rd);
2849 if (insn & (1 << 21)) {
2851 /* system register */
2856 /* Writes are ignored. */
2859 gen_helper_vfp_set_fpscr(cpu_env, tmp);
2866 /* TODO: VFP subarchitecture support.
2867 * For now, keep the EN bit only */
2868 tcg_gen_andi_i32(tmp, tmp, 1 << 30);
2869 store_cpu_field(tmp, vfp.xregs[rn]);
2872 case ARM_VFP_FPINST:
2873 case ARM_VFP_FPINST2:
2874 store_cpu_field(tmp, vfp.xregs[rn]);
2881 gen_mov_vreg_F0(0, rn);
2886 /* data processing */
2887 /* The opcode is in bits 23, 21, 20 and 6. */
2888 op = ((insn >> 20) & 8) | ((insn >> 19) & 6) | ((insn >> 6) & 1);
2892 rn = ((insn >> 15) & 0x1e) | ((insn >> 7) & 1);
2894 /* rn is register number */
2895 VFP_DREG_N(rn, insn);
2898 if (op == 15 && (rn == 15 || ((rn & 0x1c) == 0x18))) {
2899 /* Integer or single precision destination. */
2900 rd = VFP_SREG_D(insn);
2902 VFP_DREG_D(rd, insn);
2905 (((rn & 0x1c) == 0x10) || ((rn & 0x14) == 0x14))) {
2906 /* VCVT from int is always from S reg regardless of dp bit.
2907 * VCVT with immediate frac_bits has same format as SREG_M
2909 rm = VFP_SREG_M(insn);
2911 VFP_DREG_M(rm, insn);
2914 rn = VFP_SREG_N(insn);
2915 if (op == 15 && rn == 15) {
2916 /* Double precision destination. */
2917 VFP_DREG_D(rd, insn);
2919 rd = VFP_SREG_D(insn);
2921 /* NB that we implicitly rely on the encoding for the frac_bits
2922 * in VCVT of fixed to float being the same as that of an SREG_M
2924 rm = VFP_SREG_M(insn);
2927 veclen = s->vec_len;
2928 if (op == 15 && rn > 3)
2931 /* Shut up compiler warnings. */
2942 /* Figure out what type of vector operation this is. */
2943 if ((rd & bank_mask) == 0) {
2948 delta_d = (s->vec_stride >> 1) + 1;
2950 delta_d = s->vec_stride + 1;
2952 if ((rm & bank_mask) == 0) {
2953 /* mixed scalar/vector */
2962 /* Load the initial operands. */
2967 /* Integer source */
2968 gen_mov_F0_vreg(0, rm);
2973 gen_mov_F0_vreg(dp, rd);
2974 gen_mov_F1_vreg(dp, rm);
2978 /* Compare with zero */
2979 gen_mov_F0_vreg(dp, rd);
2990 /* Source and destination the same. */
2991 gen_mov_F0_vreg(dp, rd);
2994 /* One source operand. */
2995 gen_mov_F0_vreg(dp, rm);
2999 /* Two source operands. */
3000 gen_mov_F0_vreg(dp, rn);
3001 gen_mov_F1_vreg(dp, rm);
3005 /* Perform the calculation. */
3007 case 0: /* mac: fd + (fn * fm) */
3009 gen_mov_F1_vreg(dp, rd);
3012 case 1: /* nmac: fd - (fn * fm) */
3015 gen_mov_F1_vreg(dp, rd);
3018 case 2: /* msc: -fd + (fn * fm) */
3020 gen_mov_F1_vreg(dp, rd);
3023 case 3: /* nmsc: -fd - (fn * fm) */
3026 gen_mov_F1_vreg(dp, rd);
3029 case 4: /* mul: fn * fm */
3032 case 5: /* nmul: -(fn * fm) */
3036 case 6: /* add: fn + fm */
3039 case 7: /* sub: fn - fm */
3042 case 8: /* div: fn / fm */
3045 case 14: /* fconst */
3046 if (!arm_feature(env, ARM_FEATURE_VFP3))
3049 n = (insn << 12) & 0x80000000;
3050 i = ((insn >> 12) & 0x70) | (insn & 0xf);
3057 tcg_gen_movi_i64(cpu_F0d, ((uint64_t)n) << 32);
3064 tcg_gen_movi_i32(cpu_F0s, n);
3067 case 15: /* extension space */
3081 case 4: /* vcvtb.f32.f16 */
3082 if (!arm_feature(env, ARM_FEATURE_VFP_FP16))
3084 tmp = gen_vfp_mrs();
3085 tcg_gen_ext16u_i32(tmp, tmp);
3086 gen_helper_vfp_fcvt_f16_to_f32(cpu_F0s, tmp, cpu_env);
3089 case 5: /* vcvtt.f32.f16 */
3090 if (!arm_feature(env, ARM_FEATURE_VFP_FP16))
3092 tmp = gen_vfp_mrs();
3093 tcg_gen_shri_i32(tmp, tmp, 16);
3094 gen_helper_vfp_fcvt_f16_to_f32(cpu_F0s, tmp, cpu_env);
3097 case 6: /* vcvtb.f16.f32 */
3098 if (!arm_feature(env, ARM_FEATURE_VFP_FP16))
3101 gen_helper_vfp_fcvt_f32_to_f16(tmp, cpu_F0s, cpu_env);
3102 gen_mov_F0_vreg(0, rd);
3103 tmp2 = gen_vfp_mrs();
3104 tcg_gen_andi_i32(tmp2, tmp2, 0xffff0000);
3105 tcg_gen_or_i32(tmp, tmp, tmp2);
3109 case 7: /* vcvtt.f16.f32 */
3110 if (!arm_feature(env, ARM_FEATURE_VFP_FP16))
3113 gen_helper_vfp_fcvt_f32_to_f16(tmp, cpu_F0s, cpu_env);
3114 tcg_gen_shli_i32(tmp, tmp, 16);
3115 gen_mov_F0_vreg(0, rd);
3116 tmp2 = gen_vfp_mrs();
3117 tcg_gen_ext16u_i32(tmp2, tmp2);
3118 tcg_gen_or_i32(tmp, tmp, tmp2);
3131 case 11: /* cmpez */
3135 case 15: /* single<->double conversion */
3137 gen_helper_vfp_fcvtsd(cpu_F0s, cpu_F0d, cpu_env);
3139 gen_helper_vfp_fcvtds(cpu_F0d, cpu_F0s, cpu_env);
3141 case 16: /* fuito */
3144 case 17: /* fsito */
3147 case 20: /* fshto */
3148 if (!arm_feature(env, ARM_FEATURE_VFP3))
3150 gen_vfp_shto(dp, 16 - rm);
3152 case 21: /* fslto */
3153 if (!arm_feature(env, ARM_FEATURE_VFP3))
3155 gen_vfp_slto(dp, 32 - rm);
3157 case 22: /* fuhto */
3158 if (!arm_feature(env, ARM_FEATURE_VFP3))
3160 gen_vfp_uhto(dp, 16 - rm);
3162 case 23: /* fulto */
3163 if (!arm_feature(env, ARM_FEATURE_VFP3))
3165 gen_vfp_ulto(dp, 32 - rm);
3167 case 24: /* ftoui */
3170 case 25: /* ftouiz */
3173 case 26: /* ftosi */
3176 case 27: /* ftosiz */
3179 case 28: /* ftosh */
3180 if (!arm_feature(env, ARM_FEATURE_VFP3))
3182 gen_vfp_tosh(dp, 16 - rm);
3184 case 29: /* ftosl */
3185 if (!arm_feature(env, ARM_FEATURE_VFP3))
3187 gen_vfp_tosl(dp, 32 - rm);
3189 case 30: /* ftouh */
3190 if (!arm_feature(env, ARM_FEATURE_VFP3))
3192 gen_vfp_touh(dp, 16 - rm);
3194 case 31: /* ftoul */
3195 if (!arm_feature(env, ARM_FEATURE_VFP3))
3197 gen_vfp_toul(dp, 32 - rm);
3199 default: /* undefined */
3200 printf ("rn:%d\n", rn);
3204 default: /* undefined */
3205 printf ("op:%d\n", op);
3209 /* Write back the result. */
3210 if (op == 15 && (rn >= 8 && rn <= 11))
3211 ; /* Comparison, do nothing. */
3212 else if (op == 15 && dp && ((rn & 0x1c) == 0x18))
3213 /* VCVT double to int: always integer result. */
3214 gen_mov_vreg_F0(0, rd);
3215 else if (op == 15 && rn == 15)
3217 gen_mov_vreg_F0(!dp, rd);
3219 gen_mov_vreg_F0(dp, rd);
3221 /* break out of the loop if we have finished */
3225 if (op == 15 && delta_m == 0) {
3226 /* single source one-many */
3228 rd = ((rd + delta_d) & (bank_mask - 1))
3230 gen_mov_vreg_F0(dp, rd);
3234 /* Setup the next operands. */
3236 rd = ((rd + delta_d) & (bank_mask - 1))
3240 /* One source operand. */
3241 rm = ((rm + delta_m) & (bank_mask - 1))
3243 gen_mov_F0_vreg(dp, rm);
3245 /* Two source operands. */
3246 rn = ((rn + delta_d) & (bank_mask - 1))
3248 gen_mov_F0_vreg(dp, rn);
3250 rm = ((rm + delta_m) & (bank_mask - 1))
3252 gen_mov_F1_vreg(dp, rm);
3260 if ((insn & 0x03e00000) == 0x00400000) {
3261 /* two-register transfer */
3262 rn = (insn >> 16) & 0xf;
3263 rd = (insn >> 12) & 0xf;
3265 VFP_DREG_M(rm, insn);
3267 rm = VFP_SREG_M(insn);
3270 if (insn & ARM_CP_RW_BIT) {
3273 gen_mov_F0_vreg(0, rm * 2);
3274 tmp = gen_vfp_mrs();
3275 store_reg(s, rd, tmp);
3276 gen_mov_F0_vreg(0, rm * 2 + 1);
3277 tmp = gen_vfp_mrs();
3278 store_reg(s, rn, tmp);
3280 gen_mov_F0_vreg(0, rm);
3281 tmp = gen_vfp_mrs();
3282 store_reg(s, rd, tmp);
3283 gen_mov_F0_vreg(0, rm + 1);
3284 tmp = gen_vfp_mrs();
3285 store_reg(s, rn, tmp);
3290 tmp = load_reg(s, rd);
3292 gen_mov_vreg_F0(0, rm * 2);
3293 tmp = load_reg(s, rn);
3295 gen_mov_vreg_F0(0, rm * 2 + 1);
3297 tmp = load_reg(s, rd);
3299 gen_mov_vreg_F0(0, rm);
3300 tmp = load_reg(s, rn);
3302 gen_mov_vreg_F0(0, rm + 1);
3307 rn = (insn >> 16) & 0xf;
3309 VFP_DREG_D(rd, insn);
3311 rd = VFP_SREG_D(insn);
3312 if (s->thumb && rn == 15) {
3314 tcg_gen_movi_i32(addr, s->pc & ~2);
3316 addr = load_reg(s, rn);
3318 if ((insn & 0x01200000) == 0x01000000) {
3319 /* Single load/store */
3320 offset = (insn & 0xff) << 2;
3321 if ((insn & (1 << 23)) == 0)
3323 tcg_gen_addi_i32(addr, addr, offset);
3324 if (insn & (1 << 20)) {
3325 gen_vfp_ld(s, dp, addr);
3326 gen_mov_vreg_F0(dp, rd);
3328 gen_mov_F0_vreg(dp, rd);
3329 gen_vfp_st(s, dp, addr);
3333 /* load/store multiple */
3335 n = (insn >> 1) & 0x7f;
3339 if (insn & (1 << 24)) /* pre-decrement */
3340 tcg_gen_addi_i32(addr, addr, -((insn & 0xff) << 2));
3346 for (i = 0; i < n; i++) {
3347 if (insn & ARM_CP_RW_BIT) {
3349 gen_vfp_ld(s, dp, addr);
3350 gen_mov_vreg_F0(dp, rd + i);
3353 gen_mov_F0_vreg(dp, rd + i);
3354 gen_vfp_st(s, dp, addr);
3356 tcg_gen_addi_i32(addr, addr, offset);
3358 if (insn & (1 << 21)) {
3360 if (insn & (1 << 24))
3361 offset = -offset * n;
3362 else if (dp && (insn & 1))
3368 tcg_gen_addi_i32(addr, addr, offset);
3369 store_reg(s, rn, addr);
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 (unlikely(s->singlestep_enabled)) {
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. Marks t0 as dead. */
3454 static int gen_set_psr(DisasContext *s, uint32_t mask, int spsr, TCGv t0)
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(t0, t0, mask);
3465 tcg_gen_or_i32(tmp, tmp, t0);
3466 store_cpu_field(tmp, spsr);
3468 gen_set_cpsr(t0, mask);
3475 /* Returns nonzero if access to the PSR is not permitted. */
3476 static int gen_set_psr_im(DisasContext *s, uint32_t mask, int spsr, uint32_t val)
3480 tcg_gen_movi_i32(tmp, val);
3481 return gen_set_psr(s, mask, spsr, tmp);
3484 /* Generate an old-style exception return. Marks pc as dead. */
3485 static void gen_exception_return(DisasContext *s, TCGv pc)
3488 store_reg(s, 15, pc);
3489 tmp = load_cpu_field(spsr);
3490 gen_set_cpsr(tmp, 0xffffffff);
3492 s->is_jmp = DISAS_UPDATE;
3495 /* Generate a v6 exception return. Marks both values as dead. */
3496 static void gen_rfe(DisasContext *s, TCGv pc, TCGv cpsr)
3498 gen_set_cpsr(cpsr, 0xffffffff);
3500 store_reg(s, 15, pc);
3501 s->is_jmp = DISAS_UPDATE;
3505 gen_set_condexec (DisasContext *s)
3507 if (s->condexec_mask) {
3508 uint32_t val = (s->condexec_cond << 4) | (s->condexec_mask >> 1);
3509 TCGv tmp = new_tmp();
3510 tcg_gen_movi_i32(tmp, val);
3511 store_cpu_field(tmp, condexec_bits);
3515 static void gen_exception_insn(DisasContext *s, int offset, int excp)
3517 gen_set_condexec(s);
3518 gen_set_pc_im(s->pc - offset);
3519 gen_exception(excp);
3520 s->is_jmp = DISAS_JUMP;
3523 static void gen_nop_hint(DisasContext *s, int val)
3527 gen_set_pc_im(s->pc);
3528 s->is_jmp = DISAS_WFI;
3532 /* TODO: Implement SEV and WFE. May help SMP performance. */
3538 #define CPU_V001 cpu_V0, cpu_V0, cpu_V1
3540 static inline int gen_neon_add(int size, TCGv t0, TCGv t1)
3543 case 0: gen_helper_neon_add_u8(t0, t0, t1); break;
3544 case 1: gen_helper_neon_add_u16(t0, t0, t1); break;
3545 case 2: tcg_gen_add_i32(t0, t0, t1); break;
3551 static inline void gen_neon_rsb(int size, TCGv t0, TCGv t1)
3554 case 0: gen_helper_neon_sub_u8(t0, t1, t0); break;
3555 case 1: gen_helper_neon_sub_u16(t0, t1, t0); break;
3556 case 2: tcg_gen_sub_i32(t0, t1, t0); break;
3561 /* 32-bit pairwise ops end up the same as the elementwise versions. */
3562 #define gen_helper_neon_pmax_s32 gen_helper_neon_max_s32
3563 #define gen_helper_neon_pmax_u32 gen_helper_neon_max_u32
3564 #define gen_helper_neon_pmin_s32 gen_helper_neon_min_s32
3565 #define gen_helper_neon_pmin_u32 gen_helper_neon_min_u32
3567 #define GEN_NEON_INTEGER_OP_ENV(name) do { \
3568 switch ((size << 1) | u) { \
3570 gen_helper_neon_##name##_s8(tmp, cpu_env, tmp, tmp2); \
3573 gen_helper_neon_##name##_u8(tmp, cpu_env, tmp, tmp2); \
3576 gen_helper_neon_##name##_s16(tmp, cpu_env, tmp, tmp2); \
3579 gen_helper_neon_##name##_u16(tmp, cpu_env, tmp, tmp2); \
3582 gen_helper_neon_##name##_s32(tmp, cpu_env, tmp, tmp2); \
3585 gen_helper_neon_##name##_u32(tmp, cpu_env, tmp, tmp2); \
3587 default: return 1; \
3590 #define GEN_NEON_INTEGER_OP(name) do { \
3591 switch ((size << 1) | u) { \
3593 gen_helper_neon_##name##_s8(tmp, tmp, tmp2); \
3596 gen_helper_neon_##name##_u8(tmp, tmp, tmp2); \
3599 gen_helper_neon_##name##_s16(tmp, tmp, tmp2); \
3602 gen_helper_neon_##name##_u16(tmp, tmp, tmp2); \
3605 gen_helper_neon_##name##_s32(tmp, tmp, tmp2); \
3608 gen_helper_neon_##name##_u32(tmp, tmp, tmp2); \
3610 default: return 1; \
3613 static TCGv neon_load_scratch(int scratch)
3615 TCGv tmp = new_tmp();
3616 tcg_gen_ld_i32(tmp, cpu_env, offsetof(CPUARMState, vfp.scratch[scratch]));
3620 static void neon_store_scratch(int scratch, TCGv var)
3622 tcg_gen_st_i32(var, cpu_env, offsetof(CPUARMState, vfp.scratch[scratch]));
3626 static inline TCGv neon_get_scalar(int size, int reg)
3630 tmp = neon_load_reg(reg & 7, reg >> 4);
3632 gen_neon_dup_high16(tmp);
3634 gen_neon_dup_low16(tmp);
3637 tmp = neon_load_reg(reg & 15, reg >> 4);
3642 static int gen_neon_unzip(int rd, int rm, int size, int q)
3645 if (size == 3 || (!q && size == 2)) {
3648 tmp = tcg_const_i32(rd);
3649 tmp2 = tcg_const_i32(rm);
3653 gen_helper_neon_qunzip8(cpu_env, tmp, tmp2);
3656 gen_helper_neon_qunzip16(cpu_env, tmp, tmp2);
3659 gen_helper_neon_qunzip32(cpu_env, tmp, tmp2);
3667 gen_helper_neon_unzip8(cpu_env, tmp, tmp2);
3670 gen_helper_neon_unzip16(cpu_env, tmp, tmp2);
3676 tcg_temp_free_i32(tmp);
3677 tcg_temp_free_i32(tmp2);
3681 static int gen_neon_zip(int rd, int rm, int size, int q)
3684 if (size == 3 || (!q && size == 2)) {
3687 tmp = tcg_const_i32(rd);
3688 tmp2 = tcg_const_i32(rm);
3692 gen_helper_neon_qzip8(cpu_env, tmp, tmp2);
3695 gen_helper_neon_qzip16(cpu_env, tmp, tmp2);
3698 gen_helper_neon_qzip32(cpu_env, tmp, tmp2);
3706 gen_helper_neon_zip8(cpu_env, tmp, tmp2);
3709 gen_helper_neon_zip16(cpu_env, tmp, tmp2);
3715 tcg_temp_free_i32(tmp);
3716 tcg_temp_free_i32(tmp2);
3720 static void gen_neon_trn_u8(TCGv t0, TCGv t1)
3727 tcg_gen_shli_i32(rd, t0, 8);
3728 tcg_gen_andi_i32(rd, rd, 0xff00ff00);
3729 tcg_gen_andi_i32(tmp, t1, 0x00ff00ff);
3730 tcg_gen_or_i32(rd, rd, tmp);
3732 tcg_gen_shri_i32(t1, t1, 8);
3733 tcg_gen_andi_i32(t1, t1, 0x00ff00ff);
3734 tcg_gen_andi_i32(tmp, t0, 0xff00ff00);
3735 tcg_gen_or_i32(t1, t1, tmp);
3736 tcg_gen_mov_i32(t0, rd);
3742 static void gen_neon_trn_u16(TCGv t0, TCGv t1)
3749 tcg_gen_shli_i32(rd, t0, 16);
3750 tcg_gen_andi_i32(tmp, t1, 0xffff);
3751 tcg_gen_or_i32(rd, rd, tmp);
3752 tcg_gen_shri_i32(t1, t1, 16);
3753 tcg_gen_andi_i32(tmp, t0, 0xffff0000);
3754 tcg_gen_or_i32(t1, t1, tmp);
3755 tcg_gen_mov_i32(t0, rd);
3766 } neon_ls_element_type[11] = {
3780 /* Translate a NEON load/store element instruction. Return nonzero if the
3781 instruction is invalid. */
3782 static int disas_neon_ls_insn(CPUState * env, DisasContext *s, uint32_t insn)
3801 if (!s->vfp_enabled)
3803 VFP_DREG_D(rd, insn);
3804 rn = (insn >> 16) & 0xf;
3806 load = (insn & (1 << 21)) != 0;
3808 if ((insn & (1 << 23)) == 0) {
3809 /* Load store all elements. */
3810 op = (insn >> 8) & 0xf;
3811 size = (insn >> 6) & 3;
3814 nregs = neon_ls_element_type[op].nregs;
3815 interleave = neon_ls_element_type[op].interleave;
3816 spacing = neon_ls_element_type[op].spacing;
3817 if (size == 3 && (interleave | spacing) != 1)
3819 load_reg_var(s, addr, rn);
3820 stride = (1 << size) * interleave;
3821 for (reg = 0; reg < nregs; reg++) {
3822 if (interleave > 2 || (interleave == 2 && nregs == 2)) {
3823 load_reg_var(s, addr, rn);
3824 tcg_gen_addi_i32(addr, addr, (1 << size) * reg);
3825 } else if (interleave == 2 && nregs == 4 && reg == 2) {
3826 load_reg_var(s, addr, rn);
3827 tcg_gen_addi_i32(addr, addr, 1 << size);
3831 tmp64 = gen_ld64(addr, IS_USER(s));
3832 neon_store_reg64(tmp64, rd);
3833 tcg_temp_free_i64(tmp64);
3835 tmp64 = tcg_temp_new_i64();
3836 neon_load_reg64(tmp64, rd);
3837 gen_st64(tmp64, addr, IS_USER(s));
3839 tcg_gen_addi_i32(addr, addr, stride);
3841 for (pass = 0; pass < 2; pass++) {
3844 tmp = gen_ld32(addr, IS_USER(s));
3845 neon_store_reg(rd, pass, tmp);
3847 tmp = neon_load_reg(rd, pass);
3848 gen_st32(tmp, addr, IS_USER(s));
3850 tcg_gen_addi_i32(addr, addr, stride);
3851 } else if (size == 1) {
3853 tmp = gen_ld16u(addr, IS_USER(s));
3854 tcg_gen_addi_i32(addr, addr, stride);
3855 tmp2 = gen_ld16u(addr, IS_USER(s));
3856 tcg_gen_addi_i32(addr, addr, stride);
3857 tcg_gen_shli_i32(tmp2, tmp2, 16);
3858 tcg_gen_or_i32(tmp, tmp, tmp2);
3860 neon_store_reg(rd, pass, tmp);
3862 tmp = neon_load_reg(rd, pass);
3864 tcg_gen_shri_i32(tmp2, tmp, 16);
3865 gen_st16(tmp, addr, IS_USER(s));
3866 tcg_gen_addi_i32(addr, addr, stride);
3867 gen_st16(tmp2, addr, IS_USER(s));
3868 tcg_gen_addi_i32(addr, addr, stride);
3870 } else /* size == 0 */ {
3873 for (n = 0; n < 4; n++) {
3874 tmp = gen_ld8u(addr, IS_USER(s));
3875 tcg_gen_addi_i32(addr, addr, stride);
3879 tcg_gen_shli_i32(tmp, tmp, n * 8);
3880 tcg_gen_or_i32(tmp2, tmp2, tmp);
3884 neon_store_reg(rd, pass, tmp2);
3886 tmp2 = neon_load_reg(rd, pass);
3887 for (n = 0; n < 4; n++) {
3890 tcg_gen_mov_i32(tmp, tmp2);
3892 tcg_gen_shri_i32(tmp, tmp2, n * 8);
3894 gen_st8(tmp, addr, IS_USER(s));
3895 tcg_gen_addi_i32(addr, addr, stride);
3906 size = (insn >> 10) & 3;
3908 /* Load single element to all lanes. */
3911 size = (insn >> 6) & 3;
3912 nregs = ((insn >> 8) & 3) + 1;
3913 stride = (insn & (1 << 5)) ? 2 : 1;
3914 load_reg_var(s, addr, rn);
3915 for (reg = 0; reg < nregs; reg++) {
3918 tmp = gen_ld8u(addr, IS_USER(s));
3919 gen_neon_dup_u8(tmp, 0);
3922 tmp = gen_ld16u(addr, IS_USER(s));
3923 gen_neon_dup_low16(tmp);
3926 tmp = gen_ld32(addr, IS_USER(s));
3930 default: /* Avoid compiler warnings. */
3933 tcg_gen_addi_i32(addr, addr, 1 << size);
3935 tcg_gen_mov_i32(tmp2, tmp);
3936 neon_store_reg(rd, 0, tmp2);
3937 neon_store_reg(rd, 1, tmp);
3940 stride = (1 << size) * nregs;
3942 /* Single element. */
3943 pass = (insn >> 7) & 1;
3946 shift = ((insn >> 5) & 3) * 8;
3950 shift = ((insn >> 6) & 1) * 16;
3951 stride = (insn & (1 << 5)) ? 2 : 1;
3955 stride = (insn & (1 << 6)) ? 2 : 1;
3960 nregs = ((insn >> 8) & 3) + 1;
3961 load_reg_var(s, addr, rn);
3962 for (reg = 0; reg < nregs; reg++) {
3966 tmp = gen_ld8u(addr, IS_USER(s));
3969 tmp = gen_ld16u(addr, IS_USER(s));
3972 tmp = gen_ld32(addr, IS_USER(s));
3974 default: /* Avoid compiler warnings. */
3978 tmp2 = neon_load_reg(rd, pass);
3979 gen_bfi(tmp, tmp2, tmp, shift, size ? 0xffff : 0xff);
3982 neon_store_reg(rd, pass, tmp);
3983 } else { /* Store */
3984 tmp = neon_load_reg(rd, pass);
3986 tcg_gen_shri_i32(tmp, tmp, shift);
3989 gen_st8(tmp, addr, IS_USER(s));
3992 gen_st16(tmp, addr, IS_USER(s));
3995 gen_st32(tmp, addr, IS_USER(s));
4000 tcg_gen_addi_i32(addr, addr, 1 << size);
4002 stride = nregs * (1 << size);
4009 base = load_reg(s, rn);
4011 tcg_gen_addi_i32(base, base, stride);
4014 index = load_reg(s, rm);
4015 tcg_gen_add_i32(base, base, index);
4018 store_reg(s, rn, base);
4023 /* Bitwise select. dest = c ? t : f. Clobbers T and F. */
4024 static void gen_neon_bsl(TCGv dest, TCGv t, TCGv f, TCGv c)
4026 tcg_gen_and_i32(t, t, c);
4027 tcg_gen_andc_i32(f, f, c);
4028 tcg_gen_or_i32(dest, t, f);
4031 static inline void gen_neon_narrow(int size, TCGv dest, TCGv_i64 src)
4034 case 0: gen_helper_neon_narrow_u8(dest, src); break;
4035 case 1: gen_helper_neon_narrow_u16(dest, src); break;
4036 case 2: tcg_gen_trunc_i64_i32(dest, src); break;
4041 static inline void gen_neon_narrow_sats(int size, TCGv dest, TCGv_i64 src)
4044 case 0: gen_helper_neon_narrow_sat_s8(dest, cpu_env, src); break;
4045 case 1: gen_helper_neon_narrow_sat_s16(dest, cpu_env, src); break;
4046 case 2: gen_helper_neon_narrow_sat_s32(dest, cpu_env, src); break;
4051 static inline void gen_neon_narrow_satu(int size, TCGv dest, TCGv_i64 src)
4054 case 0: gen_helper_neon_narrow_sat_u8(dest, cpu_env, src); break;
4055 case 1: gen_helper_neon_narrow_sat_u16(dest, cpu_env, src); break;
4056 case 2: gen_helper_neon_narrow_sat_u32(dest, cpu_env, src); break;
4061 static inline void gen_neon_unarrow_sats(int size, TCGv dest, TCGv_i64 src)
4064 case 0: gen_helper_neon_unarrow_sat8(dest, cpu_env, src); break;
4065 case 1: gen_helper_neon_unarrow_sat16(dest, cpu_env, src); break;
4066 case 2: gen_helper_neon_unarrow_sat32(dest, cpu_env, src); break;
4071 static inline void gen_neon_shift_narrow(int size, TCGv var, TCGv shift,
4077 case 1: gen_helper_neon_rshl_u16(var, var, shift); break;
4078 case 2: gen_helper_neon_rshl_u32(var, var, shift); break;
4083 case 1: gen_helper_neon_rshl_s16(var, var, shift); break;
4084 case 2: gen_helper_neon_rshl_s32(var, var, shift); break;
4091 case 1: gen_helper_neon_shl_u16(var, var, shift); break;
4092 case 2: gen_helper_neon_shl_u32(var, var, shift); break;
4097 case 1: gen_helper_neon_shl_s16(var, var, shift); break;
4098 case 2: gen_helper_neon_shl_s32(var, var, shift); break;
4105 static inline void gen_neon_widen(TCGv_i64 dest, TCGv src, int size, int u)
4109 case 0: gen_helper_neon_widen_u8(dest, src); break;
4110 case 1: gen_helper_neon_widen_u16(dest, src); break;
4111 case 2: tcg_gen_extu_i32_i64(dest, src); break;
4116 case 0: gen_helper_neon_widen_s8(dest, src); break;
4117 case 1: gen_helper_neon_widen_s16(dest, src); break;
4118 case 2: tcg_gen_ext_i32_i64(dest, src); break;
4125 static inline void gen_neon_addl(int size)
4128 case 0: gen_helper_neon_addl_u16(CPU_V001); break;
4129 case 1: gen_helper_neon_addl_u32(CPU_V001); break;
4130 case 2: tcg_gen_add_i64(CPU_V001); break;
4135 static inline void gen_neon_subl(int size)
4138 case 0: gen_helper_neon_subl_u16(CPU_V001); break;
4139 case 1: gen_helper_neon_subl_u32(CPU_V001); break;
4140 case 2: tcg_gen_sub_i64(CPU_V001); break;
4145 static inline void gen_neon_negl(TCGv_i64 var, int size)
4148 case 0: gen_helper_neon_negl_u16(var, var); break;
4149 case 1: gen_helper_neon_negl_u32(var, var); break;
4150 case 2: gen_helper_neon_negl_u64(var, var); break;
4155 static inline void gen_neon_addl_saturate(TCGv_i64 op0, TCGv_i64 op1, int size)
4158 case 1: gen_helper_neon_addl_saturate_s32(op0, cpu_env, op0, op1); break;
4159 case 2: gen_helper_neon_addl_saturate_s64(op0, cpu_env, op0, op1); break;
4164 static inline void gen_neon_mull(TCGv_i64 dest, TCGv a, TCGv b, int size, int u)
4168 switch ((size << 1) | u) {
4169 case 0: gen_helper_neon_mull_s8(dest, a, b); break;
4170 case 1: gen_helper_neon_mull_u8(dest, a, b); break;
4171 case 2: gen_helper_neon_mull_s16(dest, a, b); break;
4172 case 3: gen_helper_neon_mull_u16(dest, a, b); break;
4174 tmp = gen_muls_i64_i32(a, b);
4175 tcg_gen_mov_i64(dest, tmp);
4178 tmp = gen_mulu_i64_i32(a, b);
4179 tcg_gen_mov_i64(dest, tmp);
4184 /* gen_helper_neon_mull_[su]{8|16} do not free their parameters.
4185 Don't forget to clean them now. */
4192 static void gen_neon_narrow_op(int op, int u, int size, TCGv dest, TCGv_i64 src)
4196 gen_neon_unarrow_sats(size, dest, src);
4198 gen_neon_narrow(size, dest, src);
4202 gen_neon_narrow_satu(size, dest, src);
4204 gen_neon_narrow_sats(size, dest, src);
4209 /* Translate a NEON data processing instruction. Return nonzero if the
4210 instruction is invalid.
4211 We process data in a mixture of 32-bit and 64-bit chunks.
4212 Mostly we use 32-bit chunks so we can use normal scalar instructions. */
4214 static int disas_neon_data_insn(CPUState * env, DisasContext *s, uint32_t insn)
4227 TCGv tmp, tmp2, tmp3, tmp4, tmp5;
4230 if (!s->vfp_enabled)
4232 q = (insn & (1 << 6)) != 0;
4233 u = (insn >> 24) & 1;
4234 VFP_DREG_D(rd, insn);
4235 VFP_DREG_N(rn, insn);
4236 VFP_DREG_M(rm, insn);
4237 size = (insn >> 20) & 3;
4238 if ((insn & (1 << 23)) == 0) {
4239 /* Three register same length. */
4240 op = ((insn >> 7) & 0x1e) | ((insn >> 4) & 1);
4241 if (size == 3 && (op == 1 || op == 5 || op == 8 || op == 9
4242 || op == 10 || op == 11 || op == 16)) {
4243 /* 64-bit element instructions. */
4244 for (pass = 0; pass < (q ? 2 : 1); pass++) {
4245 neon_load_reg64(cpu_V0, rn + pass);
4246 neon_load_reg64(cpu_V1, rm + pass);
4250 gen_helper_neon_qadd_u64(cpu_V0, cpu_env,
4253 gen_helper_neon_qadd_s64(cpu_V0, cpu_env,
4259 gen_helper_neon_qsub_u64(cpu_V0, cpu_env,
4262 gen_helper_neon_qsub_s64(cpu_V0, cpu_env,
4268 gen_helper_neon_shl_u64(cpu_V0, cpu_V1, cpu_V0);
4270 gen_helper_neon_shl_s64(cpu_V0, cpu_V1, cpu_V0);
4275 gen_helper_neon_qshl_u64(cpu_V0, cpu_env,
4278 gen_helper_neon_qshl_s64(cpu_V0, cpu_env,
4282 case 10: /* VRSHL */
4284 gen_helper_neon_rshl_u64(cpu_V0, cpu_V1, cpu_V0);
4286 gen_helper_neon_rshl_s64(cpu_V0, cpu_V1, cpu_V0);
4289 case 11: /* VQRSHL */
4291 gen_helper_neon_qrshl_u64(cpu_V0, cpu_env,
4294 gen_helper_neon_qrshl_s64(cpu_V0, cpu_env,
4300 tcg_gen_sub_i64(CPU_V001);
4302 tcg_gen_add_i64(CPU_V001);
4308 neon_store_reg64(cpu_V0, rd + pass);
4315 case 10: /* VRSHL */
4316 case 11: /* VQRSHL */
4319 /* Shift instruction operands are reversed. */
4326 case 20: /* VPMAX */
4327 case 21: /* VPMIN */
4328 case 23: /* VPADD */
4331 case 26: /* VPADD (float) */
4332 pairwise = (u && size < 2);
4334 case 30: /* VPMIN/VPMAX (float) */
4342 for (pass = 0; pass < (q ? 4 : 2); pass++) {
4351 tmp = neon_load_reg(rn, n);
4352 tmp2 = neon_load_reg(rn, n + 1);
4354 tmp = neon_load_reg(rm, n);
4355 tmp2 = neon_load_reg(rm, n + 1);
4359 tmp = neon_load_reg(rn, pass);
4360 tmp2 = neon_load_reg(rm, pass);
4364 GEN_NEON_INTEGER_OP(hadd);
4367 GEN_NEON_INTEGER_OP_ENV(qadd);
4369 case 2: /* VRHADD */
4370 GEN_NEON_INTEGER_OP(rhadd);
4372 case 3: /* Logic ops. */
4373 switch ((u << 2) | size) {
4375 tcg_gen_and_i32(tmp, tmp, tmp2);
4378 tcg_gen_andc_i32(tmp, tmp, tmp2);
4381 tcg_gen_or_i32(tmp, tmp, tmp2);
4384 tcg_gen_orc_i32(tmp, tmp, tmp2);
4387 tcg_gen_xor_i32(tmp, tmp, tmp2);
4390 tmp3 = neon_load_reg(rd, pass);
4391 gen_neon_bsl(tmp, tmp, tmp2, tmp3);
4395 tmp3 = neon_load_reg(rd, pass);
4396 gen_neon_bsl(tmp, tmp, tmp3, tmp2);
4400 tmp3 = neon_load_reg(rd, pass);
4401 gen_neon_bsl(tmp, tmp3, tmp, tmp2);
4407 GEN_NEON_INTEGER_OP(hsub);
4410 GEN_NEON_INTEGER_OP_ENV(qsub);
4413 GEN_NEON_INTEGER_OP(cgt);
4416 GEN_NEON_INTEGER_OP(cge);
4419 GEN_NEON_INTEGER_OP(shl);
4422 GEN_NEON_INTEGER_OP_ENV(qshl);
4424 case 10: /* VRSHL */
4425 GEN_NEON_INTEGER_OP(rshl);
4427 case 11: /* VQRSHL */
4428 GEN_NEON_INTEGER_OP_ENV(qrshl);
4431 GEN_NEON_INTEGER_OP(max);
4434 GEN_NEON_INTEGER_OP(min);
4437 GEN_NEON_INTEGER_OP(abd);
4440 GEN_NEON_INTEGER_OP(abd);
4442 tmp2 = neon_load_reg(rd, pass);
4443 gen_neon_add(size, tmp, tmp2);
4446 if (!u) { /* VADD */
4447 if (gen_neon_add(size, tmp, tmp2))
4451 case 0: gen_helper_neon_sub_u8(tmp, tmp, tmp2); break;
4452 case 1: gen_helper_neon_sub_u16(tmp, tmp, tmp2); break;
4453 case 2: tcg_gen_sub_i32(tmp, tmp, tmp2); break;
4459 if (!u) { /* VTST */
4461 case 0: gen_helper_neon_tst_u8(tmp, tmp, tmp2); break;
4462 case 1: gen_helper_neon_tst_u16(tmp, tmp, tmp2); break;
4463 case 2: gen_helper_neon_tst_u32(tmp, tmp, tmp2); break;
4468 case 0: gen_helper_neon_ceq_u8(tmp, tmp, tmp2); break;
4469 case 1: gen_helper_neon_ceq_u16(tmp, tmp, tmp2); break;
4470 case 2: gen_helper_neon_ceq_u32(tmp, tmp, tmp2); break;
4475 case 18: /* Multiply. */
4477 case 0: gen_helper_neon_mul_u8(tmp, tmp, tmp2); break;
4478 case 1: gen_helper_neon_mul_u16(tmp, tmp, tmp2); break;
4479 case 2: tcg_gen_mul_i32(tmp, tmp, tmp2); break;
4483 tmp2 = neon_load_reg(rd, pass);
4485 gen_neon_rsb(size, tmp, tmp2);
4487 gen_neon_add(size, tmp, tmp2);
4491 if (u) { /* polynomial */
4492 gen_helper_neon_mul_p8(tmp, tmp, tmp2);
4493 } else { /* Integer */
4495 case 0: gen_helper_neon_mul_u8(tmp, tmp, tmp2); break;
4496 case 1: gen_helper_neon_mul_u16(tmp, tmp, tmp2); break;
4497 case 2: tcg_gen_mul_i32(tmp, tmp, tmp2); break;
4502 case 20: /* VPMAX */
4503 GEN_NEON_INTEGER_OP(pmax);
4505 case 21: /* VPMIN */
4506 GEN_NEON_INTEGER_OP(pmin);
4508 case 22: /* Hultiply high. */
4509 if (!u) { /* VQDMULH */
4511 case 1: gen_helper_neon_qdmulh_s16(tmp, cpu_env, tmp, tmp2); break;
4512 case 2: gen_helper_neon_qdmulh_s32(tmp, cpu_env, tmp, tmp2); break;
4515 } else { /* VQRDHMUL */
4517 case 1: gen_helper_neon_qrdmulh_s16(tmp, cpu_env, tmp, tmp2); break;
4518 case 2: gen_helper_neon_qrdmulh_s32(tmp, cpu_env, tmp, tmp2); break;
4523 case 23: /* VPADD */
4527 case 0: gen_helper_neon_padd_u8(tmp, tmp, tmp2); break;
4528 case 1: gen_helper_neon_padd_u16(tmp, tmp, tmp2); break;
4529 case 2: tcg_gen_add_i32(tmp, tmp, tmp2); break;
4533 case 26: /* Floating point arithnetic. */
4534 switch ((u << 2) | size) {
4536 gen_helper_neon_add_f32(tmp, tmp, tmp2);
4539 gen_helper_neon_sub_f32(tmp, tmp, tmp2);
4542 gen_helper_neon_add_f32(tmp, tmp, tmp2);
4545 gen_helper_neon_abd_f32(tmp, tmp, tmp2);
4551 case 27: /* Float multiply. */
4552 gen_helper_neon_mul_f32(tmp, tmp, tmp2);
4555 tmp2 = neon_load_reg(rd, pass);
4557 gen_helper_neon_add_f32(tmp, tmp, tmp2);
4559 gen_helper_neon_sub_f32(tmp, tmp2, tmp);
4563 case 28: /* Float compare. */
4565 gen_helper_neon_ceq_f32(tmp, tmp, tmp2);
4568 gen_helper_neon_cge_f32(tmp, tmp, tmp2);
4570 gen_helper_neon_cgt_f32(tmp, tmp, tmp2);
4573 case 29: /* Float compare absolute. */
4577 gen_helper_neon_acge_f32(tmp, tmp, tmp2);
4579 gen_helper_neon_acgt_f32(tmp, tmp, tmp2);
4581 case 30: /* Float min/max. */
4583 gen_helper_neon_max_f32(tmp, tmp, tmp2);
4585 gen_helper_neon_min_f32(tmp, tmp, tmp2);
4589 gen_helper_recps_f32(tmp, tmp, tmp2, cpu_env);
4591 gen_helper_rsqrts_f32(tmp, tmp, tmp2, cpu_env);
4598 /* Save the result. For elementwise operations we can put it
4599 straight into the destination register. For pairwise operations
4600 we have to be careful to avoid clobbering the source operands. */
4601 if (pairwise && rd == rm) {
4602 neon_store_scratch(pass, tmp);
4604 neon_store_reg(rd, pass, tmp);
4608 if (pairwise && rd == rm) {
4609 for (pass = 0; pass < (q ? 4 : 2); pass++) {
4610 tmp = neon_load_scratch(pass);
4611 neon_store_reg(rd, pass, tmp);
4614 /* End of 3 register same size operations. */
4615 } else if (insn & (1 << 4)) {
4616 if ((insn & 0x00380080) != 0) {
4617 /* Two registers and shift. */
4618 op = (insn >> 8) & 0xf;
4619 if (insn & (1 << 7)) {
4624 while ((insn & (1 << (size + 19))) == 0)
4627 shift = (insn >> 16) & ((1 << (3 + size)) - 1);
4628 /* To avoid excessive dumplication of ops we implement shift
4629 by immediate using the variable shift operations. */
4631 /* Shift by immediate:
4632 VSHR, VSRA, VRSHR, VRSRA, VSRI, VSHL, VQSHL, VQSHLU. */
4633 /* Right shifts are encoded as N - shift, where N is the
4634 element size in bits. */
4636 shift = shift - (1 << (size + 3));
4644 imm = (uint8_t) shift;
4649 imm = (uint16_t) shift;
4660 for (pass = 0; pass < count; pass++) {
4662 neon_load_reg64(cpu_V0, rm + pass);
4663 tcg_gen_movi_i64(cpu_V1, imm);
4668 gen_helper_neon_shl_u64(cpu_V0, cpu_V0, cpu_V1);
4670 gen_helper_neon_shl_s64(cpu_V0, cpu_V0, cpu_V1);
4675 gen_helper_neon_rshl_u64(cpu_V0, cpu_V0, cpu_V1);
4677 gen_helper_neon_rshl_s64(cpu_V0, cpu_V0, cpu_V1);
4682 gen_helper_neon_shl_u64(cpu_V0, cpu_V0, cpu_V1);
4684 case 5: /* VSHL, VSLI */
4685 gen_helper_neon_shl_u64(cpu_V0, cpu_V0, cpu_V1);
4687 case 6: /* VQSHLU */
4689 gen_helper_neon_qshlu_s64(cpu_V0, cpu_env,
4697 gen_helper_neon_qshl_u64(cpu_V0, cpu_env,
4700 gen_helper_neon_qshl_s64(cpu_V0, cpu_env,
4705 if (op == 1 || op == 3) {
4707 neon_load_reg64(cpu_V1, rd + pass);
4708 tcg_gen_add_i64(cpu_V0, cpu_V0, cpu_V1);
4709 } else if (op == 4 || (op == 5 && u)) {
4711 neon_load_reg64(cpu_V1, rd + pass);
4713 if (shift < -63 || shift > 63) {
4717 mask = 0xffffffffffffffffull >> -shift;
4719 mask = 0xffffffffffffffffull << shift;
4722 tcg_gen_andi_i64(cpu_V1, cpu_V1, ~mask);
4723 tcg_gen_or_i64(cpu_V0, cpu_V0, cpu_V1);
4725 neon_store_reg64(cpu_V0, rd + pass);
4726 } else { /* size < 3 */
4727 /* Operands in T0 and T1. */
4728 tmp = neon_load_reg(rm, pass);
4730 tcg_gen_movi_i32(tmp2, imm);
4734 GEN_NEON_INTEGER_OP(shl);
4738 GEN_NEON_INTEGER_OP(rshl);
4743 GEN_NEON_INTEGER_OP(shl);
4745 case 5: /* VSHL, VSLI */
4747 case 0: gen_helper_neon_shl_u8(tmp, tmp, tmp2); break;
4748 case 1: gen_helper_neon_shl_u16(tmp, tmp, tmp2); break;
4749 case 2: gen_helper_neon_shl_u32(tmp, tmp, tmp2); break;
4753 case 6: /* VQSHLU */
4759 gen_helper_neon_qshlu_s8(tmp, cpu_env,
4763 gen_helper_neon_qshlu_s16(tmp, cpu_env,
4767 gen_helper_neon_qshlu_s32(tmp, cpu_env,
4775 GEN_NEON_INTEGER_OP_ENV(qshl);
4780 if (op == 1 || op == 3) {
4782 tmp2 = neon_load_reg(rd, pass);
4783 gen_neon_add(size, tmp, tmp2);
4785 } else if (op == 4 || (op == 5 && u)) {
4790 mask = 0xff >> -shift;
4792 mask = (uint8_t)(0xff << shift);
4798 mask = 0xffff >> -shift;
4800 mask = (uint16_t)(0xffff << shift);
4804 if (shift < -31 || shift > 31) {
4808 mask = 0xffffffffu >> -shift;
4810 mask = 0xffffffffu << shift;
4816 tmp2 = neon_load_reg(rd, pass);
4817 tcg_gen_andi_i32(tmp, tmp, mask);
4818 tcg_gen_andi_i32(tmp2, tmp2, ~mask);
4819 tcg_gen_or_i32(tmp, tmp, tmp2);
4822 neon_store_reg(rd, pass, tmp);
4825 } else if (op < 10) {
4826 /* Shift by immediate and narrow:
4827 VSHRN, VRSHRN, VQSHRN, VQRSHRN. */
4828 int input_unsigned = (op == 8) ? !u : u;
4830 shift = shift - (1 << (size + 3));
4833 tmp64 = tcg_const_i64(shift);
4834 neon_load_reg64(cpu_V0, rm);
4835 neon_load_reg64(cpu_V1, rm + 1);
4836 for (pass = 0; pass < 2; pass++) {
4844 if (input_unsigned) {
4845 gen_helper_neon_rshl_u64(cpu_V0, in, tmp64);
4847 gen_helper_neon_rshl_s64(cpu_V0, in, tmp64);
4850 if (input_unsigned) {
4851 gen_helper_neon_shl_u64(cpu_V0, in, tmp64);
4853 gen_helper_neon_shl_s64(cpu_V0, in, tmp64);
4857 gen_neon_narrow_op(op == 8, u, size - 1, tmp, cpu_V0);
4858 neon_store_reg(rd, pass, tmp);
4860 tcg_temp_free_i64(tmp64);
4863 imm = (uint16_t)shift;
4867 imm = (uint32_t)shift;
4869 tmp2 = tcg_const_i32(imm);
4870 tmp4 = neon_load_reg(rm + 1, 0);
4871 tmp5 = neon_load_reg(rm + 1, 1);
4872 for (pass = 0; pass < 2; pass++) {
4874 tmp = neon_load_reg(rm, 0);
4878 gen_neon_shift_narrow(size, tmp, tmp2, q,
4881 tmp3 = neon_load_reg(rm, 1);
4885 gen_neon_shift_narrow(size, tmp3, tmp2, q,
4887 tcg_gen_concat_i32_i64(cpu_V0, tmp, tmp3);
4891 gen_neon_narrow_op(op == 8, u, size - 1, tmp, cpu_V0);
4892 neon_store_reg(rd, pass, tmp);
4894 tcg_temp_free_i32(tmp2);
4896 } else if (op == 10) {
4900 tmp = neon_load_reg(rm, 0);
4901 tmp2 = neon_load_reg(rm, 1);
4902 for (pass = 0; pass < 2; pass++) {
4906 gen_neon_widen(cpu_V0, tmp, size, u);
4909 /* The shift is less than the width of the source
4910 type, so we can just shift the whole register. */
4911 tcg_gen_shli_i64(cpu_V0, cpu_V0, shift);
4912 /* Widen the result of shift: we need to clear
4913 * the potential overflow bits resulting from
4914 * left bits of the narrow input appearing as
4915 * right bits of left the neighbour narrow
4917 if (size < 2 || !u) {
4920 imm = (0xffu >> (8 - shift));
4922 } else if (size == 1) {
4923 imm = 0xffff >> (16 - shift);
4926 imm = 0xffffffff >> (32 - shift);
4929 imm64 = imm | (((uint64_t)imm) << 32);
4933 tcg_gen_andi_i64(cpu_V0, cpu_V0, ~imm64);
4936 neon_store_reg64(cpu_V0, rd + pass);
4938 } else if (op >= 14) {
4939 /* VCVT fixed-point. */
4940 /* We have already masked out the must-be-1 top bit of imm6,
4941 * hence this 32-shift where the ARM ARM has 64-imm6.
4944 for (pass = 0; pass < (q ? 4 : 2); pass++) {
4945 tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, pass));
4948 gen_vfp_ulto(0, shift);
4950 gen_vfp_slto(0, shift);
4953 gen_vfp_toul(0, shift);
4955 gen_vfp_tosl(0, shift);
4957 tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, pass));
4962 } else { /* (insn & 0x00380080) == 0 */
4965 op = (insn >> 8) & 0xf;
4966 /* One register and immediate. */
4967 imm = (u << 7) | ((insn >> 12) & 0x70) | (insn & 0xf);
4968 invert = (insn & (1 << 5)) != 0;
4986 imm = (imm << 8) | (imm << 24);
4989 imm = (imm << 8) | 0xff;
4992 imm = (imm << 16) | 0xffff;
4995 imm |= (imm << 8) | (imm << 16) | (imm << 24);
5000 imm = ((imm & 0x80) << 24) | ((imm & 0x3f) << 19)
5001 | ((imm & 0x40) ? (0x1f << 25) : (1 << 30));
5007 for (pass = 0; pass < (q ? 4 : 2); pass++) {
5008 if (op & 1 && op < 12) {
5009 tmp = neon_load_reg(rd, pass);
5011 /* The immediate value has already been inverted, so
5013 tcg_gen_andi_i32(tmp, tmp, imm);
5015 tcg_gen_ori_i32(tmp, tmp, imm);
5020 if (op == 14 && invert) {
5023 for (n = 0; n < 4; n++) {
5024 if (imm & (1 << (n + (pass & 1) * 4)))
5025 val |= 0xff << (n * 8);
5027 tcg_gen_movi_i32(tmp, val);
5029 tcg_gen_movi_i32(tmp, imm);
5032 neon_store_reg(rd, pass, tmp);
5035 } else { /* (insn & 0x00800010 == 0x00800000) */
5037 op = (insn >> 8) & 0xf;
5038 if ((insn & (1 << 6)) == 0) {
5039 /* Three registers of different lengths. */
5043 /* prewiden, src1_wide, src2_wide */
5044 static const int neon_3reg_wide[16][3] = {
5045 {1, 0, 0}, /* VADDL */
5046 {1, 1, 0}, /* VADDW */
5047 {1, 0, 0}, /* VSUBL */
5048 {1, 1, 0}, /* VSUBW */
5049 {0, 1, 1}, /* VADDHN */
5050 {0, 0, 0}, /* VABAL */
5051 {0, 1, 1}, /* VSUBHN */
5052 {0, 0, 0}, /* VABDL */
5053 {0, 0, 0}, /* VMLAL */
5054 {0, 0, 0}, /* VQDMLAL */
5055 {0, 0, 0}, /* VMLSL */
5056 {0, 0, 0}, /* VQDMLSL */
5057 {0, 0, 0}, /* Integer VMULL */
5058 {0, 0, 0}, /* VQDMULL */
5059 {0, 0, 0} /* Polynomial VMULL */
5062 prewiden = neon_3reg_wide[op][0];
5063 src1_wide = neon_3reg_wide[op][1];
5064 src2_wide = neon_3reg_wide[op][2];
5066 if (size == 0 && (op == 9 || op == 11 || op == 13))
5069 /* Avoid overlapping operands. Wide source operands are
5070 always aligned so will never overlap with wide
5071 destinations in problematic ways. */
5072 if (rd == rm && !src2_wide) {
5073 tmp = neon_load_reg(rm, 1);
5074 neon_store_scratch(2, tmp);
5075 } else if (rd == rn && !src1_wide) {
5076 tmp = neon_load_reg(rn, 1);
5077 neon_store_scratch(2, tmp);
5080 for (pass = 0; pass < 2; pass++) {
5082 neon_load_reg64(cpu_V0, rn + pass);
5085 if (pass == 1 && rd == rn) {
5086 tmp = neon_load_scratch(2);
5088 tmp = neon_load_reg(rn, pass);
5091 gen_neon_widen(cpu_V0, tmp, size, u);
5095 neon_load_reg64(cpu_V1, rm + pass);
5098 if (pass == 1 && rd == rm) {
5099 tmp2 = neon_load_scratch(2);
5101 tmp2 = neon_load_reg(rm, pass);
5104 gen_neon_widen(cpu_V1, tmp2, size, u);
5108 case 0: case 1: case 4: /* VADDL, VADDW, VADDHN, VRADDHN */
5109 gen_neon_addl(size);
5111 case 2: case 3: case 6: /* VSUBL, VSUBW, VSUBHN, VRSUBHN */
5112 gen_neon_subl(size);
5114 case 5: case 7: /* VABAL, VABDL */
5115 switch ((size << 1) | u) {
5117 gen_helper_neon_abdl_s16(cpu_V0, tmp, tmp2);
5120 gen_helper_neon_abdl_u16(cpu_V0, tmp, tmp2);
5123 gen_helper_neon_abdl_s32(cpu_V0, tmp, tmp2);
5126 gen_helper_neon_abdl_u32(cpu_V0, tmp, tmp2);
5129 gen_helper_neon_abdl_s64(cpu_V0, tmp, tmp2);
5132 gen_helper_neon_abdl_u64(cpu_V0, tmp, tmp2);
5139 case 8: case 9: case 10: case 11: case 12: case 13:
5140 /* VMLAL, VQDMLAL, VMLSL, VQDMLSL, VMULL, VQDMULL */
5141 gen_neon_mull(cpu_V0, tmp, tmp2, size, u);
5143 case 14: /* Polynomial VMULL */
5144 gen_helper_neon_mull_p8(cpu_V0, tmp, tmp2);
5148 default: /* 15 is RESERVED. */
5153 gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
5154 neon_store_reg64(cpu_V0, rd + pass);
5155 } else if (op == 5 || (op >= 8 && op <= 11)) {
5157 neon_load_reg64(cpu_V1, rd + pass);
5159 case 10: /* VMLSL */
5160 gen_neon_negl(cpu_V0, size);
5162 case 5: case 8: /* VABAL, VMLAL */
5163 gen_neon_addl(size);
5165 case 9: case 11: /* VQDMLAL, VQDMLSL */
5166 gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
5168 gen_neon_negl(cpu_V0, size);
5170 gen_neon_addl_saturate(cpu_V0, cpu_V1, size);
5175 neon_store_reg64(cpu_V0, rd + pass);
5176 } else if (op == 4 || op == 6) {
5177 /* Narrowing operation. */
5182 gen_helper_neon_narrow_high_u8(tmp, cpu_V0);
5185 gen_helper_neon_narrow_high_u16(tmp, cpu_V0);
5188 tcg_gen_shri_i64(cpu_V0, cpu_V0, 32);
5189 tcg_gen_trunc_i64_i32(tmp, cpu_V0);
5196 gen_helper_neon_narrow_round_high_u8(tmp, cpu_V0);
5199 gen_helper_neon_narrow_round_high_u16(tmp, cpu_V0);
5202 tcg_gen_addi_i64(cpu_V0, cpu_V0, 1u << 31);
5203 tcg_gen_shri_i64(cpu_V0, cpu_V0, 32);
5204 tcg_gen_trunc_i64_i32(tmp, cpu_V0);
5212 neon_store_reg(rd, 0, tmp3);
5213 neon_store_reg(rd, 1, tmp);
5216 /* Write back the result. */
5217 neon_store_reg64(cpu_V0, rd + pass);
5221 /* Two registers and a scalar. */
5223 case 0: /* Integer VMLA scalar */
5224 case 1: /* Float VMLA scalar */
5225 case 4: /* Integer VMLS scalar */
5226 case 5: /* Floating point VMLS scalar */
5227 case 8: /* Integer VMUL scalar */
5228 case 9: /* Floating point VMUL scalar */
5229 case 12: /* VQDMULH scalar */
5230 case 13: /* VQRDMULH scalar */
5231 tmp = neon_get_scalar(size, rm);
5232 neon_store_scratch(0, tmp);
5233 for (pass = 0; pass < (u ? 4 : 2); pass++) {
5234 tmp = neon_load_scratch(0);
5235 tmp2 = neon_load_reg(rn, pass);
5238 gen_helper_neon_qdmulh_s16(tmp, cpu_env, tmp, tmp2);
5240 gen_helper_neon_qdmulh_s32(tmp, cpu_env, tmp, tmp2);
5242 } else if (op == 13) {
5244 gen_helper_neon_qrdmulh_s16(tmp, cpu_env, tmp, tmp2);
5246 gen_helper_neon_qrdmulh_s32(tmp, cpu_env, tmp, tmp2);
5248 } else if (op & 1) {
5249 gen_helper_neon_mul_f32(tmp, tmp, tmp2);
5252 case 0: gen_helper_neon_mul_u8(tmp, tmp, tmp2); break;
5253 case 1: gen_helper_neon_mul_u16(tmp, tmp, tmp2); break;
5254 case 2: tcg_gen_mul_i32(tmp, tmp, tmp2); break;
5261 tmp2 = neon_load_reg(rd, pass);
5264 gen_neon_add(size, tmp, tmp2);
5267 gen_helper_neon_add_f32(tmp, tmp, tmp2);
5270 gen_neon_rsb(size, tmp, tmp2);
5273 gen_helper_neon_sub_f32(tmp, tmp2, tmp);
5280 neon_store_reg(rd, pass, tmp);
5283 case 2: /* VMLAL sclar */
5284 case 3: /* VQDMLAL scalar */
5285 case 6: /* VMLSL scalar */
5286 case 7: /* VQDMLSL scalar */
5287 case 10: /* VMULL scalar */
5288 case 11: /* VQDMULL scalar */
5289 if (size == 0 && (op == 3 || op == 7 || op == 11))
5292 tmp2 = neon_get_scalar(size, rm);
5293 /* We need a copy of tmp2 because gen_neon_mull
5294 * deletes it during pass 0. */
5296 tcg_gen_mov_i32(tmp4, tmp2);
5297 tmp3 = neon_load_reg(rn, 1);
5299 for (pass = 0; pass < 2; pass++) {
5301 tmp = neon_load_reg(rn, 0);
5306 gen_neon_mull(cpu_V0, tmp, tmp2, size, u);
5308 neon_load_reg64(cpu_V1, rd + pass);
5312 gen_neon_negl(cpu_V0, size);
5315 gen_neon_addl(size);
5318 gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
5320 gen_neon_negl(cpu_V0, size);
5322 gen_neon_addl_saturate(cpu_V0, cpu_V1, size);
5328 gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
5333 neon_store_reg64(cpu_V0, rd + pass);
5338 default: /* 14 and 15 are RESERVED */
5342 } else { /* size == 3 */
5345 imm = (insn >> 8) & 0xf;
5351 neon_load_reg64(cpu_V0, rn);
5353 neon_load_reg64(cpu_V1, rn + 1);
5355 } else if (imm == 8) {
5356 neon_load_reg64(cpu_V0, rn + 1);
5358 neon_load_reg64(cpu_V1, rm);
5361 tmp64 = tcg_temp_new_i64();
5363 neon_load_reg64(cpu_V0, rn);
5364 neon_load_reg64(tmp64, rn + 1);
5366 neon_load_reg64(cpu_V0, rn + 1);
5367 neon_load_reg64(tmp64, rm);
5369 tcg_gen_shri_i64(cpu_V0, cpu_V0, (imm & 7) * 8);
5370 tcg_gen_shli_i64(cpu_V1, tmp64, 64 - ((imm & 7) * 8));
5371 tcg_gen_or_i64(cpu_V0, cpu_V0, cpu_V1);
5373 neon_load_reg64(cpu_V1, rm);
5375 neon_load_reg64(cpu_V1, rm + 1);
5378 tcg_gen_shli_i64(cpu_V1, cpu_V1, 64 - (imm * 8));
5379 tcg_gen_shri_i64(tmp64, tmp64, imm * 8);
5380 tcg_gen_or_i64(cpu_V1, cpu_V1, tmp64);
5381 tcg_temp_free_i64(tmp64);
5384 neon_load_reg64(cpu_V0, rn);
5385 tcg_gen_shri_i64(cpu_V0, cpu_V0, imm * 8);
5386 neon_load_reg64(cpu_V1, rm);
5387 tcg_gen_shli_i64(cpu_V1, cpu_V1, 64 - (imm * 8));
5388 tcg_gen_or_i64(cpu_V0, cpu_V0, cpu_V1);
5390 neon_store_reg64(cpu_V0, rd);
5392 neon_store_reg64(cpu_V1, rd + 1);
5394 } else if ((insn & (1 << 11)) == 0) {
5395 /* Two register misc. */
5396 op = ((insn >> 12) & 0x30) | ((insn >> 7) & 0xf);
5397 size = (insn >> 18) & 3;
5399 case 0: /* VREV64 */
5402 for (pass = 0; pass < (q ? 2 : 1); pass++) {
5403 tmp = neon_load_reg(rm, pass * 2);
5404 tmp2 = neon_load_reg(rm, pass * 2 + 1);
5406 case 0: tcg_gen_bswap32_i32(tmp, tmp); break;
5407 case 1: gen_swap_half(tmp); break;
5408 case 2: /* no-op */ break;
5411 neon_store_reg(rd, pass * 2 + 1, tmp);
5413 neon_store_reg(rd, pass * 2, tmp2);
5416 case 0: tcg_gen_bswap32_i32(tmp2, tmp2); break;
5417 case 1: gen_swap_half(tmp2); break;
5420 neon_store_reg(rd, pass * 2, tmp2);
5424 case 4: case 5: /* VPADDL */
5425 case 12: case 13: /* VPADAL */
5428 for (pass = 0; pass < q + 1; pass++) {
5429 tmp = neon_load_reg(rm, pass * 2);
5430 gen_neon_widen(cpu_V0, tmp, size, op & 1);
5431 tmp = neon_load_reg(rm, pass * 2 + 1);
5432 gen_neon_widen(cpu_V1, tmp, size, op & 1);
5434 case 0: gen_helper_neon_paddl_u16(CPU_V001); break;
5435 case 1: gen_helper_neon_paddl_u32(CPU_V001); break;
5436 case 2: tcg_gen_add_i64(CPU_V001); break;
5441 neon_load_reg64(cpu_V1, rd + pass);
5442 gen_neon_addl(size);
5444 neon_store_reg64(cpu_V0, rd + pass);
5449 for (n = 0; n < (q ? 4 : 2); n += 2) {
5450 tmp = neon_load_reg(rm, n);
5451 tmp2 = neon_load_reg(rd, n + 1);
5452 neon_store_reg(rm, n, tmp2);
5453 neon_store_reg(rd, n + 1, tmp);
5460 if (gen_neon_unzip(rd, rm, size, q)) {
5465 if (gen_neon_zip(rd, rm, size, q)) {
5469 case 36: case 37: /* VMOVN, VQMOVUN, VQMOVN */
5473 for (pass = 0; pass < 2; pass++) {
5474 neon_load_reg64(cpu_V0, rm + pass);
5476 gen_neon_narrow_op(op == 36, q, size, tmp, cpu_V0);
5480 neon_store_reg(rd, 0, tmp2);
5481 neon_store_reg(rd, 1, tmp);
5485 case 38: /* VSHLL */
5488 tmp = neon_load_reg(rm, 0);
5489 tmp2 = neon_load_reg(rm, 1);
5490 for (pass = 0; pass < 2; pass++) {
5493 gen_neon_widen(cpu_V0, tmp, size, 1);
5494 tcg_gen_shli_i64(cpu_V0, cpu_V0, 8 << size);
5495 neon_store_reg64(cpu_V0, rd + pass);
5498 case 44: /* VCVT.F16.F32 */
5499 if (!arm_feature(env, ARM_FEATURE_VFP_FP16))
5503 tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, 0));
5504 gen_helper_neon_fcvt_f32_to_f16(tmp, cpu_F0s, cpu_env);
5505 tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, 1));
5506 gen_helper_neon_fcvt_f32_to_f16(tmp2, cpu_F0s, cpu_env);
5507 tcg_gen_shli_i32(tmp2, tmp2, 16);
5508 tcg_gen_or_i32(tmp2, tmp2, tmp);
5509 tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, 2));
5510 gen_helper_neon_fcvt_f32_to_f16(tmp, cpu_F0s, cpu_env);
5511 tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, 3));
5512 neon_store_reg(rd, 0, tmp2);
5514 gen_helper_neon_fcvt_f32_to_f16(tmp2, cpu_F0s, cpu_env);
5515 tcg_gen_shli_i32(tmp2, tmp2, 16);
5516 tcg_gen_or_i32(tmp2, tmp2, tmp);
5517 neon_store_reg(rd, 1, tmp2);
5520 case 46: /* VCVT.F32.F16 */
5521 if (!arm_feature(env, ARM_FEATURE_VFP_FP16))
5524 tmp = neon_load_reg(rm, 0);
5525 tmp2 = neon_load_reg(rm, 1);
5526 tcg_gen_ext16u_i32(tmp3, tmp);
5527 gen_helper_neon_fcvt_f16_to_f32(cpu_F0s, tmp3, cpu_env);
5528 tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, 0));
5529 tcg_gen_shri_i32(tmp3, tmp, 16);
5530 gen_helper_neon_fcvt_f16_to_f32(cpu_F0s, tmp3, cpu_env);
5531 tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, 1));
5533 tcg_gen_ext16u_i32(tmp3, tmp2);
5534 gen_helper_neon_fcvt_f16_to_f32(cpu_F0s, tmp3, cpu_env);
5535 tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, 2));
5536 tcg_gen_shri_i32(tmp3, tmp2, 16);
5537 gen_helper_neon_fcvt_f16_to_f32(cpu_F0s, tmp3, cpu_env);
5538 tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, 3));
5544 for (pass = 0; pass < (q ? 4 : 2); pass++) {
5545 if (op == 30 || op == 31 || op >= 58) {
5546 tcg_gen_ld_f32(cpu_F0s, cpu_env,
5547 neon_reg_offset(rm, pass));
5550 tmp = neon_load_reg(rm, pass);
5553 case 1: /* VREV32 */
5555 case 0: tcg_gen_bswap32_i32(tmp, tmp); break;
5556 case 1: gen_swap_half(tmp); break;
5560 case 2: /* VREV16 */
5567 case 0: gen_helper_neon_cls_s8(tmp, tmp); break;
5568 case 1: gen_helper_neon_cls_s16(tmp, tmp); break;
5569 case 2: gen_helper_neon_cls_s32(tmp, tmp); break;
5575 case 0: gen_helper_neon_clz_u8(tmp, tmp); break;
5576 case 1: gen_helper_neon_clz_u16(tmp, tmp); break;
5577 case 2: gen_helper_clz(tmp, tmp); break;
5584 gen_helper_neon_cnt_u8(tmp, tmp);
5589 tcg_gen_not_i32(tmp, tmp);
5591 case 14: /* VQABS */
5593 case 0: gen_helper_neon_qabs_s8(tmp, cpu_env, tmp); break;
5594 case 1: gen_helper_neon_qabs_s16(tmp, cpu_env, tmp); break;
5595 case 2: gen_helper_neon_qabs_s32(tmp, cpu_env, tmp); break;
5599 case 15: /* VQNEG */
5601 case 0: gen_helper_neon_qneg_s8(tmp, cpu_env, tmp); break;
5602 case 1: gen_helper_neon_qneg_s16(tmp, cpu_env, tmp); break;
5603 case 2: gen_helper_neon_qneg_s32(tmp, cpu_env, tmp); break;
5607 case 16: case 19: /* VCGT #0, VCLE #0 */
5608 tmp2 = tcg_const_i32(0);
5610 case 0: gen_helper_neon_cgt_s8(tmp, tmp, tmp2); break;
5611 case 1: gen_helper_neon_cgt_s16(tmp, tmp, tmp2); break;
5612 case 2: gen_helper_neon_cgt_s32(tmp, tmp, tmp2); break;
5615 tcg_temp_free(tmp2);
5617 tcg_gen_not_i32(tmp, tmp);
5619 case 17: case 20: /* VCGE #0, VCLT #0 */
5620 tmp2 = tcg_const_i32(0);
5622 case 0: gen_helper_neon_cge_s8(tmp, tmp, tmp2); break;
5623 case 1: gen_helper_neon_cge_s16(tmp, tmp, tmp2); break;
5624 case 2: gen_helper_neon_cge_s32(tmp, tmp, tmp2); break;
5627 tcg_temp_free(tmp2);
5629 tcg_gen_not_i32(tmp, tmp);
5631 case 18: /* VCEQ #0 */
5632 tmp2 = tcg_const_i32(0);
5634 case 0: gen_helper_neon_ceq_u8(tmp, tmp, tmp2); break;
5635 case 1: gen_helper_neon_ceq_u16(tmp, tmp, tmp2); break;
5636 case 2: gen_helper_neon_ceq_u32(tmp, tmp, tmp2); break;
5639 tcg_temp_free(tmp2);
5643 case 0: gen_helper_neon_abs_s8(tmp, tmp); break;
5644 case 1: gen_helper_neon_abs_s16(tmp, tmp); break;
5645 case 2: tcg_gen_abs_i32(tmp, tmp); break;
5652 tmp2 = tcg_const_i32(0);
5653 gen_neon_rsb(size, tmp, tmp2);
5654 tcg_temp_free(tmp2);
5656 case 24: case 27: /* Float VCGT #0, Float VCLE #0 */
5657 tmp2 = tcg_const_i32(0);
5658 gen_helper_neon_cgt_f32(tmp, tmp, tmp2);
5659 tcg_temp_free(tmp2);
5661 tcg_gen_not_i32(tmp, tmp);
5663 case 25: case 28: /* Float VCGE #0, Float VCLT #0 */
5664 tmp2 = tcg_const_i32(0);
5665 gen_helper_neon_cge_f32(tmp, tmp, tmp2);
5666 tcg_temp_free(tmp2);
5668 tcg_gen_not_i32(tmp, tmp);
5670 case 26: /* Float VCEQ #0 */
5671 tmp2 = tcg_const_i32(0);
5672 gen_helper_neon_ceq_f32(tmp, tmp, tmp2);
5673 tcg_temp_free(tmp2);
5675 case 30: /* Float VABS */
5678 case 31: /* Float VNEG */
5682 tmp2 = neon_load_reg(rd, pass);
5683 neon_store_reg(rm, pass, tmp2);
5686 tmp2 = neon_load_reg(rd, pass);
5688 case 0: gen_neon_trn_u8(tmp, tmp2); break;
5689 case 1: gen_neon_trn_u16(tmp, tmp2); break;
5693 neon_store_reg(rm, pass, tmp2);
5695 case 56: /* Integer VRECPE */
5696 gen_helper_recpe_u32(tmp, tmp, cpu_env);
5698 case 57: /* Integer VRSQRTE */
5699 gen_helper_rsqrte_u32(tmp, tmp, cpu_env);
5701 case 58: /* Float VRECPE */
5702 gen_helper_recpe_f32(cpu_F0s, cpu_F0s, cpu_env);
5704 case 59: /* Float VRSQRTE */
5705 gen_helper_rsqrte_f32(cpu_F0s, cpu_F0s, cpu_env);
5707 case 60: /* VCVT.F32.S32 */
5710 case 61: /* VCVT.F32.U32 */
5713 case 62: /* VCVT.S32.F32 */
5716 case 63: /* VCVT.U32.F32 */
5720 /* Reserved: 21, 29, 39-56 */
5723 if (op == 30 || op == 31 || op >= 58) {
5724 tcg_gen_st_f32(cpu_F0s, cpu_env,
5725 neon_reg_offset(rd, pass));
5727 neon_store_reg(rd, pass, tmp);
5732 } else if ((insn & (1 << 10)) == 0) {
5734 n = ((insn >> 5) & 0x18) + 8;
5735 if (insn & (1 << 6)) {
5736 tmp = neon_load_reg(rd, 0);
5739 tcg_gen_movi_i32(tmp, 0);
5741 tmp2 = neon_load_reg(rm, 0);
5742 tmp4 = tcg_const_i32(rn);
5743 tmp5 = tcg_const_i32(n);
5744 gen_helper_neon_tbl(tmp2, tmp2, tmp, tmp4, tmp5);
5746 if (insn & (1 << 6)) {
5747 tmp = neon_load_reg(rd, 1);
5750 tcg_gen_movi_i32(tmp, 0);
5752 tmp3 = neon_load_reg(rm, 1);
5753 gen_helper_neon_tbl(tmp3, tmp3, tmp, tmp4, tmp5);
5754 tcg_temp_free_i32(tmp5);
5755 tcg_temp_free_i32(tmp4);
5756 neon_store_reg(rd, 0, tmp2);
5757 neon_store_reg(rd, 1, tmp3);
5759 } else if ((insn & 0x380) == 0) {
5761 if (insn & (1 << 19)) {
5762 tmp = neon_load_reg(rm, 1);
5764 tmp = neon_load_reg(rm, 0);
5766 if (insn & (1 << 16)) {
5767 gen_neon_dup_u8(tmp, ((insn >> 17) & 3) * 8);
5768 } else if (insn & (1 << 17)) {
5769 if ((insn >> 18) & 1)
5770 gen_neon_dup_high16(tmp);
5772 gen_neon_dup_low16(tmp);
5774 for (pass = 0; pass < (q ? 4 : 2); pass++) {
5776 tcg_gen_mov_i32(tmp2, tmp);
5777 neon_store_reg(rd, pass, tmp2);
5788 static int disas_cp14_read(CPUState * env, DisasContext *s, uint32_t insn)
5790 int crn = (insn >> 16) & 0xf;
5791 int crm = insn & 0xf;
5792 int op1 = (insn >> 21) & 7;
5793 int op2 = (insn >> 5) & 7;
5794 int rt = (insn >> 12) & 0xf;
5797 if (arm_feature(env, ARM_FEATURE_THUMB2EE)) {
5798 if (op1 == 6 && crn == 0 && crm == 0 && op2 == 0) {
5802 tmp = load_cpu_field(teecr);
5803 store_reg(s, rt, tmp);
5806 if (op1 == 6 && crn == 1 && crm == 0 && op2 == 0) {
5808 if (IS_USER(s) && (env->teecr & 1))
5810 tmp = load_cpu_field(teehbr);
5811 store_reg(s, rt, tmp);
5815 fprintf(stderr, "Unknown cp14 read op1:%d crn:%d crm:%d op2:%d\n",
5816 op1, crn, crm, op2);
5820 static int disas_cp14_write(CPUState * env, DisasContext *s, uint32_t insn)
5822 int crn = (insn >> 16) & 0xf;
5823 int crm = insn & 0xf;
5824 int op1 = (insn >> 21) & 7;
5825 int op2 = (insn >> 5) & 7;
5826 int rt = (insn >> 12) & 0xf;
5829 if (arm_feature(env, ARM_FEATURE_THUMB2EE)) {
5830 if (op1 == 6 && crn == 0 && crm == 0 && op2 == 0) {
5834 tmp = load_reg(s, rt);
5835 gen_helper_set_teecr(cpu_env, tmp);
5839 if (op1 == 6 && crn == 1 && crm == 0 && op2 == 0) {
5841 if (IS_USER(s) && (env->teecr & 1))
5843 tmp = load_reg(s, rt);
5844 store_cpu_field(tmp, teehbr);
5848 fprintf(stderr, "Unknown cp14 write op1:%d crn:%d crm:%d op2:%d\n",
5849 op1, crn, crm, op2);
5853 static int disas_coproc_insn(CPUState * env, DisasContext *s, uint32_t insn)
5857 cpnum = (insn >> 8) & 0xf;
5858 if (arm_feature(env, ARM_FEATURE_XSCALE)
5859 && ((env->cp15.c15_cpar ^ 0x3fff) & (1 << cpnum)))
5865 if (arm_feature(env, ARM_FEATURE_IWMMXT)) {
5866 return disas_iwmmxt_insn(env, s, insn);
5867 } else if (arm_feature(env, ARM_FEATURE_XSCALE)) {
5868 return disas_dsp_insn(env, s, insn);
5873 return disas_vfp_insn (env, s, insn);
5875 /* Coprocessors 7-15 are architecturally reserved by ARM.
5876 Unfortunately Intel decided to ignore this. */
5877 if (arm_feature(env, ARM_FEATURE_XSCALE))
5879 if (insn & (1 << 20))
5880 return disas_cp14_read(env, s, insn);
5882 return disas_cp14_write(env, s, insn);
5884 return disas_cp15_insn (env, s, insn);
5887 /* Unknown coprocessor. See if the board has hooked it. */
5888 return disas_cp_insn (env, s, insn);
5893 /* Store a 64-bit value to a register pair. Clobbers val. */
5894 static void gen_storeq_reg(DisasContext *s, int rlow, int rhigh, TCGv_i64 val)
5898 tcg_gen_trunc_i64_i32(tmp, val);
5899 store_reg(s, rlow, tmp);
5901 tcg_gen_shri_i64(val, val, 32);
5902 tcg_gen_trunc_i64_i32(tmp, val);
5903 store_reg(s, rhigh, tmp);
5906 /* load a 32-bit value from a register and perform a 64-bit accumulate. */
5907 static void gen_addq_lo(DisasContext *s, TCGv_i64 val, int rlow)
5912 /* Load value and extend to 64 bits. */
5913 tmp = tcg_temp_new_i64();
5914 tmp2 = load_reg(s, rlow);
5915 tcg_gen_extu_i32_i64(tmp, tmp2);
5917 tcg_gen_add_i64(val, val, tmp);
5918 tcg_temp_free_i64(tmp);
5921 /* load and add a 64-bit value from a register pair. */
5922 static void gen_addq(DisasContext *s, TCGv_i64 val, int rlow, int rhigh)
5928 /* Load 64-bit value rd:rn. */
5929 tmpl = load_reg(s, rlow);
5930 tmph = load_reg(s, rhigh);
5931 tmp = tcg_temp_new_i64();
5932 tcg_gen_concat_i32_i64(tmp, tmpl, tmph);
5935 tcg_gen_add_i64(val, val, tmp);
5936 tcg_temp_free_i64(tmp);
5939 /* Set N and Z flags from a 64-bit value. */
5940 static void gen_logicq_cc(TCGv_i64 val)
5942 TCGv tmp = new_tmp();
5943 gen_helper_logicq_cc(tmp, val);
5948 /* Load/Store exclusive instructions are implemented by remembering
5949 the value/address loaded, and seeing if these are the same
5950 when the store is performed. This should be is sufficient to implement
5951 the architecturally mandated semantics, and avoids having to monitor
5954 In system emulation mode only one CPU will be running at once, so
5955 this sequence is effectively atomic. In user emulation mode we
5956 throw an exception and handle the atomic operation elsewhere. */
5957 static void gen_load_exclusive(DisasContext *s, int rt, int rt2,
5958 TCGv addr, int size)
5964 tmp = gen_ld8u(addr, IS_USER(s));
5967 tmp = gen_ld16u(addr, IS_USER(s));
5971 tmp = gen_ld32(addr, IS_USER(s));
5976 tcg_gen_mov_i32(cpu_exclusive_val, tmp);
5977 store_reg(s, rt, tmp);
5979 TCGv tmp2 = new_tmp();
5980 tcg_gen_addi_i32(tmp2, addr, 4);
5981 tmp = gen_ld32(tmp2, IS_USER(s));
5983 tcg_gen_mov_i32(cpu_exclusive_high, tmp);
5984 store_reg(s, rt2, tmp);
5986 tcg_gen_mov_i32(cpu_exclusive_addr, addr);
5989 static void gen_clrex(DisasContext *s)
5991 tcg_gen_movi_i32(cpu_exclusive_addr, -1);
5994 #ifdef CONFIG_USER_ONLY
5995 static void gen_store_exclusive(DisasContext *s, int rd, int rt, int rt2,
5996 TCGv addr, int size)
5998 tcg_gen_mov_i32(cpu_exclusive_test, addr);
5999 tcg_gen_movi_i32(cpu_exclusive_info,
6000 size | (rd << 4) | (rt << 8) | (rt2 << 12));
6001 gen_exception_insn(s, 4, EXCP_STREX);
6004 static void gen_store_exclusive(DisasContext *s, int rd, int rt, int rt2,
6005 TCGv addr, int size)
6011 /* if (env->exclusive_addr == addr && env->exclusive_val == [addr]) {
6017 fail_label = gen_new_label();
6018 done_label = gen_new_label();
6019 tcg_gen_brcond_i32(TCG_COND_NE, addr, cpu_exclusive_addr, fail_label);
6022 tmp = gen_ld8u(addr, IS_USER(s));
6025 tmp = gen_ld16u(addr, IS_USER(s));
6029 tmp = gen_ld32(addr, IS_USER(s));
6034 tcg_gen_brcond_i32(TCG_COND_NE, tmp, cpu_exclusive_val, fail_label);
6037 TCGv tmp2 = new_tmp();
6038 tcg_gen_addi_i32(tmp2, addr, 4);
6039 tmp = gen_ld32(tmp2, IS_USER(s));
6041 tcg_gen_brcond_i32(TCG_COND_NE, tmp, cpu_exclusive_high, fail_label);
6044 tmp = load_reg(s, rt);
6047 gen_st8(tmp, addr, IS_USER(s));
6050 gen_st16(tmp, addr, IS_USER(s));
6054 gen_st32(tmp, addr, IS_USER(s));
6060 tcg_gen_addi_i32(addr, addr, 4);
6061 tmp = load_reg(s, rt2);
6062 gen_st32(tmp, addr, IS_USER(s));
6064 tcg_gen_movi_i32(cpu_R[rd], 0);
6065 tcg_gen_br(done_label);
6066 gen_set_label(fail_label);
6067 tcg_gen_movi_i32(cpu_R[rd], 1);
6068 gen_set_label(done_label);
6069 tcg_gen_movi_i32(cpu_exclusive_addr, -1);
6073 static void disas_arm_insn(CPUState * env, DisasContext *s)
6075 unsigned int cond, insn, val, op1, i, shift, rm, rs, rn, rd, sh;
6082 insn = ldl_code(s->pc);
6085 /* M variants do not implement ARM mode. */
6090 /* Unconditional instructions. */
6091 if (((insn >> 25) & 7) == 1) {
6092 /* NEON Data processing. */
6093 if (!arm_feature(env, ARM_FEATURE_NEON))
6096 if (disas_neon_data_insn(env, s, insn))
6100 if ((insn & 0x0f100000) == 0x04000000) {
6101 /* NEON load/store. */
6102 if (!arm_feature(env, ARM_FEATURE_NEON))
6105 if (disas_neon_ls_insn(env, s, insn))
6109 if (((insn & 0x0f30f000) == 0x0510f000) ||
6110 ((insn & 0x0f30f010) == 0x0710f000)) {
6111 if ((insn & (1 << 22)) == 0) {
6113 if (!arm_feature(env, ARM_FEATURE_V7MP)) {
6117 /* Otherwise PLD; v5TE+ */
6120 if (((insn & 0x0f70f000) == 0x0450f000) ||
6121 ((insn & 0x0f70f010) == 0x0650f000)) {
6123 return; /* PLI; V7 */
6125 if (((insn & 0x0f700000) == 0x04100000) ||
6126 ((insn & 0x0f700010) == 0x06100000)) {
6127 if (!arm_feature(env, ARM_FEATURE_V7MP)) {
6130 return; /* v7MP: Unallocated memory hint: must NOP */
6133 if ((insn & 0x0ffffdff) == 0x01010000) {
6136 if (insn & (1 << 9)) {
6137 /* BE8 mode not implemented. */
6141 } else if ((insn & 0x0fffff00) == 0x057ff000) {
6142 switch ((insn >> 4) & 0xf) {
6151 /* We don't emulate caches so these are a no-op. */
6156 } else if ((insn & 0x0e5fffe0) == 0x084d0500) {
6162 op1 = (insn & 0x1f);
6164 tmp = tcg_const_i32(op1);
6165 gen_helper_get_r13_banked(addr, cpu_env, tmp);
6166 tcg_temp_free_i32(tmp);
6167 i = (insn >> 23) & 3;
6169 case 0: offset = -4; break; /* DA */
6170 case 1: offset = 0; break; /* IA */
6171 case 2: offset = -8; break; /* DB */
6172 case 3: offset = 4; break; /* IB */
6176 tcg_gen_addi_i32(addr, addr, offset);
6177 tmp = load_reg(s, 14);
6178 gen_st32(tmp, addr, 0);
6179 tmp = load_cpu_field(spsr);
6180 tcg_gen_addi_i32(addr, addr, 4);
6181 gen_st32(tmp, addr, 0);
6182 if (insn & (1 << 21)) {
6183 /* Base writeback. */
6185 case 0: offset = -8; break;
6186 case 1: offset = 4; break;
6187 case 2: offset = -4; break;
6188 case 3: offset = 0; break;
6192 tcg_gen_addi_i32(addr, addr, offset);
6193 tmp = tcg_const_i32(op1);
6194 gen_helper_set_r13_banked(cpu_env, tmp, addr);
6195 tcg_temp_free_i32(tmp);
6201 } else if ((insn & 0x0e50ffe0) == 0x08100a00) {
6207 rn = (insn >> 16) & 0xf;
6208 addr = load_reg(s, rn);
6209 i = (insn >> 23) & 3;
6211 case 0: offset = -4; break; /* DA */
6212 case 1: offset = 0; break; /* IA */
6213 case 2: offset = -8; break; /* DB */
6214 case 3: offset = 4; break; /* IB */
6218 tcg_gen_addi_i32(addr, addr, offset);
6219 /* Load PC into tmp and CPSR into tmp2. */
6220 tmp = gen_ld32(addr, 0);
6221 tcg_gen_addi_i32(addr, addr, 4);
6222 tmp2 = gen_ld32(addr, 0);
6223 if (insn & (1 << 21)) {
6224 /* Base writeback. */
6226 case 0: offset = -8; break;
6227 case 1: offset = 4; break;
6228 case 2: offset = -4; break;
6229 case 3: offset = 0; break;
6233 tcg_gen_addi_i32(addr, addr, offset);
6234 store_reg(s, rn, addr);
6238 gen_rfe(s, tmp, tmp2);
6240 } else if ((insn & 0x0e000000) == 0x0a000000) {
6241 /* branch link and change to thumb (blx <offset>) */
6244 val = (uint32_t)s->pc;
6246 tcg_gen_movi_i32(tmp, val);
6247 store_reg(s, 14, tmp);
6248 /* Sign-extend the 24-bit offset */
6249 offset = (((int32_t)insn) << 8) >> 8;
6250 /* offset * 4 + bit24 * 2 + (thumb bit) */
6251 val += (offset << 2) | ((insn >> 23) & 2) | 1;
6252 /* pipeline offset */
6256 } else if ((insn & 0x0e000f00) == 0x0c000100) {
6257 if (arm_feature(env, ARM_FEATURE_IWMMXT)) {
6258 /* iWMMXt register transfer. */
6259 if (env->cp15.c15_cpar & (1 << 1))
6260 if (!disas_iwmmxt_insn(env, s, insn))
6263 } else if ((insn & 0x0fe00000) == 0x0c400000) {
6264 /* Coprocessor double register transfer. */
6265 } else if ((insn & 0x0f000010) == 0x0e000010) {
6266 /* Additional coprocessor register transfer. */
6267 } else if ((insn & 0x0ff10020) == 0x01000000) {
6270 /* cps (privileged) */
6274 if (insn & (1 << 19)) {
6275 if (insn & (1 << 8))
6277 if (insn & (1 << 7))
6279 if (insn & (1 << 6))
6281 if (insn & (1 << 18))
6284 if (insn & (1 << 17)) {
6286 val |= (insn & 0x1f);
6289 gen_set_psr_im(s, mask, 0, val);
6296 /* if not always execute, we generate a conditional jump to
6298 s->condlabel = gen_new_label();
6299 gen_test_cc(cond ^ 1, s->condlabel);
6302 if ((insn & 0x0f900000) == 0x03000000) {
6303 if ((insn & (1 << 21)) == 0) {
6305 rd = (insn >> 12) & 0xf;
6306 val = ((insn >> 4) & 0xf000) | (insn & 0xfff);
6307 if ((insn & (1 << 22)) == 0) {
6310 tcg_gen_movi_i32(tmp, val);
6313 tmp = load_reg(s, rd);
6314 tcg_gen_ext16u_i32(tmp, tmp);
6315 tcg_gen_ori_i32(tmp, tmp, val << 16);
6317 store_reg(s, rd, tmp);
6319 if (((insn >> 12) & 0xf) != 0xf)
6321 if (((insn >> 16) & 0xf) == 0) {
6322 gen_nop_hint(s, insn & 0xff);
6324 /* CPSR = immediate */
6326 shift = ((insn >> 8) & 0xf) * 2;
6328 val = (val >> shift) | (val << (32 - shift));
6329 i = ((insn & (1 << 22)) != 0);
6330 if (gen_set_psr_im(s, msr_mask(env, s, (insn >> 16) & 0xf, i), i, val))
6334 } else if ((insn & 0x0f900000) == 0x01000000
6335 && (insn & 0x00000090) != 0x00000090) {
6336 /* miscellaneous instructions */
6337 op1 = (insn >> 21) & 3;
6338 sh = (insn >> 4) & 0xf;
6341 case 0x0: /* move program status register */
6344 tmp = load_reg(s, rm);
6345 i = ((op1 & 2) != 0);
6346 if (gen_set_psr(s, msr_mask(env, s, (insn >> 16) & 0xf, i), i, tmp))
6350 rd = (insn >> 12) & 0xf;
6354 tmp = load_cpu_field(spsr);
6357 gen_helper_cpsr_read(tmp);
6359 store_reg(s, rd, tmp);
6364 /* branch/exchange thumb (bx). */
6365 tmp = load_reg(s, rm);
6367 } else if (op1 == 3) {
6369 rd = (insn >> 12) & 0xf;
6370 tmp = load_reg(s, rm);
6371 gen_helper_clz(tmp, tmp);
6372 store_reg(s, rd, tmp);
6380 /* Trivial implementation equivalent to bx. */
6381 tmp = load_reg(s, rm);
6391 /* branch link/exchange thumb (blx) */
6392 tmp = load_reg(s, rm);
6394 tcg_gen_movi_i32(tmp2, s->pc);
6395 store_reg(s, 14, tmp2);
6398 case 0x5: /* saturating add/subtract */
6399 rd = (insn >> 12) & 0xf;
6400 rn = (insn >> 16) & 0xf;
6401 tmp = load_reg(s, rm);
6402 tmp2 = load_reg(s, rn);
6404 gen_helper_double_saturate(tmp2, tmp2);
6406 gen_helper_sub_saturate(tmp, tmp, tmp2);
6408 gen_helper_add_saturate(tmp, tmp, tmp2);
6410 store_reg(s, rd, tmp);
6413 /* SMC instruction (op1 == 3)
6414 and undefined instructions (op1 == 0 || op1 == 2)
6420 gen_exception_insn(s, 4, EXCP_BKPT);
6422 case 0x8: /* signed multiply */
6426 rs = (insn >> 8) & 0xf;
6427 rn = (insn >> 12) & 0xf;
6428 rd = (insn >> 16) & 0xf;
6430 /* (32 * 16) >> 16 */
6431 tmp = load_reg(s, rm);
6432 tmp2 = load_reg(s, rs);
6434 tcg_gen_sari_i32(tmp2, tmp2, 16);
6437 tmp64 = gen_muls_i64_i32(tmp, tmp2);
6438 tcg_gen_shri_i64(tmp64, tmp64, 16);
6440 tcg_gen_trunc_i64_i32(tmp, tmp64);
6441 tcg_temp_free_i64(tmp64);
6442 if ((sh & 2) == 0) {
6443 tmp2 = load_reg(s, rn);
6444 gen_helper_add_setq(tmp, tmp, tmp2);
6447 store_reg(s, rd, tmp);
6450 tmp = load_reg(s, rm);
6451 tmp2 = load_reg(s, rs);
6452 gen_mulxy(tmp, tmp2, sh & 2, sh & 4);
6455 tmp64 = tcg_temp_new_i64();
6456 tcg_gen_ext_i32_i64(tmp64, tmp);
6458 gen_addq(s, tmp64, rn, rd);
6459 gen_storeq_reg(s, rn, rd, tmp64);
6460 tcg_temp_free_i64(tmp64);
6463 tmp2 = load_reg(s, rn);
6464 gen_helper_add_setq(tmp, tmp, tmp2);
6467 store_reg(s, rd, tmp);
6474 } else if (((insn & 0x0e000000) == 0 &&
6475 (insn & 0x00000090) != 0x90) ||
6476 ((insn & 0x0e000000) == (1 << 25))) {
6477 int set_cc, logic_cc, shiftop;
6479 op1 = (insn >> 21) & 0xf;
6480 set_cc = (insn >> 20) & 1;
6481 logic_cc = table_logic_cc[op1] & set_cc;
6483 /* data processing instruction */
6484 if (insn & (1 << 25)) {
6485 /* immediate operand */
6487 shift = ((insn >> 8) & 0xf) * 2;
6489 val = (val >> shift) | (val << (32 - shift));
6492 tcg_gen_movi_i32(tmp2, val);
6493 if (logic_cc && shift) {
6494 gen_set_CF_bit31(tmp2);
6499 tmp2 = load_reg(s, rm);
6500 shiftop = (insn >> 5) & 3;
6501 if (!(insn & (1 << 4))) {
6502 shift = (insn >> 7) & 0x1f;
6503 gen_arm_shift_im(tmp2, shiftop, shift, logic_cc);
6505 rs = (insn >> 8) & 0xf;
6506 tmp = load_reg(s, rs);
6507 gen_arm_shift_reg(tmp2, shiftop, tmp, logic_cc);
6510 if (op1 != 0x0f && op1 != 0x0d) {
6511 rn = (insn >> 16) & 0xf;
6512 tmp = load_reg(s, rn);
6516 rd = (insn >> 12) & 0xf;
6519 tcg_gen_and_i32(tmp, tmp, tmp2);
6523 store_reg_bx(env, s, rd, tmp);
6526 tcg_gen_xor_i32(tmp, tmp, tmp2);
6530 store_reg_bx(env, s, rd, tmp);
6533 if (set_cc && rd == 15) {
6534 /* SUBS r15, ... is used for exception return. */
6538 gen_helper_sub_cc(tmp, tmp, tmp2);
6539 gen_exception_return(s, tmp);
6542 gen_helper_sub_cc(tmp, tmp, tmp2);
6544 tcg_gen_sub_i32(tmp, tmp, tmp2);
6546 store_reg_bx(env, s, rd, tmp);
6551 gen_helper_sub_cc(tmp, tmp2, tmp);
6553 tcg_gen_sub_i32(tmp, tmp2, tmp);
6555 store_reg_bx(env, s, rd, tmp);
6559 gen_helper_add_cc(tmp, tmp, tmp2);
6561 tcg_gen_add_i32(tmp, tmp, tmp2);
6563 store_reg_bx(env, s, rd, tmp);
6567 gen_helper_adc_cc(tmp, tmp, tmp2);
6569 gen_add_carry(tmp, tmp, tmp2);
6571 store_reg_bx(env, s, rd, tmp);
6575 gen_helper_sbc_cc(tmp, tmp, tmp2);
6577 gen_sub_carry(tmp, tmp, tmp2);
6579 store_reg_bx(env, s, rd, tmp);
6583 gen_helper_sbc_cc(tmp, tmp2, tmp);
6585 gen_sub_carry(tmp, tmp2, tmp);
6587 store_reg_bx(env, s, rd, tmp);
6591 tcg_gen_and_i32(tmp, tmp, tmp2);
6598 tcg_gen_xor_i32(tmp, tmp, tmp2);
6605 gen_helper_sub_cc(tmp, tmp, tmp2);
6611 gen_helper_add_cc(tmp, tmp, tmp2);
6616 tcg_gen_or_i32(tmp, tmp, tmp2);
6620 store_reg_bx(env, s, rd, tmp);
6623 if (logic_cc && rd == 15) {
6624 /* MOVS r15, ... is used for exception return. */
6628 gen_exception_return(s, tmp2);
6633 store_reg_bx(env, s, rd, tmp2);
6637 tcg_gen_andc_i32(tmp, tmp, tmp2);
6641 store_reg_bx(env, s, rd, tmp);
6645 tcg_gen_not_i32(tmp2, tmp2);
6649 store_reg_bx(env, s, rd, tmp2);
6652 if (op1 != 0x0f && op1 != 0x0d) {
6656 /* other instructions */
6657 op1 = (insn >> 24) & 0xf;
6661 /* multiplies, extra load/stores */
6662 sh = (insn >> 5) & 3;
6665 rd = (insn >> 16) & 0xf;
6666 rn = (insn >> 12) & 0xf;
6667 rs = (insn >> 8) & 0xf;
6669 op1 = (insn >> 20) & 0xf;
6671 case 0: case 1: case 2: case 3: case 6:
6673 tmp = load_reg(s, rs);
6674 tmp2 = load_reg(s, rm);
6675 tcg_gen_mul_i32(tmp, tmp, tmp2);
6677 if (insn & (1 << 22)) {
6678 /* Subtract (mls) */
6680 tmp2 = load_reg(s, rn);
6681 tcg_gen_sub_i32(tmp, tmp2, tmp);
6683 } else if (insn & (1 << 21)) {
6685 tmp2 = load_reg(s, rn);
6686 tcg_gen_add_i32(tmp, tmp, tmp2);
6689 if (insn & (1 << 20))
6691 store_reg(s, rd, tmp);
6694 /* 64 bit mul double accumulate (UMAAL) */
6696 tmp = load_reg(s, rs);
6697 tmp2 = load_reg(s, rm);
6698 tmp64 = gen_mulu_i64_i32(tmp, tmp2);
6699 gen_addq_lo(s, tmp64, rn);
6700 gen_addq_lo(s, tmp64, rd);
6701 gen_storeq_reg(s, rn, rd, tmp64);
6702 tcg_temp_free_i64(tmp64);
6704 case 8: case 9: case 10: case 11:
6705 case 12: case 13: case 14: case 15:
6706 /* 64 bit mul: UMULL, UMLAL, SMULL, SMLAL. */
6707 tmp = load_reg(s, rs);
6708 tmp2 = load_reg(s, rm);
6709 if (insn & (1 << 22)) {
6710 tmp64 = gen_muls_i64_i32(tmp, tmp2);
6712 tmp64 = gen_mulu_i64_i32(tmp, tmp2);
6714 if (insn & (1 << 21)) { /* mult accumulate */
6715 gen_addq(s, tmp64, rn, rd);
6717 if (insn & (1 << 20)) {
6718 gen_logicq_cc(tmp64);
6720 gen_storeq_reg(s, rn, rd, tmp64);
6721 tcg_temp_free_i64(tmp64);
6727 rn = (insn >> 16) & 0xf;
6728 rd = (insn >> 12) & 0xf;
6729 if (insn & (1 << 23)) {
6730 /* load/store exclusive */
6731 op1 = (insn >> 21) & 0x3;
6736 addr = tcg_temp_local_new_i32();
6737 load_reg_var(s, addr, rn);
6738 if (insn & (1 << 20)) {
6741 gen_load_exclusive(s, rd, 15, addr, 2);
6743 case 1: /* ldrexd */
6744 gen_load_exclusive(s, rd, rd + 1, addr, 3);
6746 case 2: /* ldrexb */
6747 gen_load_exclusive(s, rd, 15, addr, 0);
6749 case 3: /* ldrexh */
6750 gen_load_exclusive(s, rd, 15, addr, 1);
6759 gen_store_exclusive(s, rd, rm, 15, addr, 2);
6761 case 1: /* strexd */
6762 gen_store_exclusive(s, rd, rm, rm + 1, addr, 3);
6764 case 2: /* strexb */
6765 gen_store_exclusive(s, rd, rm, 15, addr, 0);
6767 case 3: /* strexh */
6768 gen_store_exclusive(s, rd, rm, 15, addr, 1);
6774 tcg_temp_free(addr);
6776 /* SWP instruction */
6779 /* ??? This is not really atomic. However we know
6780 we never have multiple CPUs running in parallel,
6781 so it is good enough. */
6782 addr = load_reg(s, rn);
6783 tmp = load_reg(s, rm);
6784 if (insn & (1 << 22)) {
6785 tmp2 = gen_ld8u(addr, IS_USER(s));
6786 gen_st8(tmp, addr, IS_USER(s));
6788 tmp2 = gen_ld32(addr, IS_USER(s));
6789 gen_st32(tmp, addr, IS_USER(s));
6792 store_reg(s, rd, tmp2);
6798 /* Misc load/store */
6799 rn = (insn >> 16) & 0xf;
6800 rd = (insn >> 12) & 0xf;
6801 addr = load_reg(s, rn);
6802 if (insn & (1 << 24))
6803 gen_add_datah_offset(s, insn, 0, addr);
6805 if (insn & (1 << 20)) {
6809 tmp = gen_ld16u(addr, IS_USER(s));
6812 tmp = gen_ld8s(addr, IS_USER(s));
6816 tmp = gen_ld16s(addr, IS_USER(s));
6820 } else if (sh & 2) {
6824 tmp = load_reg(s, rd);
6825 gen_st32(tmp, addr, IS_USER(s));
6826 tcg_gen_addi_i32(addr, addr, 4);
6827 tmp = load_reg(s, rd + 1);
6828 gen_st32(tmp, addr, IS_USER(s));
6832 tmp = gen_ld32(addr, IS_USER(s));
6833 store_reg(s, rd, tmp);
6834 tcg_gen_addi_i32(addr, addr, 4);
6835 tmp = gen_ld32(addr, IS_USER(s));
6839 address_offset = -4;
6842 tmp = load_reg(s, rd);
6843 gen_st16(tmp, addr, IS_USER(s));
6846 /* Perform base writeback before the loaded value to
6847 ensure correct behavior with overlapping index registers.
6848 ldrd with base writeback is is undefined if the
6849 destination and index registers overlap. */
6850 if (!(insn & (1 << 24))) {
6851 gen_add_datah_offset(s, insn, address_offset, addr);
6852 store_reg(s, rn, addr);
6853 } else if (insn & (1 << 21)) {
6855 tcg_gen_addi_i32(addr, addr, address_offset);
6856 store_reg(s, rn, addr);
6861 /* Complete the load. */
6862 store_reg(s, rd, tmp);
6871 if (insn & (1 << 4)) {
6873 /* Armv6 Media instructions. */
6875 rn = (insn >> 16) & 0xf;
6876 rd = (insn >> 12) & 0xf;
6877 rs = (insn >> 8) & 0xf;
6878 switch ((insn >> 23) & 3) {
6879 case 0: /* Parallel add/subtract. */
6880 op1 = (insn >> 20) & 7;
6881 tmp = load_reg(s, rn);
6882 tmp2 = load_reg(s, rm);
6883 sh = (insn >> 5) & 7;
6884 if ((op1 & 3) == 0 || sh == 5 || sh == 6)
6886 gen_arm_parallel_addsub(op1, sh, tmp, tmp2);
6888 store_reg(s, rd, tmp);
6891 if ((insn & 0x00700020) == 0) {
6892 /* Halfword pack. */
6893 tmp = load_reg(s, rn);
6894 tmp2 = load_reg(s, rm);
6895 shift = (insn >> 7) & 0x1f;
6896 if (insn & (1 << 6)) {
6900 tcg_gen_sari_i32(tmp2, tmp2, shift);
6901 tcg_gen_andi_i32(tmp, tmp, 0xffff0000);
6902 tcg_gen_ext16u_i32(tmp2, tmp2);
6906 tcg_gen_shli_i32(tmp2, tmp2, shift);
6907 tcg_gen_ext16u_i32(tmp, tmp);
6908 tcg_gen_andi_i32(tmp2, tmp2, 0xffff0000);
6910 tcg_gen_or_i32(tmp, tmp, tmp2);
6912 store_reg(s, rd, tmp);
6913 } else if ((insn & 0x00200020) == 0x00200000) {
6915 tmp = load_reg(s, rm);
6916 shift = (insn >> 7) & 0x1f;
6917 if (insn & (1 << 6)) {
6920 tcg_gen_sari_i32(tmp, tmp, shift);
6922 tcg_gen_shli_i32(tmp, tmp, shift);
6924 sh = (insn >> 16) & 0x1f;
6925 tmp2 = tcg_const_i32(sh);
6926 if (insn & (1 << 22))
6927 gen_helper_usat(tmp, tmp, tmp2);
6929 gen_helper_ssat(tmp, tmp, tmp2);
6930 tcg_temp_free_i32(tmp2);
6931 store_reg(s, rd, tmp);
6932 } else if ((insn & 0x00300fe0) == 0x00200f20) {
6934 tmp = load_reg(s, rm);
6935 sh = (insn >> 16) & 0x1f;
6936 tmp2 = tcg_const_i32(sh);
6937 if (insn & (1 << 22))
6938 gen_helper_usat16(tmp, tmp, tmp2);
6940 gen_helper_ssat16(tmp, tmp, tmp2);
6941 tcg_temp_free_i32(tmp2);
6942 store_reg(s, rd, tmp);
6943 } else if ((insn & 0x00700fe0) == 0x00000fa0) {
6945 tmp = load_reg(s, rn);
6946 tmp2 = load_reg(s, rm);
6948 tcg_gen_ld_i32(tmp3, cpu_env, offsetof(CPUState, GE));
6949 gen_helper_sel_flags(tmp, tmp3, tmp, tmp2);
6952 store_reg(s, rd, tmp);
6953 } else if ((insn & 0x000003e0) == 0x00000060) {
6954 tmp = load_reg(s, rm);
6955 shift = (insn >> 10) & 3;
6956 /* ??? In many cases it's not neccessary to do a
6957 rotate, a shift is sufficient. */
6959 tcg_gen_rotri_i32(tmp, tmp, shift * 8);
6960 op1 = (insn >> 20) & 7;
6962 case 0: gen_sxtb16(tmp); break;
6963 case 2: gen_sxtb(tmp); break;
6964 case 3: gen_sxth(tmp); break;
6965 case 4: gen_uxtb16(tmp); break;
6966 case 6: gen_uxtb(tmp); break;
6967 case 7: gen_uxth(tmp); break;
6968 default: goto illegal_op;
6971 tmp2 = load_reg(s, rn);
6972 if ((op1 & 3) == 0) {
6973 gen_add16(tmp, tmp2);
6975 tcg_gen_add_i32(tmp, tmp, tmp2);
6979 store_reg(s, rd, tmp);
6980 } else if ((insn & 0x003f0f60) == 0x003f0f20) {
6982 tmp = load_reg(s, rm);
6983 if (insn & (1 << 22)) {
6984 if (insn & (1 << 7)) {
6988 gen_helper_rbit(tmp, tmp);
6991 if (insn & (1 << 7))
6994 tcg_gen_bswap32_i32(tmp, tmp);
6996 store_reg(s, rd, tmp);
7001 case 2: /* Multiplies (Type 3). */
7002 tmp = load_reg(s, rm);
7003 tmp2 = load_reg(s, rs);
7004 if (insn & (1 << 20)) {
7005 /* Signed multiply most significant [accumulate].
7006 (SMMUL, SMMLA, SMMLS) */
7007 tmp64 = gen_muls_i64_i32(tmp, tmp2);
7010 tmp = load_reg(s, rd);
7011 if (insn & (1 << 6)) {
7012 tmp64 = gen_subq_msw(tmp64, tmp);
7014 tmp64 = gen_addq_msw(tmp64, tmp);
7017 if (insn & (1 << 5)) {
7018 tcg_gen_addi_i64(tmp64, tmp64, 0x80000000u);
7020 tcg_gen_shri_i64(tmp64, tmp64, 32);
7022 tcg_gen_trunc_i64_i32(tmp, tmp64);
7023 tcg_temp_free_i64(tmp64);
7024 store_reg(s, rn, tmp);
7026 if (insn & (1 << 5))
7027 gen_swap_half(tmp2);
7028 gen_smul_dual(tmp, tmp2);
7029 /* This addition cannot overflow. */
7030 if (insn & (1 << 6)) {
7031 tcg_gen_sub_i32(tmp, tmp, tmp2);
7033 tcg_gen_add_i32(tmp, tmp, tmp2);
7036 if (insn & (1 << 22)) {
7037 /* smlald, smlsld */
7038 tmp64 = tcg_temp_new_i64();
7039 tcg_gen_ext_i32_i64(tmp64, tmp);
7041 gen_addq(s, tmp64, rd, rn);
7042 gen_storeq_reg(s, rd, rn, tmp64);
7043 tcg_temp_free_i64(tmp64);
7045 /* smuad, smusd, smlad, smlsd */
7048 tmp2 = load_reg(s, rd);
7049 gen_helper_add_setq(tmp, tmp, tmp2);
7052 store_reg(s, rn, tmp);
7057 op1 = ((insn >> 17) & 0x38) | ((insn >> 5) & 7);
7059 case 0: /* Unsigned sum of absolute differences. */
7061 tmp = load_reg(s, rm);
7062 tmp2 = load_reg(s, rs);
7063 gen_helper_usad8(tmp, tmp, tmp2);
7066 tmp2 = load_reg(s, rd);
7067 tcg_gen_add_i32(tmp, tmp, tmp2);
7070 store_reg(s, rn, tmp);
7072 case 0x20: case 0x24: case 0x28: case 0x2c:
7073 /* Bitfield insert/clear. */
7075 shift = (insn >> 7) & 0x1f;
7076 i = (insn >> 16) & 0x1f;
7080 tcg_gen_movi_i32(tmp, 0);
7082 tmp = load_reg(s, rm);
7085 tmp2 = load_reg(s, rd);
7086 gen_bfi(tmp, tmp2, tmp, shift, (1u << i) - 1);
7089 store_reg(s, rd, tmp);
7091 case 0x12: case 0x16: case 0x1a: case 0x1e: /* sbfx */
7092 case 0x32: case 0x36: case 0x3a: case 0x3e: /* ubfx */
7094 tmp = load_reg(s, rm);
7095 shift = (insn >> 7) & 0x1f;
7096 i = ((insn >> 16) & 0x1f) + 1;
7101 gen_ubfx(tmp, shift, (1u << i) - 1);
7103 gen_sbfx(tmp, shift, i);
7106 store_reg(s, rd, tmp);
7116 /* Check for undefined extension instructions
7117 * per the ARM Bible IE:
7118 * xxxx 0111 1111 xxxx xxxx xxxx 1111 xxxx
7120 sh = (0xf << 20) | (0xf << 4);
7121 if (op1 == 0x7 && ((insn & sh) == sh))
7125 /* load/store byte/word */
7126 rn = (insn >> 16) & 0xf;
7127 rd = (insn >> 12) & 0xf;
7128 tmp2 = load_reg(s, rn);
7129 i = (IS_USER(s) || (insn & 0x01200000) == 0x00200000);
7130 if (insn & (1 << 24))
7131 gen_add_data_offset(s, insn, tmp2);
7132 if (insn & (1 << 20)) {
7134 if (insn & (1 << 22)) {
7135 tmp = gen_ld8u(tmp2, i);
7137 tmp = gen_ld32(tmp2, i);
7141 tmp = load_reg(s, rd);
7142 if (insn & (1 << 22))
7143 gen_st8(tmp, tmp2, i);
7145 gen_st32(tmp, tmp2, i);
7147 if (!(insn & (1 << 24))) {
7148 gen_add_data_offset(s, insn, tmp2);
7149 store_reg(s, rn, tmp2);
7150 } else if (insn & (1 << 21)) {
7151 store_reg(s, rn, tmp2);
7155 if (insn & (1 << 20)) {
7156 /* Complete the load. */
7160 store_reg(s, rd, tmp);
7166 int j, n, user, loaded_base;
7168 /* load/store multiple words */
7169 /* XXX: store correct base if write back */
7171 if (insn & (1 << 22)) {
7173 goto illegal_op; /* only usable in supervisor mode */
7175 if ((insn & (1 << 15)) == 0)
7178 rn = (insn >> 16) & 0xf;
7179 addr = load_reg(s, rn);
7181 /* compute total size */
7183 TCGV_UNUSED(loaded_var);
7186 if (insn & (1 << i))
7189 /* XXX: test invalid n == 0 case ? */
7190 if (insn & (1 << 23)) {
7191 if (insn & (1 << 24)) {
7193 tcg_gen_addi_i32(addr, addr, 4);
7195 /* post increment */
7198 if (insn & (1 << 24)) {
7200 tcg_gen_addi_i32(addr, addr, -(n * 4));
7202 /* post decrement */
7204 tcg_gen_addi_i32(addr, addr, -((n - 1) * 4));
7209 if (insn & (1 << i)) {
7210 if (insn & (1 << 20)) {
7212 tmp = gen_ld32(addr, IS_USER(s));
7216 tmp2 = tcg_const_i32(i);
7217 gen_helper_set_user_reg(tmp2, tmp);
7218 tcg_temp_free_i32(tmp2);
7220 } else if (i == rn) {
7224 store_reg(s, i, tmp);
7229 /* special case: r15 = PC + 8 */
7230 val = (long)s->pc + 4;
7232 tcg_gen_movi_i32(tmp, val);
7235 tmp2 = tcg_const_i32(i);
7236 gen_helper_get_user_reg(tmp, tmp2);
7237 tcg_temp_free_i32(tmp2);
7239 tmp = load_reg(s, i);
7241 gen_st32(tmp, addr, IS_USER(s));
7244 /* no need to add after the last transfer */
7246 tcg_gen_addi_i32(addr, addr, 4);
7249 if (insn & (1 << 21)) {
7251 if (insn & (1 << 23)) {
7252 if (insn & (1 << 24)) {
7255 /* post increment */
7256 tcg_gen_addi_i32(addr, addr, 4);
7259 if (insn & (1 << 24)) {
7262 tcg_gen_addi_i32(addr, addr, -((n - 1) * 4));
7264 /* post decrement */
7265 tcg_gen_addi_i32(addr, addr, -(n * 4));
7268 store_reg(s, rn, addr);
7273 store_reg(s, rn, loaded_var);
7275 if ((insn & (1 << 22)) && !user) {
7276 /* Restore CPSR from SPSR. */
7277 tmp = load_cpu_field(spsr);
7278 gen_set_cpsr(tmp, 0xffffffff);
7280 s->is_jmp = DISAS_UPDATE;
7289 /* branch (and link) */
7290 val = (int32_t)s->pc;
7291 if (insn & (1 << 24)) {
7293 tcg_gen_movi_i32(tmp, val);
7294 store_reg(s, 14, tmp);
7296 offset = (((int32_t)insn << 8) >> 8);
7297 val += (offset << 2) + 4;
7305 if (disas_coproc_insn(env, s, insn))
7310 gen_set_pc_im(s->pc);
7311 s->is_jmp = DISAS_SWI;
7315 gen_exception_insn(s, 4, EXCP_UDEF);
7321 /* Return true if this is a Thumb-2 logical op. */
7323 thumb2_logic_op(int op)
7328 /* Generate code for a Thumb-2 data processing operation. If CONDS is nonzero
7329 then set condition code flags based on the result of the operation.
7330 If SHIFTER_OUT is nonzero then set the carry flag for logical operations
7331 to the high bit of T1.
7332 Returns zero if the opcode is valid. */
7335 gen_thumb2_data_op(DisasContext *s, int op, int conds, uint32_t shifter_out, TCGv t0, TCGv t1)
7342 tcg_gen_and_i32(t0, t0, t1);
7346 tcg_gen_andc_i32(t0, t0, t1);
7350 tcg_gen_or_i32(t0, t0, t1);
7354 tcg_gen_not_i32(t1, t1);
7355 tcg_gen_or_i32(t0, t0, t1);
7359 tcg_gen_xor_i32(t0, t0, t1);
7364 gen_helper_add_cc(t0, t0, t1);
7366 tcg_gen_add_i32(t0, t0, t1);
7370 gen_helper_adc_cc(t0, t0, t1);
7376 gen_helper_sbc_cc(t0, t0, t1);
7378 gen_sub_carry(t0, t0, t1);
7382 gen_helper_sub_cc(t0, t0, t1);
7384 tcg_gen_sub_i32(t0, t0, t1);
7388 gen_helper_sub_cc(t0, t1, t0);
7390 tcg_gen_sub_i32(t0, t1, t0);
7392 default: /* 5, 6, 7, 9, 12, 15. */
7398 gen_set_CF_bit31(t1);
7403 /* Translate a 32-bit thumb instruction. Returns nonzero if the instruction
7405 static int disas_thumb2_insn(CPUState *env, DisasContext *s, uint16_t insn_hw1)
7407 uint32_t insn, imm, shift, offset;
7408 uint32_t rd, rn, rm, rs;
7419 if (!(arm_feature(env, ARM_FEATURE_THUMB2)
7420 || arm_feature (env, ARM_FEATURE_M))) {
7421 /* Thumb-1 cores may need to treat bl and blx as a pair of
7422 16-bit instructions to get correct prefetch abort behavior. */
7424 if ((insn & (1 << 12)) == 0) {
7425 /* Second half of blx. */
7426 offset = ((insn & 0x7ff) << 1);
7427 tmp = load_reg(s, 14);
7428 tcg_gen_addi_i32(tmp, tmp, offset);
7429 tcg_gen_andi_i32(tmp, tmp, 0xfffffffc);
7432 tcg_gen_movi_i32(tmp2, s->pc | 1);
7433 store_reg(s, 14, tmp2);
7437 if (insn & (1 << 11)) {
7438 /* Second half of bl. */
7439 offset = ((insn & 0x7ff) << 1) | 1;
7440 tmp = load_reg(s, 14);
7441 tcg_gen_addi_i32(tmp, tmp, offset);
7444 tcg_gen_movi_i32(tmp2, s->pc | 1);
7445 store_reg(s, 14, tmp2);
7449 if ((s->pc & ~TARGET_PAGE_MASK) == 0) {
7450 /* Instruction spans a page boundary. Implement it as two
7451 16-bit instructions in case the second half causes an
7453 offset = ((int32_t)insn << 21) >> 9;
7454 tcg_gen_movi_i32(cpu_R[14], s->pc + 2 + offset);
7457 /* Fall through to 32-bit decode. */
7460 insn = lduw_code(s->pc);
7462 insn |= (uint32_t)insn_hw1 << 16;
7464 if ((insn & 0xf800e800) != 0xf000e800) {
7468 rn = (insn >> 16) & 0xf;
7469 rs = (insn >> 12) & 0xf;
7470 rd = (insn >> 8) & 0xf;
7472 switch ((insn >> 25) & 0xf) {
7473 case 0: case 1: case 2: case 3:
7474 /* 16-bit instructions. Should never happen. */
7477 if (insn & (1 << 22)) {
7478 /* Other load/store, table branch. */
7479 if (insn & 0x01200000) {
7480 /* Load/store doubleword. */
7483 tcg_gen_movi_i32(addr, s->pc & ~3);
7485 addr = load_reg(s, rn);
7487 offset = (insn & 0xff) * 4;
7488 if ((insn & (1 << 23)) == 0)
7490 if (insn & (1 << 24)) {
7491 tcg_gen_addi_i32(addr, addr, offset);
7494 if (insn & (1 << 20)) {
7496 tmp = gen_ld32(addr, IS_USER(s));
7497 store_reg(s, rs, tmp);
7498 tcg_gen_addi_i32(addr, addr, 4);
7499 tmp = gen_ld32(addr, IS_USER(s));
7500 store_reg(s, rd, tmp);
7503 tmp = load_reg(s, rs);
7504 gen_st32(tmp, addr, IS_USER(s));
7505 tcg_gen_addi_i32(addr, addr, 4);
7506 tmp = load_reg(s, rd);
7507 gen_st32(tmp, addr, IS_USER(s));
7509 if (insn & (1 << 21)) {
7510 /* Base writeback. */
7513 tcg_gen_addi_i32(addr, addr, offset - 4);
7514 store_reg(s, rn, addr);
7518 } else if ((insn & (1 << 23)) == 0) {
7519 /* Load/store exclusive word. */
7520 addr = tcg_temp_local_new();
7521 load_reg_var(s, addr, rn);
7522 tcg_gen_addi_i32(addr, addr, (insn & 0xff) << 2);
7523 if (insn & (1 << 20)) {
7524 gen_load_exclusive(s, rs, 15, addr, 2);
7526 gen_store_exclusive(s, rd, rs, 15, addr, 2);
7528 tcg_temp_free(addr);
7529 } else if ((insn & (1 << 6)) == 0) {
7533 tcg_gen_movi_i32(addr, s->pc);
7535 addr = load_reg(s, rn);
7537 tmp = load_reg(s, rm);
7538 tcg_gen_add_i32(addr, addr, tmp);
7539 if (insn & (1 << 4)) {
7541 tcg_gen_add_i32(addr, addr, tmp);
7543 tmp = gen_ld16u(addr, IS_USER(s));
7546 tmp = gen_ld8u(addr, IS_USER(s));
7549 tcg_gen_shli_i32(tmp, tmp, 1);
7550 tcg_gen_addi_i32(tmp, tmp, s->pc);
7551 store_reg(s, 15, tmp);
7553 /* Load/store exclusive byte/halfword/doubleword. */
7555 op = (insn >> 4) & 0x3;
7559 addr = tcg_temp_local_new();
7560 load_reg_var(s, addr, rn);
7561 if (insn & (1 << 20)) {
7562 gen_load_exclusive(s, rs, rd, addr, op);
7564 gen_store_exclusive(s, rm, rs, rd, addr, op);
7566 tcg_temp_free(addr);
7569 /* Load/store multiple, RFE, SRS. */
7570 if (((insn >> 23) & 1) == ((insn >> 24) & 1)) {
7571 /* Not available in user mode. */
7574 if (insn & (1 << 20)) {
7576 addr = load_reg(s, rn);
7577 if ((insn & (1 << 24)) == 0)
7578 tcg_gen_addi_i32(addr, addr, -8);
7579 /* Load PC into tmp and CPSR into tmp2. */
7580 tmp = gen_ld32(addr, 0);
7581 tcg_gen_addi_i32(addr, addr, 4);
7582 tmp2 = gen_ld32(addr, 0);
7583 if (insn & (1 << 21)) {
7584 /* Base writeback. */
7585 if (insn & (1 << 24)) {
7586 tcg_gen_addi_i32(addr, addr, 4);
7588 tcg_gen_addi_i32(addr, addr, -4);
7590 store_reg(s, rn, addr);
7594 gen_rfe(s, tmp, tmp2);
7599 tmp = tcg_const_i32(op);
7600 gen_helper_get_r13_banked(addr, cpu_env, tmp);
7601 tcg_temp_free_i32(tmp);
7602 if ((insn & (1 << 24)) == 0) {
7603 tcg_gen_addi_i32(addr, addr, -8);
7605 tmp = load_reg(s, 14);
7606 gen_st32(tmp, addr, 0);
7607 tcg_gen_addi_i32(addr, addr, 4);
7609 gen_helper_cpsr_read(tmp);
7610 gen_st32(tmp, addr, 0);
7611 if (insn & (1 << 21)) {
7612 if ((insn & (1 << 24)) == 0) {
7613 tcg_gen_addi_i32(addr, addr, -4);
7615 tcg_gen_addi_i32(addr, addr, 4);
7617 tmp = tcg_const_i32(op);
7618 gen_helper_set_r13_banked(cpu_env, tmp, addr);
7619 tcg_temp_free_i32(tmp);
7626 /* Load/store multiple. */
7627 addr = load_reg(s, rn);
7629 for (i = 0; i < 16; i++) {
7630 if (insn & (1 << i))
7633 if (insn & (1 << 24)) {
7634 tcg_gen_addi_i32(addr, addr, -offset);
7637 for (i = 0; i < 16; i++) {
7638 if ((insn & (1 << i)) == 0)
7640 if (insn & (1 << 20)) {
7642 tmp = gen_ld32(addr, IS_USER(s));
7646 store_reg(s, i, tmp);
7650 tmp = load_reg(s, i);
7651 gen_st32(tmp, addr, IS_USER(s));
7653 tcg_gen_addi_i32(addr, addr, 4);
7655 if (insn & (1 << 21)) {
7656 /* Base register writeback. */
7657 if (insn & (1 << 24)) {
7658 tcg_gen_addi_i32(addr, addr, -offset);
7660 /* Fault if writeback register is in register list. */
7661 if (insn & (1 << rn))
7663 store_reg(s, rn, addr);
7672 op = (insn >> 21) & 0xf;
7674 /* Halfword pack. */
7675 tmp = load_reg(s, rn);
7676 tmp2 = load_reg(s, rm);
7677 shift = ((insn >> 10) & 0x1c) | ((insn >> 6) & 0x3);
7678 if (insn & (1 << 5)) {
7682 tcg_gen_sari_i32(tmp2, tmp2, shift);
7683 tcg_gen_andi_i32(tmp, tmp, 0xffff0000);
7684 tcg_gen_ext16u_i32(tmp2, tmp2);
7688 tcg_gen_shli_i32(tmp2, tmp2, shift);
7689 tcg_gen_ext16u_i32(tmp, tmp);
7690 tcg_gen_andi_i32(tmp2, tmp2, 0xffff0000);
7692 tcg_gen_or_i32(tmp, tmp, tmp2);
7694 store_reg(s, rd, tmp);
7696 /* Data processing register constant shift. */
7699 tcg_gen_movi_i32(tmp, 0);
7701 tmp = load_reg(s, rn);
7703 tmp2 = load_reg(s, rm);
7705 shiftop = (insn >> 4) & 3;
7706 shift = ((insn >> 6) & 3) | ((insn >> 10) & 0x1c);
7707 conds = (insn & (1 << 20)) != 0;
7708 logic_cc = (conds && thumb2_logic_op(op));
7709 gen_arm_shift_im(tmp2, shiftop, shift, logic_cc);
7710 if (gen_thumb2_data_op(s, op, conds, 0, tmp, tmp2))
7714 store_reg(s, rd, tmp);
7720 case 13: /* Misc data processing. */
7721 op = ((insn >> 22) & 6) | ((insn >> 7) & 1);
7722 if (op < 4 && (insn & 0xf000) != 0xf000)
7725 case 0: /* Register controlled shift. */
7726 tmp = load_reg(s, rn);
7727 tmp2 = load_reg(s, rm);
7728 if ((insn & 0x70) != 0)
7730 op = (insn >> 21) & 3;
7731 logic_cc = (insn & (1 << 20)) != 0;
7732 gen_arm_shift_reg(tmp, op, tmp2, logic_cc);
7735 store_reg_bx(env, s, rd, tmp);
7737 case 1: /* Sign/zero extend. */
7738 tmp = load_reg(s, rm);
7739 shift = (insn >> 4) & 3;
7740 /* ??? In many cases it's not neccessary to do a
7741 rotate, a shift is sufficient. */
7743 tcg_gen_rotri_i32(tmp, tmp, shift * 8);
7744 op = (insn >> 20) & 7;
7746 case 0: gen_sxth(tmp); break;
7747 case 1: gen_uxth(tmp); break;
7748 case 2: gen_sxtb16(tmp); break;
7749 case 3: gen_uxtb16(tmp); break;
7750 case 4: gen_sxtb(tmp); break;
7751 case 5: gen_uxtb(tmp); break;
7752 default: goto illegal_op;
7755 tmp2 = load_reg(s, rn);
7756 if ((op >> 1) == 1) {
7757 gen_add16(tmp, tmp2);
7759 tcg_gen_add_i32(tmp, tmp, tmp2);
7763 store_reg(s, rd, tmp);
7765 case 2: /* SIMD add/subtract. */
7766 op = (insn >> 20) & 7;
7767 shift = (insn >> 4) & 7;
7768 if ((op & 3) == 3 || (shift & 3) == 3)
7770 tmp = load_reg(s, rn);
7771 tmp2 = load_reg(s, rm);
7772 gen_thumb2_parallel_addsub(op, shift, tmp, tmp2);
7774 store_reg(s, rd, tmp);
7776 case 3: /* Other data processing. */
7777 op = ((insn >> 17) & 0x38) | ((insn >> 4) & 7);
7779 /* Saturating add/subtract. */
7780 tmp = load_reg(s, rn);
7781 tmp2 = load_reg(s, rm);
7783 gen_helper_double_saturate(tmp, tmp);
7785 gen_helper_sub_saturate(tmp, tmp2, tmp);
7787 gen_helper_add_saturate(tmp, tmp, tmp2);
7790 tmp = load_reg(s, rn);
7792 case 0x0a: /* rbit */
7793 gen_helper_rbit(tmp, tmp);
7795 case 0x08: /* rev */
7796 tcg_gen_bswap32_i32(tmp, tmp);
7798 case 0x09: /* rev16 */
7801 case 0x0b: /* revsh */
7804 case 0x10: /* sel */
7805 tmp2 = load_reg(s, rm);
7807 tcg_gen_ld_i32(tmp3, cpu_env, offsetof(CPUState, GE));
7808 gen_helper_sel_flags(tmp, tmp3, tmp, tmp2);
7812 case 0x18: /* clz */
7813 gen_helper_clz(tmp, tmp);
7819 store_reg(s, rd, tmp);
7821 case 4: case 5: /* 32-bit multiply. Sum of absolute differences. */
7822 op = (insn >> 4) & 0xf;
7823 tmp = load_reg(s, rn);
7824 tmp2 = load_reg(s, rm);
7825 switch ((insn >> 20) & 7) {
7826 case 0: /* 32 x 32 -> 32 */
7827 tcg_gen_mul_i32(tmp, tmp, tmp2);
7830 tmp2 = load_reg(s, rs);
7832 tcg_gen_sub_i32(tmp, tmp2, tmp);
7834 tcg_gen_add_i32(tmp, tmp, tmp2);
7838 case 1: /* 16 x 16 -> 32 */
7839 gen_mulxy(tmp, tmp2, op & 2, op & 1);
7842 tmp2 = load_reg(s, rs);
7843 gen_helper_add_setq(tmp, tmp, tmp2);
7847 case 2: /* Dual multiply add. */
7848 case 4: /* Dual multiply subtract. */
7850 gen_swap_half(tmp2);
7851 gen_smul_dual(tmp, tmp2);
7852 /* This addition cannot overflow. */
7853 if (insn & (1 << 22)) {
7854 tcg_gen_sub_i32(tmp, tmp, tmp2);
7856 tcg_gen_add_i32(tmp, tmp, tmp2);
7861 tmp2 = load_reg(s, rs);
7862 gen_helper_add_setq(tmp, tmp, tmp2);
7866 case 3: /* 32 * 16 -> 32msb */
7868 tcg_gen_sari_i32(tmp2, tmp2, 16);
7871 tmp64 = gen_muls_i64_i32(tmp, tmp2);
7872 tcg_gen_shri_i64(tmp64, tmp64, 16);
7874 tcg_gen_trunc_i64_i32(tmp, tmp64);
7875 tcg_temp_free_i64(tmp64);
7878 tmp2 = load_reg(s, rs);
7879 gen_helper_add_setq(tmp, tmp, tmp2);
7883 case 5: case 6: /* 32 * 32 -> 32msb (SMMUL, SMMLA, SMMLS) */
7884 tmp64 = gen_muls_i64_i32(tmp, tmp2);
7886 tmp = load_reg(s, rs);
7887 if (insn & (1 << 20)) {
7888 tmp64 = gen_addq_msw(tmp64, tmp);
7890 tmp64 = gen_subq_msw(tmp64, tmp);
7893 if (insn & (1 << 4)) {
7894 tcg_gen_addi_i64(tmp64, tmp64, 0x80000000u);
7896 tcg_gen_shri_i64(tmp64, tmp64, 32);
7898 tcg_gen_trunc_i64_i32(tmp, tmp64);
7899 tcg_temp_free_i64(tmp64);
7901 case 7: /* Unsigned sum of absolute differences. */
7902 gen_helper_usad8(tmp, tmp, tmp2);
7905 tmp2 = load_reg(s, rs);
7906 tcg_gen_add_i32(tmp, tmp, tmp2);
7911 store_reg(s, rd, tmp);
7913 case 6: case 7: /* 64-bit multiply, Divide. */
7914 op = ((insn >> 4) & 0xf) | ((insn >> 16) & 0x70);
7915 tmp = load_reg(s, rn);
7916 tmp2 = load_reg(s, rm);
7917 if ((op & 0x50) == 0x10) {
7919 if (!arm_feature(env, ARM_FEATURE_DIV))
7922 gen_helper_udiv(tmp, tmp, tmp2);
7924 gen_helper_sdiv(tmp, tmp, tmp2);
7926 store_reg(s, rd, tmp);
7927 } else if ((op & 0xe) == 0xc) {
7928 /* Dual multiply accumulate long. */
7930 gen_swap_half(tmp2);
7931 gen_smul_dual(tmp, tmp2);
7933 tcg_gen_sub_i32(tmp, tmp, tmp2);
7935 tcg_gen_add_i32(tmp, tmp, tmp2);
7939 tmp64 = tcg_temp_new_i64();
7940 tcg_gen_ext_i32_i64(tmp64, tmp);
7942 gen_addq(s, tmp64, rs, rd);
7943 gen_storeq_reg(s, rs, rd, tmp64);
7944 tcg_temp_free_i64(tmp64);
7947 /* Unsigned 64-bit multiply */
7948 tmp64 = gen_mulu_i64_i32(tmp, tmp2);
7952 gen_mulxy(tmp, tmp2, op & 2, op & 1);
7954 tmp64 = tcg_temp_new_i64();
7955 tcg_gen_ext_i32_i64(tmp64, tmp);
7958 /* Signed 64-bit multiply */
7959 tmp64 = gen_muls_i64_i32(tmp, tmp2);
7964 gen_addq_lo(s, tmp64, rs);
7965 gen_addq_lo(s, tmp64, rd);
7966 } else if (op & 0x40) {
7967 /* 64-bit accumulate. */
7968 gen_addq(s, tmp64, rs, rd);
7970 gen_storeq_reg(s, rs, rd, tmp64);
7971 tcg_temp_free_i64(tmp64);
7976 case 6: case 7: case 14: case 15:
7978 if (((insn >> 24) & 3) == 3) {
7979 /* Translate into the equivalent ARM encoding. */
7980 insn = (insn & 0xe2ffffff) | ((insn & (1 << 28)) >> 4) | (1 << 28);
7981 if (disas_neon_data_insn(env, s, insn))
7984 if (insn & (1 << 28))
7986 if (disas_coproc_insn (env, s, insn))
7990 case 8: case 9: case 10: case 11:
7991 if (insn & (1 << 15)) {
7992 /* Branches, misc control. */
7993 if (insn & 0x5000) {
7994 /* Unconditional branch. */
7995 /* signextend(hw1[10:0]) -> offset[:12]. */
7996 offset = ((int32_t)insn << 5) >> 9 & ~(int32_t)0xfff;
7997 /* hw1[10:0] -> offset[11:1]. */
7998 offset |= (insn & 0x7ff) << 1;
7999 /* (~hw2[13, 11] ^ offset[24]) -> offset[23,22]
8000 offset[24:22] already have the same value because of the
8001 sign extension above. */
8002 offset ^= ((~insn) & (1 << 13)) << 10;
8003 offset ^= ((~insn) & (1 << 11)) << 11;
8005 if (insn & (1 << 14)) {
8006 /* Branch and link. */
8007 tcg_gen_movi_i32(cpu_R[14], s->pc | 1);
8011 if (insn & (1 << 12)) {
8016 offset &= ~(uint32_t)2;
8017 gen_bx_im(s, offset);
8019 } else if (((insn >> 23) & 7) == 7) {
8021 if (insn & (1 << 13))
8024 if (insn & (1 << 26)) {
8025 /* Secure monitor call (v6Z) */
8026 goto illegal_op; /* not implemented. */
8028 op = (insn >> 20) & 7;
8030 case 0: /* msr cpsr. */
8032 tmp = load_reg(s, rn);
8033 addr = tcg_const_i32(insn & 0xff);
8034 gen_helper_v7m_msr(cpu_env, addr, tmp);
8035 tcg_temp_free_i32(addr);
8041 case 1: /* msr spsr. */
8044 tmp = load_reg(s, rn);
8046 msr_mask(env, s, (insn >> 8) & 0xf, op == 1),
8050 case 2: /* cps, nop-hint. */
8051 if (((insn >> 8) & 7) == 0) {
8052 gen_nop_hint(s, insn & 0xff);
8054 /* Implemented as NOP in user mode. */
8059 if (insn & (1 << 10)) {
8060 if (insn & (1 << 7))
8062 if (insn & (1 << 6))
8064 if (insn & (1 << 5))
8066 if (insn & (1 << 9))
8067 imm = CPSR_A | CPSR_I | CPSR_F;
8069 if (insn & (1 << 8)) {
8071 imm |= (insn & 0x1f);
8074 gen_set_psr_im(s, offset, 0, imm);
8077 case 3: /* Special control operations. */
8079 op = (insn >> 4) & 0xf;
8087 /* These execute as NOPs. */
8094 /* Trivial implementation equivalent to bx. */
8095 tmp = load_reg(s, rn);
8098 case 5: /* Exception return. */
8102 if (rn != 14 || rd != 15) {
8105 tmp = load_reg(s, rn);
8106 tcg_gen_subi_i32(tmp, tmp, insn & 0xff);
8107 gen_exception_return(s, tmp);
8109 case 6: /* mrs cpsr. */
8112 addr = tcg_const_i32(insn & 0xff);
8113 gen_helper_v7m_mrs(tmp, cpu_env, addr);
8114 tcg_temp_free_i32(addr);
8116 gen_helper_cpsr_read(tmp);
8118 store_reg(s, rd, tmp);
8120 case 7: /* mrs spsr. */
8121 /* Not accessible in user mode. */
8122 if (IS_USER(s) || IS_M(env))
8124 tmp = load_cpu_field(spsr);
8125 store_reg(s, rd, tmp);
8130 /* Conditional branch. */
8131 op = (insn >> 22) & 0xf;
8132 /* Generate a conditional jump to next instruction. */
8133 s->condlabel = gen_new_label();
8134 gen_test_cc(op ^ 1, s->condlabel);
8137 /* offset[11:1] = insn[10:0] */
8138 offset = (insn & 0x7ff) << 1;
8139 /* offset[17:12] = insn[21:16]. */
8140 offset |= (insn & 0x003f0000) >> 4;
8141 /* offset[31:20] = insn[26]. */
8142 offset |= ((int32_t)((insn << 5) & 0x80000000)) >> 11;
8143 /* offset[18] = insn[13]. */
8144 offset |= (insn & (1 << 13)) << 5;
8145 /* offset[19] = insn[11]. */
8146 offset |= (insn & (1 << 11)) << 8;
8148 /* jump to the offset */
8149 gen_jmp(s, s->pc + offset);
8152 /* Data processing immediate. */
8153 if (insn & (1 << 25)) {
8154 if (insn & (1 << 24)) {
8155 if (insn & (1 << 20))
8157 /* Bitfield/Saturate. */
8158 op = (insn >> 21) & 7;
8160 shift = ((insn >> 6) & 3) | ((insn >> 10) & 0x1c);
8163 tcg_gen_movi_i32(tmp, 0);
8165 tmp = load_reg(s, rn);
8168 case 2: /* Signed bitfield extract. */
8170 if (shift + imm > 32)
8173 gen_sbfx(tmp, shift, imm);
8175 case 6: /* Unsigned bitfield extract. */
8177 if (shift + imm > 32)
8180 gen_ubfx(tmp, shift, (1u << imm) - 1);
8182 case 3: /* Bitfield insert/clear. */
8185 imm = imm + 1 - shift;
8187 tmp2 = load_reg(s, rd);
8188 gen_bfi(tmp, tmp2, tmp, shift, (1u << imm) - 1);
8194 default: /* Saturate. */
8197 tcg_gen_sari_i32(tmp, tmp, shift);
8199 tcg_gen_shli_i32(tmp, tmp, shift);
8201 tmp2 = tcg_const_i32(imm);
8204 if ((op & 1) && shift == 0)
8205 gen_helper_usat16(tmp, tmp, tmp2);
8207 gen_helper_usat(tmp, tmp, tmp2);
8210 if ((op & 1) && shift == 0)
8211 gen_helper_ssat16(tmp, tmp, tmp2);
8213 gen_helper_ssat(tmp, tmp, tmp2);
8215 tcg_temp_free_i32(tmp2);
8218 store_reg(s, rd, tmp);
8220 imm = ((insn & 0x04000000) >> 15)
8221 | ((insn & 0x7000) >> 4) | (insn & 0xff);
8222 if (insn & (1 << 22)) {
8223 /* 16-bit immediate. */
8224 imm |= (insn >> 4) & 0xf000;
8225 if (insn & (1 << 23)) {
8227 tmp = load_reg(s, rd);
8228 tcg_gen_ext16u_i32(tmp, tmp);
8229 tcg_gen_ori_i32(tmp, tmp, imm << 16);
8233 tcg_gen_movi_i32(tmp, imm);
8236 /* Add/sub 12-bit immediate. */
8238 offset = s->pc & ~(uint32_t)3;
8239 if (insn & (1 << 23))
8244 tcg_gen_movi_i32(tmp, offset);
8246 tmp = load_reg(s, rn);
8247 if (insn & (1 << 23))
8248 tcg_gen_subi_i32(tmp, tmp, imm);
8250 tcg_gen_addi_i32(tmp, tmp, imm);
8253 store_reg(s, rd, tmp);
8256 int shifter_out = 0;
8257 /* modified 12-bit immediate. */
8258 shift = ((insn & 0x04000000) >> 23) | ((insn & 0x7000) >> 12);
8259 imm = (insn & 0xff);
8262 /* Nothing to do. */
8264 case 1: /* 00XY00XY */
8267 case 2: /* XY00XY00 */
8271 case 3: /* XYXYXYXY */
8275 default: /* Rotated constant. */
8276 shift = (shift << 1) | (imm >> 7);
8278 imm = imm << (32 - shift);
8283 tcg_gen_movi_i32(tmp2, imm);
8284 rn = (insn >> 16) & 0xf;
8287 tcg_gen_movi_i32(tmp, 0);
8289 tmp = load_reg(s, rn);
8291 op = (insn >> 21) & 0xf;
8292 if (gen_thumb2_data_op(s, op, (insn & (1 << 20)) != 0,
8293 shifter_out, tmp, tmp2))
8296 rd = (insn >> 8) & 0xf;
8298 store_reg(s, rd, tmp);
8305 case 12: /* Load/store single data item. */
8310 if ((insn & 0x01100000) == 0x01000000) {
8311 if (disas_neon_ls_insn(env, s, insn))
8315 op = ((insn >> 21) & 3) | ((insn >> 22) & 4);
8317 if (!(insn & (1 << 20))) {
8321 /* Byte or halfword load space with dest == r15 : memory hints.
8322 * Catch them early so we don't emit pointless addressing code.
8323 * This space is a mix of:
8324 * PLD/PLDW/PLI, which we implement as NOPs (note that unlike
8325 * the ARM encodings, PLDW space doesn't UNDEF for non-v7MP
8327 * unallocated hints, which must be treated as NOPs
8328 * UNPREDICTABLE space, which we NOP or UNDEF depending on
8329 * which is easiest for the decoding logic
8330 * Some space which must UNDEF
8332 int op1 = (insn >> 23) & 3;
8333 int op2 = (insn >> 6) & 0x3f;
8338 /* UNPREDICTABLE or unallocated hint */
8342 return 0; /* PLD* or unallocated hint */
8344 if ((op2 == 0) || ((op2 & 0x3c) == 0x30)) {
8345 return 0; /* PLD* or unallocated hint */
8347 /* UNDEF space, or an UNPREDICTABLE */
8355 /* s->pc has already been incremented by 4. */
8356 imm = s->pc & 0xfffffffc;
8357 if (insn & (1 << 23))
8358 imm += insn & 0xfff;
8360 imm -= insn & 0xfff;
8361 tcg_gen_movi_i32(addr, imm);
8363 addr = load_reg(s, rn);
8364 if (insn & (1 << 23)) {
8365 /* Positive offset. */
8367 tcg_gen_addi_i32(addr, addr, imm);
8370 switch ((insn >> 8) & 7) {
8371 case 0: case 8: /* Shifted Register. */
8372 shift = (insn >> 4) & 0xf;
8375 tmp = load_reg(s, rm);
8377 tcg_gen_shli_i32(tmp, tmp, shift);
8378 tcg_gen_add_i32(addr, addr, tmp);
8381 case 4: /* Negative offset. */
8382 tcg_gen_addi_i32(addr, addr, -imm);
8384 case 6: /* User privilege. */
8385 tcg_gen_addi_i32(addr, addr, imm);
8388 case 1: /* Post-decrement. */
8391 case 3: /* Post-increment. */
8395 case 5: /* Pre-decrement. */
8398 case 7: /* Pre-increment. */
8399 tcg_gen_addi_i32(addr, addr, imm);
8407 if (insn & (1 << 20)) {
8410 case 0: tmp = gen_ld8u(addr, user); break;
8411 case 4: tmp = gen_ld8s(addr, user); break;
8412 case 1: tmp = gen_ld16u(addr, user); break;
8413 case 5: tmp = gen_ld16s(addr, user); break;
8414 case 2: tmp = gen_ld32(addr, user); break;
8415 default: goto illegal_op;
8420 store_reg(s, rs, tmp);
8424 tmp = load_reg(s, rs);
8426 case 0: gen_st8(tmp, addr, user); break;
8427 case 1: gen_st16(tmp, addr, user); break;
8428 case 2: gen_st32(tmp, addr, user); break;
8429 default: goto illegal_op;
8433 tcg_gen_addi_i32(addr, addr, imm);
8435 store_reg(s, rn, addr);
8449 static void disas_thumb_insn(CPUState *env, DisasContext *s)
8451 uint32_t val, insn, op, rm, rn, rd, shift, cond;
8458 if (s->condexec_mask) {
8459 cond = s->condexec_cond;
8460 if (cond != 0x0e) { /* Skip conditional when condition is AL. */
8461 s->condlabel = gen_new_label();
8462 gen_test_cc(cond ^ 1, s->condlabel);
8467 insn = lduw_code(s->pc);
8470 switch (insn >> 12) {
8474 op = (insn >> 11) & 3;
8477 rn = (insn >> 3) & 7;
8478 tmp = load_reg(s, rn);
8479 if (insn & (1 << 10)) {
8482 tcg_gen_movi_i32(tmp2, (insn >> 6) & 7);
8485 rm = (insn >> 6) & 7;
8486 tmp2 = load_reg(s, rm);
8488 if (insn & (1 << 9)) {
8489 if (s->condexec_mask)
8490 tcg_gen_sub_i32(tmp, tmp, tmp2);
8492 gen_helper_sub_cc(tmp, tmp, tmp2);
8494 if (s->condexec_mask)
8495 tcg_gen_add_i32(tmp, tmp, tmp2);
8497 gen_helper_add_cc(tmp, tmp, tmp2);
8500 store_reg(s, rd, tmp);
8502 /* shift immediate */
8503 rm = (insn >> 3) & 7;
8504 shift = (insn >> 6) & 0x1f;
8505 tmp = load_reg(s, rm);
8506 gen_arm_shift_im(tmp, op, shift, s->condexec_mask == 0);
8507 if (!s->condexec_mask)
8509 store_reg(s, rd, tmp);
8513 /* arithmetic large immediate */
8514 op = (insn >> 11) & 3;
8515 rd = (insn >> 8) & 0x7;
8516 if (op == 0) { /* mov */
8518 tcg_gen_movi_i32(tmp, insn & 0xff);
8519 if (!s->condexec_mask)
8521 store_reg(s, rd, tmp);
8523 tmp = load_reg(s, rd);
8525 tcg_gen_movi_i32(tmp2, insn & 0xff);
8528 gen_helper_sub_cc(tmp, tmp, tmp2);
8533 if (s->condexec_mask)
8534 tcg_gen_add_i32(tmp, tmp, tmp2);
8536 gen_helper_add_cc(tmp, tmp, tmp2);
8538 store_reg(s, rd, tmp);
8541 if (s->condexec_mask)
8542 tcg_gen_sub_i32(tmp, tmp, tmp2);
8544 gen_helper_sub_cc(tmp, tmp, tmp2);
8546 store_reg(s, rd, tmp);
8552 if (insn & (1 << 11)) {
8553 rd = (insn >> 8) & 7;
8554 /* load pc-relative. Bit 1 of PC is ignored. */
8555 val = s->pc + 2 + ((insn & 0xff) * 4);
8556 val &= ~(uint32_t)2;
8558 tcg_gen_movi_i32(addr, val);
8559 tmp = gen_ld32(addr, IS_USER(s));
8561 store_reg(s, rd, tmp);
8564 if (insn & (1 << 10)) {
8565 /* data processing extended or blx */
8566 rd = (insn & 7) | ((insn >> 4) & 8);
8567 rm = (insn >> 3) & 0xf;
8568 op = (insn >> 8) & 3;
8571 tmp = load_reg(s, rd);
8572 tmp2 = load_reg(s, rm);
8573 tcg_gen_add_i32(tmp, tmp, tmp2);
8575 store_reg(s, rd, tmp);
8578 tmp = load_reg(s, rd);
8579 tmp2 = load_reg(s, rm);
8580 gen_helper_sub_cc(tmp, tmp, tmp2);
8584 case 2: /* mov/cpy */
8585 tmp = load_reg(s, rm);
8586 store_reg(s, rd, tmp);
8588 case 3:/* branch [and link] exchange thumb register */
8589 tmp = load_reg(s, rm);
8590 if (insn & (1 << 7)) {
8591 val = (uint32_t)s->pc | 1;
8593 tcg_gen_movi_i32(tmp2, val);
8594 store_reg(s, 14, tmp2);
8602 /* data processing register */
8604 rm = (insn >> 3) & 7;
8605 op = (insn >> 6) & 0xf;
8606 if (op == 2 || op == 3 || op == 4 || op == 7) {
8607 /* the shift/rotate ops want the operands backwards */
8616 if (op == 9) { /* neg */
8618 tcg_gen_movi_i32(tmp, 0);
8619 } else if (op != 0xf) { /* mvn doesn't read its first operand */
8620 tmp = load_reg(s, rd);
8625 tmp2 = load_reg(s, rm);
8628 tcg_gen_and_i32(tmp, tmp, tmp2);
8629 if (!s->condexec_mask)
8633 tcg_gen_xor_i32(tmp, tmp, tmp2);
8634 if (!s->condexec_mask)
8638 if (s->condexec_mask) {
8639 gen_helper_shl(tmp2, tmp2, tmp);
8641 gen_helper_shl_cc(tmp2, tmp2, tmp);
8646 if (s->condexec_mask) {
8647 gen_helper_shr(tmp2, tmp2, tmp);
8649 gen_helper_shr_cc(tmp2, tmp2, tmp);
8654 if (s->condexec_mask) {
8655 gen_helper_sar(tmp2, tmp2, tmp);
8657 gen_helper_sar_cc(tmp2, tmp2, tmp);
8662 if (s->condexec_mask)
8665 gen_helper_adc_cc(tmp, tmp, tmp2);
8668 if (s->condexec_mask)
8669 gen_sub_carry(tmp, tmp, tmp2);
8671 gen_helper_sbc_cc(tmp, tmp, tmp2);
8674 if (s->condexec_mask) {
8675 tcg_gen_andi_i32(tmp, tmp, 0x1f);
8676 tcg_gen_rotr_i32(tmp2, tmp2, tmp);
8678 gen_helper_ror_cc(tmp2, tmp2, tmp);
8683 tcg_gen_and_i32(tmp, tmp, tmp2);
8688 if (s->condexec_mask)
8689 tcg_gen_neg_i32(tmp, tmp2);
8691 gen_helper_sub_cc(tmp, tmp, tmp2);
8694 gen_helper_sub_cc(tmp, tmp, tmp2);
8698 gen_helper_add_cc(tmp, tmp, tmp2);
8702 tcg_gen_or_i32(tmp, tmp, tmp2);
8703 if (!s->condexec_mask)
8707 tcg_gen_mul_i32(tmp, tmp, tmp2);
8708 if (!s->condexec_mask)
8712 tcg_gen_andc_i32(tmp, tmp, tmp2);
8713 if (!s->condexec_mask)
8717 tcg_gen_not_i32(tmp2, tmp2);
8718 if (!s->condexec_mask)
8726 store_reg(s, rm, tmp2);
8730 store_reg(s, rd, tmp);
8740 /* load/store register offset. */
8742 rn = (insn >> 3) & 7;
8743 rm = (insn >> 6) & 7;
8744 op = (insn >> 9) & 7;
8745 addr = load_reg(s, rn);
8746 tmp = load_reg(s, rm);
8747 tcg_gen_add_i32(addr, addr, tmp);
8750 if (op < 3) /* store */
8751 tmp = load_reg(s, rd);
8755 gen_st32(tmp, addr, IS_USER(s));
8758 gen_st16(tmp, addr, IS_USER(s));
8761 gen_st8(tmp, addr, IS_USER(s));
8764 tmp = gen_ld8s(addr, IS_USER(s));
8767 tmp = gen_ld32(addr, IS_USER(s));
8770 tmp = gen_ld16u(addr, IS_USER(s));
8773 tmp = gen_ld8u(addr, IS_USER(s));
8776 tmp = gen_ld16s(addr, IS_USER(s));
8779 if (op >= 3) /* load */
8780 store_reg(s, rd, tmp);
8785 /* load/store word immediate offset */
8787 rn = (insn >> 3) & 7;
8788 addr = load_reg(s, rn);
8789 val = (insn >> 4) & 0x7c;
8790 tcg_gen_addi_i32(addr, addr, val);
8792 if (insn & (1 << 11)) {
8794 tmp = gen_ld32(addr, IS_USER(s));
8795 store_reg(s, rd, tmp);
8798 tmp = load_reg(s, rd);
8799 gen_st32(tmp, addr, IS_USER(s));
8805 /* load/store byte immediate offset */
8807 rn = (insn >> 3) & 7;
8808 addr = load_reg(s, rn);
8809 val = (insn >> 6) & 0x1f;
8810 tcg_gen_addi_i32(addr, addr, val);
8812 if (insn & (1 << 11)) {
8814 tmp = gen_ld8u(addr, IS_USER(s));
8815 store_reg(s, rd, tmp);
8818 tmp = load_reg(s, rd);
8819 gen_st8(tmp, addr, IS_USER(s));
8825 /* load/store halfword immediate offset */
8827 rn = (insn >> 3) & 7;
8828 addr = load_reg(s, rn);
8829 val = (insn >> 5) & 0x3e;
8830 tcg_gen_addi_i32(addr, addr, val);
8832 if (insn & (1 << 11)) {
8834 tmp = gen_ld16u(addr, IS_USER(s));
8835 store_reg(s, rd, tmp);
8838 tmp = load_reg(s, rd);
8839 gen_st16(tmp, addr, IS_USER(s));
8845 /* load/store from stack */
8846 rd = (insn >> 8) & 7;
8847 addr = load_reg(s, 13);
8848 val = (insn & 0xff) * 4;
8849 tcg_gen_addi_i32(addr, addr, val);
8851 if (insn & (1 << 11)) {
8853 tmp = gen_ld32(addr, IS_USER(s));
8854 store_reg(s, rd, tmp);
8857 tmp = load_reg(s, rd);
8858 gen_st32(tmp, addr, IS_USER(s));
8864 /* add to high reg */
8865 rd = (insn >> 8) & 7;
8866 if (insn & (1 << 11)) {
8868 tmp = load_reg(s, 13);
8870 /* PC. bit 1 is ignored. */
8872 tcg_gen_movi_i32(tmp, (s->pc + 2) & ~(uint32_t)2);
8874 val = (insn & 0xff) * 4;
8875 tcg_gen_addi_i32(tmp, tmp, val);
8876 store_reg(s, rd, tmp);
8881 op = (insn >> 8) & 0xf;
8884 /* adjust stack pointer */
8885 tmp = load_reg(s, 13);
8886 val = (insn & 0x7f) * 4;
8887 if (insn & (1 << 7))
8888 val = -(int32_t)val;
8889 tcg_gen_addi_i32(tmp, tmp, val);
8890 store_reg(s, 13, tmp);
8893 case 2: /* sign/zero extend. */
8896 rm = (insn >> 3) & 7;
8897 tmp = load_reg(s, rm);
8898 switch ((insn >> 6) & 3) {
8899 case 0: gen_sxth(tmp); break;
8900 case 1: gen_sxtb(tmp); break;
8901 case 2: gen_uxth(tmp); break;
8902 case 3: gen_uxtb(tmp); break;
8904 store_reg(s, rd, tmp);
8906 case 4: case 5: case 0xc: case 0xd:
8908 addr = load_reg(s, 13);
8909 if (insn & (1 << 8))
8913 for (i = 0; i < 8; i++) {
8914 if (insn & (1 << i))
8917 if ((insn & (1 << 11)) == 0) {
8918 tcg_gen_addi_i32(addr, addr, -offset);
8920 for (i = 0; i < 8; i++) {
8921 if (insn & (1 << i)) {
8922 if (insn & (1 << 11)) {
8924 tmp = gen_ld32(addr, IS_USER(s));
8925 store_reg(s, i, tmp);
8928 tmp = load_reg(s, i);
8929 gen_st32(tmp, addr, IS_USER(s));
8931 /* advance to the next address. */
8932 tcg_gen_addi_i32(addr, addr, 4);
8936 if (insn & (1 << 8)) {
8937 if (insn & (1 << 11)) {
8939 tmp = gen_ld32(addr, IS_USER(s));
8940 /* don't set the pc until the rest of the instruction
8944 tmp = load_reg(s, 14);
8945 gen_st32(tmp, addr, IS_USER(s));
8947 tcg_gen_addi_i32(addr, addr, 4);
8949 if ((insn & (1 << 11)) == 0) {
8950 tcg_gen_addi_i32(addr, addr, -offset);
8952 /* write back the new stack pointer */
8953 store_reg(s, 13, addr);
8954 /* set the new PC value */
8955 if ((insn & 0x0900) == 0x0900)
8959 case 1: case 3: case 9: case 11: /* czb */
8961 tmp = load_reg(s, rm);
8962 s->condlabel = gen_new_label();
8964 if (insn & (1 << 11))
8965 tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 0, s->condlabel);
8967 tcg_gen_brcondi_i32(TCG_COND_NE, tmp, 0, s->condlabel);
8969 offset = ((insn & 0xf8) >> 2) | (insn & 0x200) >> 3;
8970 val = (uint32_t)s->pc + 2;
8975 case 15: /* IT, nop-hint. */
8976 if ((insn & 0xf) == 0) {
8977 gen_nop_hint(s, (insn >> 4) & 0xf);
8981 s->condexec_cond = (insn >> 4) & 0xe;
8982 s->condexec_mask = insn & 0x1f;
8983 /* No actual code generated for this insn, just setup state. */
8986 case 0xe: /* bkpt */
8987 gen_exception_insn(s, 2, EXCP_BKPT);
8992 rn = (insn >> 3) & 0x7;
8994 tmp = load_reg(s, rn);
8995 switch ((insn >> 6) & 3) {
8996 case 0: tcg_gen_bswap32_i32(tmp, tmp); break;
8997 case 1: gen_rev16(tmp); break;
8998 case 3: gen_revsh(tmp); break;
8999 default: goto illegal_op;
9001 store_reg(s, rd, tmp);
9009 tmp = tcg_const_i32((insn & (1 << 4)) != 0);
9012 addr = tcg_const_i32(16);
9013 gen_helper_v7m_msr(cpu_env, addr, tmp);
9014 tcg_temp_free_i32(addr);
9018 addr = tcg_const_i32(17);
9019 gen_helper_v7m_msr(cpu_env, addr, tmp);
9020 tcg_temp_free_i32(addr);
9022 tcg_temp_free_i32(tmp);
9025 if (insn & (1 << 4))
9026 shift = CPSR_A | CPSR_I | CPSR_F;
9029 gen_set_psr_im(s, ((insn & 7) << 6), 0, shift);
9039 /* load/store multiple */
9040 rn = (insn >> 8) & 0x7;
9041 addr = load_reg(s, rn);
9042 for (i = 0; i < 8; i++) {
9043 if (insn & (1 << i)) {
9044 if (insn & (1 << 11)) {
9046 tmp = gen_ld32(addr, IS_USER(s));
9047 store_reg(s, i, tmp);
9050 tmp = load_reg(s, i);
9051 gen_st32(tmp, addr, IS_USER(s));
9053 /* advance to the next address */
9054 tcg_gen_addi_i32(addr, addr, 4);
9057 /* Base register writeback. */
9058 if ((insn & (1 << rn)) == 0) {
9059 store_reg(s, rn, addr);
9066 /* conditional branch or swi */
9067 cond = (insn >> 8) & 0xf;
9073 gen_set_pc_im(s->pc);
9074 s->is_jmp = DISAS_SWI;
9077 /* generate a conditional jump to next instruction */
9078 s->condlabel = gen_new_label();
9079 gen_test_cc(cond ^ 1, s->condlabel);
9082 /* jump to the offset */
9083 val = (uint32_t)s->pc + 2;
9084 offset = ((int32_t)insn << 24) >> 24;
9090 if (insn & (1 << 11)) {
9091 if (disas_thumb2_insn(env, s, insn))
9095 /* unconditional branch */
9096 val = (uint32_t)s->pc;
9097 offset = ((int32_t)insn << 21) >> 21;
9098 val += (offset << 1) + 2;
9103 if (disas_thumb2_insn(env, s, insn))
9109 gen_exception_insn(s, 4, EXCP_UDEF);
9113 gen_exception_insn(s, 2, EXCP_UDEF);
9116 /* generate intermediate code in gen_opc_buf and gen_opparam_buf for
9117 basic block 'tb'. If search_pc is TRUE, also generate PC
9118 information for each intermediate instruction. */
9119 static inline void gen_intermediate_code_internal(CPUState *env,
9120 TranslationBlock *tb,
9123 DisasContext dc1, *dc = &dc1;
9125 uint16_t *gen_opc_end;
9127 target_ulong pc_start;
9128 uint32_t next_page_start;
9132 /* generate intermediate code */
9139 gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
9141 dc->is_jmp = DISAS_NEXT;
9143 dc->singlestep_enabled = env->singlestep_enabled;
9145 dc->thumb = ARM_TBFLAG_THUMB(tb->flags);
9146 dc->condexec_mask = (ARM_TBFLAG_CONDEXEC(tb->flags) & 0xf) << 1;
9147 dc->condexec_cond = ARM_TBFLAG_CONDEXEC(tb->flags) >> 4;
9148 #if !defined(CONFIG_USER_ONLY)
9149 dc->user = (ARM_TBFLAG_PRIV(tb->flags) == 0);
9151 dc->vfp_enabled = ARM_TBFLAG_VFPEN(tb->flags);
9152 dc->vec_len = ARM_TBFLAG_VECLEN(tb->flags);
9153 dc->vec_stride = ARM_TBFLAG_VECSTRIDE(tb->flags);
9154 cpu_F0s = tcg_temp_new_i32();
9155 cpu_F1s = tcg_temp_new_i32();
9156 cpu_F0d = tcg_temp_new_i64();
9157 cpu_F1d = tcg_temp_new_i64();
9160 /* FIXME: cpu_M0 can probably be the same as cpu_V0. */
9161 cpu_M0 = tcg_temp_new_i64();
9162 next_page_start = (pc_start & TARGET_PAGE_MASK) + TARGET_PAGE_SIZE;
9165 max_insns = tb->cflags & CF_COUNT_MASK;
9167 max_insns = CF_COUNT_MASK;
9171 /* A note on handling of the condexec (IT) bits:
9173 * We want to avoid the overhead of having to write the updated condexec
9174 * bits back to the CPUState for every instruction in an IT block. So:
9175 * (1) if the condexec bits are not already zero then we write
9176 * zero back into the CPUState now. This avoids complications trying
9177 * to do it at the end of the block. (For example if we don't do this
9178 * it's hard to identify whether we can safely skip writing condexec
9179 * at the end of the TB, which we definitely want to do for the case
9180 * where a TB doesn't do anything with the IT state at all.)
9181 * (2) if we are going to leave the TB then we call gen_set_condexec()
9182 * which will write the correct value into CPUState if zero is wrong.
9183 * This is done both for leaving the TB at the end, and for leaving
9184 * it because of an exception we know will happen, which is done in
9185 * gen_exception_insn(). The latter is necessary because we need to
9186 * leave the TB with the PC/IT state just prior to execution of the
9187 * instruction which caused the exception.
9188 * (3) if we leave the TB unexpectedly (eg a data abort on a load)
9189 * then the CPUState will be wrong and we need to reset it.
9190 * This is handled in the same way as restoration of the
9191 * PC in these situations: we will be called again with search_pc=1
9192 * and generate a mapping of the condexec bits for each PC in
9193 * gen_opc_condexec_bits[]. gen_pc_load[] then uses this to restore
9194 * the condexec bits.
9196 * Note that there are no instructions which can read the condexec
9197 * bits, and none which can write non-static values to them, so
9198 * we don't need to care about whether CPUState is correct in the
9202 /* Reset the conditional execution bits immediately. This avoids
9203 complications trying to do it at the end of the block. */
9204 if (dc->condexec_mask || dc->condexec_cond)
9206 TCGv tmp = new_tmp();
9207 tcg_gen_movi_i32(tmp, 0);
9208 store_cpu_field(tmp, condexec_bits);
9211 #ifdef CONFIG_USER_ONLY
9212 /* Intercept jump to the magic kernel page. */
9213 if (dc->pc >= 0xffff0000) {
9214 /* We always get here via a jump, so know we are not in a
9215 conditional execution block. */
9216 gen_exception(EXCP_KERNEL_TRAP);
9217 dc->is_jmp = DISAS_UPDATE;
9221 if (dc->pc >= 0xfffffff0 && IS_M(env)) {
9222 /* We always get here via a jump, so know we are not in a
9223 conditional execution block. */
9224 gen_exception(EXCP_EXCEPTION_EXIT);
9225 dc->is_jmp = DISAS_UPDATE;
9230 if (unlikely(!QTAILQ_EMPTY(&env->breakpoints))) {
9231 QTAILQ_FOREACH(bp, &env->breakpoints, entry) {
9232 if (bp->pc == dc->pc) {
9233 gen_exception_insn(dc, 0, EXCP_DEBUG);
9234 /* Advance PC so that clearing the breakpoint will
9235 invalidate this TB. */
9237 goto done_generating;
9243 j = gen_opc_ptr - gen_opc_buf;
9247 gen_opc_instr_start[lj++] = 0;
9249 gen_opc_pc[lj] = dc->pc;
9250 gen_opc_condexec_bits[lj] = (dc->condexec_cond << 4) | (dc->condexec_mask >> 1);
9251 gen_opc_instr_start[lj] = 1;
9252 gen_opc_icount[lj] = num_insns;
9255 if (num_insns + 1 == max_insns && (tb->cflags & CF_LAST_IO))
9258 if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP))) {
9259 tcg_gen_debug_insn_start(dc->pc);
9263 disas_thumb_insn(env, dc);
9264 if (dc->condexec_mask) {
9265 dc->condexec_cond = (dc->condexec_cond & 0xe)
9266 | ((dc->condexec_mask >> 4) & 1);
9267 dc->condexec_mask = (dc->condexec_mask << 1) & 0x1f;
9268 if (dc->condexec_mask == 0) {
9269 dc->condexec_cond = 0;
9273 disas_arm_insn(env, dc);
9276 fprintf(stderr, "Internal resource leak before %08x\n", dc->pc);
9280 if (dc->condjmp && !dc->is_jmp) {
9281 gen_set_label(dc->condlabel);
9284 /* Translation stops when a conditional branch is encountered.
9285 * Otherwise the subsequent code could get translated several times.
9286 * Also stop translation when a page boundary is reached. This
9287 * ensures prefetch aborts occur at the right place. */
9289 } while (!dc->is_jmp && gen_opc_ptr < gen_opc_end &&
9290 !env->singlestep_enabled &&
9292 dc->pc < next_page_start &&
9293 num_insns < max_insns);
9295 if (tb->cflags & CF_LAST_IO) {
9297 /* FIXME: This can theoretically happen with self-modifying
9299 cpu_abort(env, "IO on conditional branch instruction");
9304 /* At this stage dc->condjmp will only be set when the skipped
9305 instruction was a conditional branch or trap, and the PC has
9306 already been written. */
9307 if (unlikely(env->singlestep_enabled)) {
9308 /* Make sure the pc is updated, and raise a debug exception. */
9310 gen_set_condexec(dc);
9311 if (dc->is_jmp == DISAS_SWI) {
9312 gen_exception(EXCP_SWI);
9314 gen_exception(EXCP_DEBUG);
9316 gen_set_label(dc->condlabel);
9318 if (dc->condjmp || !dc->is_jmp) {
9319 gen_set_pc_im(dc->pc);
9322 gen_set_condexec(dc);
9323 if (dc->is_jmp == DISAS_SWI && !dc->condjmp) {
9324 gen_exception(EXCP_SWI);
9326 /* FIXME: Single stepping a WFI insn will not halt
9328 gen_exception(EXCP_DEBUG);
9331 /* While branches must always occur at the end of an IT block,
9332 there are a few other things that can cause us to terminate
9333 the TB in the middel of an IT block:
9334 - Exception generating instructions (bkpt, swi, undefined).
9336 - Hardware watchpoints.
9337 Hardware breakpoints have already been handled and skip this code.
9339 gen_set_condexec(dc);
9340 switch(dc->is_jmp) {
9342 gen_goto_tb(dc, 1, dc->pc);
9347 /* indicate that the hash table must be used to find the next TB */
9351 /* nothing more to generate */
9357 gen_exception(EXCP_SWI);
9361 gen_set_label(dc->condlabel);
9362 gen_set_condexec(dc);
9363 gen_goto_tb(dc, 1, dc->pc);
9369 gen_icount_end(tb, num_insns);
9370 *gen_opc_ptr = INDEX_op_end;
9373 if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
9374 qemu_log("----------------\n");
9375 qemu_log("IN: %s\n", lookup_symbol(pc_start));
9376 log_target_disas(pc_start, dc->pc - pc_start, dc->thumb);
9381 j = gen_opc_ptr - gen_opc_buf;
9384 gen_opc_instr_start[lj++] = 0;
9386 tb->size = dc->pc - pc_start;
9387 tb->icount = num_insns;
9391 void gen_intermediate_code(CPUState *env, TranslationBlock *tb)
9393 gen_intermediate_code_internal(env, tb, 0);
9396 void gen_intermediate_code_pc(CPUState *env, TranslationBlock *tb)
9398 gen_intermediate_code_internal(env, tb, 1);
9401 static const char *cpu_mode_names[16] = {
9402 "usr", "fiq", "irq", "svc", "???", "???", "???", "abt",
9403 "???", "???", "???", "und", "???", "???", "???", "sys"
9406 void cpu_dump_state(CPUState *env, FILE *f, fprintf_function cpu_fprintf,
9416 /* ??? This assumes float64 and double have the same layout.
9417 Oh well, it's only debug dumps. */
9426 cpu_fprintf(f, "R%02d=%08x", i, env->regs[i]);
9428 cpu_fprintf(f, "\n");
9430 cpu_fprintf(f, " ");
9432 psr = cpsr_read(env);
9433 cpu_fprintf(f, "PSR=%08x %c%c%c%c %c %s%d\n",
9435 psr & (1 << 31) ? 'N' : '-',
9436 psr & (1 << 30) ? 'Z' : '-',
9437 psr & (1 << 29) ? 'C' : '-',
9438 psr & (1 << 28) ? 'V' : '-',
9439 psr & CPSR_T ? 'T' : 'A',
9440 cpu_mode_names[psr & 0xf], (psr & 0x10) ? 32 : 26);
9443 for (i = 0; i < 16; i++) {
9444 d.d = env->vfp.regs[i];
9448 cpu_fprintf(f, "s%02d=%08x(%8g) s%02d=%08x(%8g) d%02d=%08x%08x(%8g)\n",
9449 i * 2, (int)s0.i, s0.s,
9450 i * 2 + 1, (int)s1.i, s1.s,
9451 i, (int)(uint32_t)d.l.upper, (int)(uint32_t)d.l.lower,
9454 cpu_fprintf(f, "FPSCR: %08x\n", (int)env->vfp.xregs[ARM_VFP_FPSCR]);
9458 void gen_pc_load(CPUState *env, TranslationBlock *tb,
9459 unsigned long searched_pc, int pc_pos, void *puc)
9461 env->regs[15] = gen_opc_pc[pc_pos];
9462 env->condexec_bits = gen_opc_condexec_bits[pc_pos];